import gradio as gr
from huggingface_hub import HfApi, list_models, list_spaces
from datetime import datetime
import json
# ── fetch repos ─────────────────────────────────────────────
AUTHOR = "ScottzillaSystems"
api = HfApi()
models_raw = list(list_models(author=AUTHOR, limit=500))
spaces_raw = list(list_spaces(author=AUTHOR, limit=500))
models = []
for m in models_raw:
models.append({
"id": m.modelId,
"task": m.pipeline_tag or "—",
"library": (m.library_name or "—"),
"downloads": m.downloads or 0,
"likes": m.likes or 0,
"tags": m.tags[:6] if m.tags else [],
"private": getattr(m, "private", False),
"created": getattr(m, "created_at", "—"),
"url": f"https://huggingface.co/{m.modelId}",
"type": "model",
})
spaces = []
for s in spaces_raw:
spaces.append({
"id": s.id,
"sdk": getattr(s, "sdk", "—"),
"likes": s.likes or 0,
"tags": s.tags[:6] if getattr(s, "tags", None) else [],
"private": getattr(s, "private", False),
"created": getattr(s, "created_at", "—"),
"url": f"https://huggingface.co/spaces/{s.id}",
"type": "space",
})
all_repos = models + spaces
# ── helpers ─────────────────────────────────────────────────
def _card(repo):
priv = "🔒" if repo["private"] else ""
tags = " ".join(f"{t}" for t in repo["tags"])
extra = ""
if repo["type"] == "model":
extra = f"
⬇️ {repo['downloads']:,} | ❤️ {repo['likes']}
"
else:
extra = f"❤️ {repo['likes']} | SDK: {repo['sdk']}
"
return f"""
{priv} {repo['id'].split('/')[-1]}
{repo['type'].upper()}
{extra}
{tags}
"""
def _header():
m_pub = sum(1 for r in models if not r["private"])
m_priv = sum(1 for r in models if r["private"])
s_pub = sum(1 for r in spaces if not r["private"])
s_priv = sum(1 for r in spaces if r["private"])
return f"""
"""
CSS = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
body {font-family: 'Inter', sans-serif; background:#0f0f1a; color:#e0e0e0;}
.header {text-align:center; padding:2rem 1rem 1rem;}
.header h1 {font-size:2.2rem; margin-bottom:.5rem; color:#ffb86c;}
.stats {display:flex; flex-wrap:wrap; justify-content:center; gap:1rem; margin-top:1rem;}
.stat-box {background:#1a1a2e; border:1px solid #2a2a40; border-radius:12px; padding:1rem 1.4rem; text-align:center; min-width:110px;}
.stat-num {display:block; font-size:1.6rem; font-weight:700; color:#82aaff;}
.stat-num.green {color:#50fa7b;} .stat-num.red {color:#ff5555;}
#cards {display:grid; grid-template-columns:repeat(auto-fill, minmax(280px,1fr)); gap:1rem; padding:1rem;}
.card {background:#16162a; border:1px solid #2a2a45; border-radius:14px; padding:1.2rem; display:block; text-decoration:none; color:inherit; transition:transform .15s, box-shadow .15s;}
.card:hover {transform:translateY(-4px); box-shadow:0 8px 24px rgba(0,0,0,.45); border-color:#ffb86c;}
.card h3 {margin:0 0 .4rem; font-size:1.15rem; color:#f8f8f2;}
.card .type {font-size:.75rem; color:#ffb86c; font-weight:600; margin-bottom:.5rem; text-transform:uppercase; letter-spacing:.05em;}
.card .meta {font-size:.85rem; color:#a0a0c0; margin-bottom:.6rem;}
.tag {display:inline-block; background:#2a2a45; color:#c0c0e0; font-size:.7rem; padding:.2rem .5rem; border-radius:6px; margin:.15rem .15rem 0 0;}
.tags {margin-top:.4rem;}
"""
# ── filter logic ────────────────────────────────────────────
def update(q="", kind="All", visibility="All"):
q = q.lower().strip()
filtered = []
for r in all_repos:
if kind != "All" and r["type"] != kind.lower(): continue
if visibility != "All":
if visibility == "Public" and r["private"]: continue
if visibility == "Private" and not r["private"]: continue
if q and q not in r["id"].lower() and q not in " ".join(r["tags"]).lower(): continue
filtered.append(r)
html = _header() + "" + "".join(_card(r) for r in filtered) + "
"
return f"{html}"
def show_all(): return update()
# ── Gradio UI ───────────────────────────────────────────────
with gr.Blocks(title="ScottzillaSystems Hub Dashboard") as demo:
with gr.Row():
search = gr.Textbox(label="🔎 Search", placeholder="repo name or tag …", scale=4)
kind_dd = gr.Dropdown(["All", "Model", "Space"], value="All", label="Type", scale=1)
vis_dd = gr.Dropdown(["All", "Public", "Private"], value="All", label="Visibility", scale=1)
out = gr.HTML(label="Dashboard")
demo.load(show_all, outputs=out)
search.change(update, inputs=[search, kind_dd, vis_dd], outputs=out)
kind_dd.change(update, inputs=[search, kind_dd, vis_dd], outputs=out)
vis_dd.change(update, inputs=[search, kind_dd, vis_dd], outputs=out)
gr.Markdown("Built with ❤️ using Gradio • Data refreshes on page load")
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0")