from flask import Flask, render_template, request, redirect, url_for, jsonify, session, Response import requests import os from datetime import timedelta from urllib.parse import urlparse, urljoin app = Flask(__name__) app.secret_key = os.urandom(24) # Session encryption key app.permanent_session_lifetime = timedelta(days=7) # Session duration # Huggingface URL list HUGGINGFACE_URLS = [ "https://huggingface.co/spaces/ginipick/Tech_Hangman_Game", "https://huggingface.co/spaces/openfree/deepseek_r1_API", "https://huggingface.co/spaces/ginipick/open_Deep-Research", "https://huggingface.co/spaces/aiqmaster/open-deep-research", "https://huggingface.co/spaces/seawolf2357/DeepSeek-R1-32b-search", "https://huggingface.co/spaces/ginigen/LLaDA", "https://huggingface.co/spaces/VIDraft/PHI4-Multimodal", "https://huggingface.co/spaces/ginigen/Ovis2-8B", "https://huggingface.co/spaces/ginigen/Graph-Mind", "https://huggingface.co/spaces/ginigen/Workflow-Canvas", "https://huggingface.co/spaces/ginigen/Design", "https://huggingface.co/spaces/ginigen/Diagram", "https://huggingface.co/spaces/ginigen/Mockup", "https://huggingface.co/spaces/ginigen/Infographic", "https://huggingface.co/spaces/ginigen/Flowchart", "https://huggingface.co/spaces/aiqcamp/FLUX-Vision", "https://huggingface.co/spaces/ginigen/VoiceClone-TTS", "https://huggingface.co/spaces/openfree/Perceptron-Network", "https://huggingface.co/spaces/openfree/Article-Generator", ] # Extract model/space info from URL def extract_model_info(url): parts = url.split('/') if len(parts) < 6: return None if parts[3] == 'spaces' or parts[3] == 'models': return { 'type': parts[3], 'owner': parts[4], 'repo': parts[5], 'full_id': f"{parts[4]}/{parts[5]}" } elif len(parts) >= 5: # Other URL format return { 'type': 'models', # Default 'owner': parts[3], 'repo': parts[4], 'full_id': f"{parts[3]}/{parts[4]}" } return None # Extract direct embed URL def get_embed_url(url): model_info = extract_model_info(url) if not model_info or model_info['type'] != 'spaces': return url # For spaces, use the embedded version return f"https://huggingface.co/spaces/{model_info['owner']}/{model_info['repo']}/embed" # Extract title from the last part of URL def extract_title(url): parts = url.split("/") title = parts[-1] if parts else "" return title.replace("_", " ").replace("-", " ") # Huggingface token validation def validate_token(token): headers = {"Authorization": f"Bearer {token}"} # Try whoami-v2 endpoint first try: response = requests.get("https://huggingface.co/api/whoami-v2", headers=headers) if response.ok: return True, response.json() except Exception as e: print(f"whoami-v2 token validation error: {e}") # Try the original whoami endpoint try: response = requests.get("https://huggingface.co/api/whoami", headers=headers) if response.ok: return True, response.json() except Exception as e: print(f"whoami token validation error: {e}") return False, None # Homepage route @app.route('/') def home(): return render_template('index.html') # Login API @app.route('/api/login', methods=['POST']) def login(): token = request.form.get('token', '') if not token: return jsonify({'success': False, 'message': '토큰을 입력해주세요.'}) is_valid, user_info = validate_token(token) if not is_valid or not user_info: return jsonify({'success': False, 'message': '유효하지 않은 토큰입니다.'}) # Find username username = None if 'name' in user_info: username = user_info['name'] elif 'user' in user_info and 'username' in user_info['user']: username = user_info['user']['username'] elif 'username' in user_info: username = user_info['username'] else: username = '인증된 사용자' # Save to session session['token'] = token session['username'] = username return jsonify({ 'success': True, 'username': username }) # Logout API @app.route('/api/logout', methods=['POST']) def logout(): session.pop('token', None) session.pop('username', None) return jsonify({'success': True}) # URL list API @app.route('/api/urls', methods=['GET']) def get_urls(): search_query = request.args.get('search', '').lower() results = [] for url in HUGGINGFACE_URLS: title = extract_title(url) model_info = extract_model_info(url) if not model_info: continue if search_query and search_query not in url.lower() and search_query not in title.lower(): continue results.append({ 'url': url, 'embedUrl': get_embed_url(url), 'title': title, 'model_info': model_info }) return jsonify(results) # Session status API @app.route('/api/session-status', methods=['GET']) def session_status(): return jsonify({ 'logged_in': 'token' in session, 'username': session.get('username') }) if __name__ == '__main__': # Create templates folder os.makedirs('templates', exist_ok=True) # Create index.html file with open('templates/index.html', 'w', encoding='utf-8') as f: f.write('''