import os import json import re import gradio as gr # ───────────────────── 1. 기본 설정 ───────────────────── BEST_FILE, PER_PAGE = "best_games.json", 9 # ❶ 한 페이지에 9개씩 # ───────────────────── 2. BEST 데이터 ──────────────────── def _init_best(): if not os.path.exists(BEST_FILE): json.dump([], open(BEST_FILE, "w"), ensure_ascii=False) def _load_best(): try: raw = json.load(open(BEST_FILE)) return [u if isinstance(u, str) else u.get("url") for u in raw] if isinstance(raw, list) else [] except Exception as e: print("BEST 로드 오류:", e) return [] def _save_best(lst): try: json.dump(lst, open(BEST_FILE, "w"), ensure_ascii=False, indent=2) return True except Exception as e: print("BEST 저장 오류:", e) return False # *.hf.space → Hub URL(새 탭용) 변환 def to_hub_space_url(url: str) -> str: m = re.match(r"https?://([^-]+)-([^.]+)\.hf\.space(/.*)?", url) if m: owner, space, _ = m.groups() return f"https://huggingface.co/spaces/{owner}/{space}" return url def add_url_to_best(url: str): data = _load_best() if url in data: return False data.insert(0, url) return _save_best(data) # ───────────────────── 3. 유틸 ────────────────────────── def page(lst, pg): s, e = (pg - 1) * PER_PAGE, (pg - 1) * PER_PAGE + PER_PAGE total = (len(lst) + PER_PAGE - 1) // PER_PAGE return lst[s:e], total def process_url_for_iframe(url): """iframe용 주소 변환""" if "huggingface.co/spaces" in url: owner, name = url.rstrip("/").split("/spaces/")[1].split("/")[:2] return f"https://huggingface.co/spaces/{owner}/{name}/embed", "huggingface", [] m = re.match(r"https?://([^/]+)\.hf\.space(/.*)?", url) if m: sub, rest = m.groups() static_url = f"https://{sub}.static.hf.space{rest or ''}" return static_url, "hfspace", [url] return url, "", [] # ───────────────────── 4. HTML 그리드 ─────────────────── def html(cards, pg, total): if not cards: return "