Spaces:
Running
Running
File size: 6,731 Bytes
03dcabd 93d180e d927a6e 3140ee8 93d180e b1a8e9d 3140ee8 93d180e 3140ee8 b1a8e9d 3140ee8 cf37bae 3140ee8 93d180e 3140ee8 93d180e 3140ee8 4372751 3140ee8 fb08ce6 3140ee8 fb08ce6 3140ee8 93d180e 3140ee8 fb08ce6 93d180e 3140ee8 93d180e 3140ee8 93d180e 3140ee8 93d180e 3140ee8 93d180e 3140ee8 93d180e e2255ea |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
from flask import Flask, render_template, request, jsonify
import os, re, json
app = Flask(__name__)
# 1️⃣ curated lists ----------------------------------------------------------
CATEGORIES = {
"Productivity": [
"https://huggingface.co/spaces/ginigen/perflexity-clone",
"https://huggingface.co/spaces/ginipick/IDEA-DESIGN",
"https://huggingface.co/spaces/VIDraft/mouse-webgen",
"https://huggingface.co/spaces/openfree/Vibe-Game",
"https://huggingface.co/spaces/openfree/Game-Gallery",
"https://huggingface.co/spaces/aiqtech/Contributors-Leaderboard",
"https://huggingface.co/spaces/fantaxy/Model-Leaderboard",
"https://huggingface.co/spaces/fantaxy/Space-Leaderboard",
"https://huggingface.co/spaces/openfree/Korean-Leaderboard",
],
"Multimodal": [
"https://huggingface.co/spaces/openfree/DreamO-video",
"https://huggingface.co/spaces/Heartsync/NSFW-Uncensored-photo",
"https://huggingface.co/spaces/Heartsync/NSFW-Uncensored",
"https://huggingface.co/spaces/fantaxy/Sound-AI-SFX",
"https://huggingface.co/spaces/ginigen/SFX-Sound-magic",
"https://huggingface.co/spaces/ginigen/VoiceClone-TTS",
"https://huggingface.co/spaces/aiqcamp/MCP-kokoro",
"https://huggingface.co/spaces/aiqcamp/ENGLISH-Speaking-Scoring",
],
"Professional": [
"https://huggingface.co/spaces/ginigen/blogger",
"https://huggingface.co/spaces/VIDraft/money-radar",
"https://huggingface.co/spaces/immunobiotech/drug-discovery",
"https://huggingface.co/spaces/immunobiotech/Gemini-MICHELIN",
"https://huggingface.co/spaces/Heartsync/Papers-Leaderboard",
"https://huggingface.co/spaces/VIDraft/PapersImpact",
"https://huggingface.co/spaces/ginipick/AgentX-Papers",
"https://huggingface.co/spaces/openfree/Cycle-Navigator",
],
"Image": [
"https://huggingface.co/spaces/ginigen/interior-design",
"https://huggingface.co/spaces/ginigen/Workflow-Canvas",
"https://huggingface.co/spaces/ginigen/Multi-LoRAgen",
"https://huggingface.co/spaces/ginigen/Every-Text",
"https://huggingface.co/spaces/ginigen/text3d-r1",
"https://huggingface.co/spaces/ginipick/FLUXllama",
"https://huggingface.co/spaces/Heartsync/FLUX-Vision",
"https://huggingface.co/spaces/ginigen/VisualCloze",
"https://huggingface.co/spaces/seawolf2357/Ghibli-Multilingual-Text-rendering",
"https://huggingface.co/spaces/ginigen/Ghibli-Meme-Studio",
"https://huggingface.co/spaces/VIDraft/Open-Meme-Studio",
"https://huggingface.co/spaces/ginigen/3D-LLAMA",
],
"LLM / VLM": [
"https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-4B",
"https://huggingface.co/spaces/VIDraft/Gemma-3-R1984-12B",
"https://huggingface.co/spaces/ginigen/Mistral-Perflexity",
"https://huggingface.co/spaces/aiqcamp/gemini-2.5-flash-preview",
"https://huggingface.co/spaces/openfree/qwen3-30b-a3b-research",
"https://huggingface.co/spaces/openfree/qwen3-235b-a22b-research",
"https://huggingface.co/spaces/openfree/Llama-4-Maverick-17B-Research",
],
}
# 2️⃣ url helpers -----------------------------------------------------------
def to_direct(url: str) -> str:
m = re.match(r"https?://huggingface\.co/spaces/([^/]+)/([^/?#]+)", url)
if not m:
return url
owner, space = m.groups()
owner = owner.lower()
space = space.replace('.', '-').replace('_', '-').lower()
return f"https://{owner}-{space}.hf.space"
def to_snapshot(url: str) -> str:
return f"https://image.thum.io/get/fullpage/{to_direct(url)}"
# 3️⃣ simple API -----------------------------------------------------------
@app.route('/api/category')
def api_cat():
name = request.args.get('name', '')
urls = CATEGORIES.get(name, [])
return jsonify([{
"title": url.split('/')[-1],
"img": to_snapshot(url),
"link": to_direct(url)
} for url in urls])
# 4️⃣ web front ------------------------------------------------------------
@app.route('/')
def home():
return render_template('index.html', cats=list(CATEGORIES.keys()))
# 5️⃣ generate template once ----------------------------------------------
os.makedirs('templates', exist_ok=True)
with open('templates/index.html', 'w', encoding='utf-8') as fp:
fp.write(r'''<!DOCTYPE html>
<html><head><meta charset="utf-8"><meta name="viewport"content="width=device-width,initial-scale=1">
<title>Curated HuggingFace Spaces</title>
<style>
body{margin:0;font-family:Nunito,sans-serif;background:#f6f8fb}
.tabs{display:flex;flex-wrap:wrap;gap:8px;padding:16px}
.tab{padding:6px 14px;border:none;border-radius:18px;background:#e2e8f0;font-weight:600;cursor:pointer}
.tab.active{background:#a78bfa;color:#1a202c}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px;padding:0 16px 40px}
.card{background:#fff;border-radius:12px;box-shadow:0 2px 8px rgba(0,0,0,.08);overflow:hidden;height:420px;display:flex;flex-direction:column}
.frame{flex:1;position:relative;overflow:hidden}
.frame img{width:166.667%;height:166.667%;transform:scale(.6);transform-origin:top left}
.foot{height:44px;background:#fafafa;display:flex;align-items:center;justify-content:center;border-top:1px solid #eee}
.foot a{font-size:.85rem;font-weight:700;color:#4a6dd8;text-decoration:none}
</style></head>
<body>
<div class="tabs" id="tabs"></div>
<div class="grid" id="grid"></div>
<script>
const cats={{cats|tojson}};
const tabs=document.getElementById('tabs');
const grid=document.getElementById('grid');
let active="";
function load(cat){
if(cat===active) return; active=cat;
[...tabs.children].forEach(b=>b.classList.toggle('active',b.dataset.c===cat));
grid.innerHTML='<p style="grid-column:1/-1;text-align:center;padding:40px">Loading…</p>';
fetch('/api/category?name='+encodeURIComponent(cat))
.then(r=>r.json()).then(arr=>{
grid.innerHTML="";
arr.forEach(sp=>{
const c=document.createElement('div');c.className='card';
c.innerHTML=`<div class="frame"><img src="${sp.img}" loading="lazy"></div>
<div class="foot"><a href="${sp.link}" target="_blank">${sp.title}</a></div>`;
grid.appendChild(c);
});
});
}
cats.forEach((c,i)=>{
const b=document.createElement('button');b.textContent=c;b.className='tab';b.dataset.c=c;
b.onclick=()=>load(c);tabs.appendChild(b);if(i==0)load(c);
});
</script>
</body></html>''')
# 6️⃣ run ------------------------------------------------------------------
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860)
|