import os, re, time, json, datetime, requests, gradio as gr # ───────────────────── 1. 기본 설정 ───────────────────── BEST_FILE, PER_PAGE = "best_games.json", 9 # ───────────────────── 2. BEST 데이터 ──────────────────── def _init_best(): if not os.path.exists(BEST_FILE): json.dump([], open(BEST_FILE, "w")) def _load_best(): try: data = json.load(open(BEST_FILE)) for it in data: if "ts" not in it: it["ts"] = int(it.get("timestamp", time.time())) return data except Exception as e: print(f"BEST 데이터 로드 오류: {e}") return [] def _save_best(data): try: json.dump(data, open(BEST_FILE, "w")) return True except Exception as e: print(f"BEST 데이터 저장 오류: {e}") return False # ───────────────────── 3. URL 추가 기능 ───────────────────── def add_url_to_best(title, url): """사용자가 제공한 URL을 BEST 목록에 추가합니다.""" try: # 현재 BEST 데이터 로드 data = _load_best() # URL이 이미 존재하는지 확인 for item in data: if item.get("url") == url: print(f"URL이 이미 존재합니다: {url}") return False # 새 항목 추가 new_item = { "title": title, "url": url, "ts": int(time.time()), "projectId": "", # 사용자가 직접 추가하므로 projectId 없음 "deploymentId": "" # 사용자가 직접 추가하므로 deploymentId 없음 } data.append(new_item) # 시간순으로 정렬 data = sorted(data, key=lambda x: x["ts"], reverse=True) # 저장 if _save_best(data): print(f"URL이 성공적으로 추가되었습니다: {url}") return True return False except Exception as e: print(f"URL 추가 오류: {str(e)}") return False # ───────────────────── 4. 페이지네이션 ─────────────────── def page(lst, pg): s = (pg-1) * PER_PAGE e = s + PER_PAGE total = (len(lst) + PER_PAGE - 1) // PER_PAGE return lst[s:e], total # ───────────────────── 5. URL 처리 함수 ───────────────────── def process_url_for_iframe(url): """URL을 iframe에 표시하기 적합한 형태로 변환합니다.""" # 허깅페이스 URL 패턴 감지 is_huggingface = False embed_urls = [] # 1. huggingface.co/spaces 패턴 처리 if "huggingface.co/spaces" in url: is_huggingface = True # 기본 URL 정규화 base_url = url.rstrip("/") try: # /spaces/ 이후의 경로 추출 if "/spaces/" in base_url: path = base_url.split("/spaces/")[1] parts = path.split("/") owner = parts[0] # name 부분 추출 if len(parts) > 1: name = parts[1] # 특수 문자 변환 clean_name = name.replace('.', '-').replace('_', '-').lower() clean_owner = owner.lower() # 여러 포맷의 URL을 시도하기 위해 목록에 추가 embed_urls.append(f"https://huggingface.co/spaces/{owner}/{name}/embed") # 공식 embed URL embed_urls.append(f"https://{clean_owner}-{clean_name}.hf.space") # 직접 도메인 접근 else: # owner만 있는 경우 공식 URL 사용 embed_urls.append(f"https://huggingface.co/spaces/{owner}/embed") except Exception as e: print(f"허깅페이스 URL 처리 중 오류: {e}") # 기본 embed URL 시도 if not base_url.endswith("/embed"): embed_urls.append(f"{base_url}/embed") else: embed_urls.append(base_url) # 2. .hf.space 도메인 처리 elif ".hf.space" in url: is_huggingface = True embed_urls.append(url) # 현재 URL 그대로 시도 # 3. 일반 URL은 그대로 반환 else: return url, is_huggingface, [] # 최종 URL과 함께 시도할 대체 URL 목록 반환 primary_url = embed_urls[0] if embed_urls else url return primary_url, is_huggingface, embed_urls[1:] if len(embed_urls) > 1 else [] # ───────────────────── 6. HTML 그리드 ─────────────────── def html(cards, pg, total): if not cards: return "