Spaces:
Paused
Paused
| import yt_dlp | |
| import os | |
| import gradio as gr | |
| import random | |
| import threading | |
| import requests | |
| from gradio_client import Client | |
| from huggingface_hub import InferenceClient | |
| # ===================================================== | |
| # π¨ CSS & UI CONFIGURATION (RESPONSIVE) | |
| # ===================================================== | |
| custom_css = """ | |
| /* Hide the footer for a cleaner look */ | |
| footer {visibility: hidden} | |
| /* PC Styles */ | |
| .container { max-width: 1200px; margin: auto; padding-top: 20px; } | |
| .card { border-radius: 12px; border: 1px solid #e5e7eb; padding: 20px; margin-bottom: 20px; } | |
| /* Mobile Response */ | |
| @media (max-width: 768px) { | |
| .gradio-container { padding: 5px !important; } | |
| .group-container { padding: 10px !important; } | |
| button { min-height: 50px; } | |
| } | |
| /* Error Message Styling */ | |
| .error-box { | |
| text-align: center; | |
| padding: 50px; | |
| background: #FEF2F2; | |
| border: 2px solid #F87171; | |
| border-radius: 10px; | |
| color: #991B1B; | |
| font-size: 1.2rem; | |
| font-weight: bold; | |
| } | |
| """ | |
| # ===================================================== | |
| # βοΈ CONFIG & CLIENTS | |
| # ===================================================== | |
| PROXY_SPACE_URL = "lexicalspace/Proxy-Server" | |
| OUTPUT_DIR = "downloads" | |
| os.makedirs(OUTPUT_DIR, exist_ok=True) | |
| MAX_CONCURRENCY = 6 | |
| MAX_QUEUE = 20 | |
| # SEO Config | |
| HF_TOKEN = os.getenv("HF_TOKEN") | |
| SEO_MODEL_ID = "Qwen/Qwen2.5-Coder-32B-Instruct" | |
| try: | |
| seo_client = InferenceClient(api_key=HF_TOKEN) | |
| except: | |
| seo_client = None | |
| # ===================================================== | |
| # π GLOBAL STATE | |
| # ===================================================== | |
| active_jobs = {} | |
| job_lock = threading.Lock() | |
| # ===================================================== | |
| # π₯ PART 1: DOWNLOADER LOGIC | |
| # ===================================================== | |
| def get_proxy_batch(): | |
| try: | |
| client = Client(PROXY_SPACE_URL) | |
| return [f"http://{p}" for p in client.predict(api_name="/get_proxies_api")[0][:6]] | |
| except: return [] | |
| def get_best_proxy(): | |
| try: | |
| proxies = Client(PROXY_SPACE_URL).predict(api_name="/get_proxies_api")[0] | |
| return f"http://{random.choice(proxies)}" if proxies else None | |
| except: return None | |
| def build_format_selector(quality_mode): | |
| if "Audio" in quality_mode: return {'format': 'bestaudio/best', 'postprocessors': [{'key': 'FFmpegExtractAudio','preferredcodec': 'mp3'}], 'ext': 'mp3'} | |
| if "4K" in quality_mode: return {'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', 'ext': 'mp4'} | |
| height = 1080 if "1080" in quality_mode else 720 if "720" in quality_mode else 360 | |
| return {'format': f'bestvideo[height<={height}][ext=mp4]+bestaudio[ext=m4a]/best[height<={height}][ext=mp4]', 'ext': 'mp4'} | |
| def fetch_metadata(url): | |
| if not url: return None, "β οΈ Please enter a URL.", None, None, None | |
| try: | |
| data = requests.get(f"https://noembed.com/embed?url={url}", timeout=5).json() | |
| if "error" in data: return None, f"β Error: {data['error']}", None, None, None | |
| title = data.get('title', 'Media File') | |
| desc = f"### π¬ {title}\n**π€ Author:** {data.get('author_name', 'Unknown')}" | |
| safe_title = "".join([c for c in title if c.isalnum() or c in " ._-"]) | |
| return data.get('thumbnail_url'), desc, gr.update(interactive=True), safe_title, "β Ready" | |
| except Exception as e: | |
| return None, f"β Error: {str(e)}", None, None, None | |
| def run_downloader(engine_mode, url, quality, custom_name, cookies, progress=gr.Progress()): | |
| if not url: return None, "β οΈ No URL provided", "" | |
| # Engine Selection | |
| engine_name = "V2 (Fast)" if "V2" in engine_mode or ("Auto" in engine_mode and len(url) > 60) else "V1 (Stable)" | |
| with job_lock: | |
| if active_jobs.get(url) == "running": return None, "β Already running", "" | |
| active_jobs[url] = "running" | |
| log = [f"π Engine: {engine_name} | Q: {quality}"] | |
| opts = build_format_selector(quality) | |
| fname = f"{custom_name}.%(ext)s" if custom_name else '%(title)s.%(ext)s' | |
| # Setup Proxy & Client | |
| proxies = get_proxy_batch() if "V1" in engine_name else ([get_best_proxy()] if get_best_proxy() else [None]) | |
| strategies = ["android", "web", "ios"] | |
| success, final_file = False, None | |
| cookie_path = f"cookies_{random.randint(1000,9999)}.txt" if cookies else None | |
| if cookies: | |
| with open(cookie_path, "w") as f: f.write(cookies) | |
| for proxy in proxies: | |
| if success: break | |
| for strat in strategies: | |
| if success: break | |
| ydl_opts = { | |
| 'outtmpl': os.path.join(OUTPUT_DIR, fname), | |
| 'quiet': True, 'noplaylist': True, | |
| 'extractor_args': {'youtube': {'player_client': [strat]}}, | |
| **opts | |
| } | |
| if proxy: ydl_opts['proxy'] = proxy | |
| if cookie_path: ydl_opts['cookiefile'] = cookie_path | |
| try: | |
| with yt_dlp.YoutubeDL(ydl_opts) as ydl: | |
| info = ydl.extract_info(url, download=True) | |
| fpath = ydl.prepare_filename(info) | |
| final_file = fpath.rsplit('.', 1)[0] + '.' + opts['ext'] | |
| if os.path.exists(final_file): success = True | |
| except: continue | |
| if cookie_path and os.path.exists(cookie_path): os.remove(cookie_path) | |
| with job_lock: active_jobs.pop(url, None) | |
| return (final_file, "β Download Complete", "\n".join(log)) if success else (None, "β Failed", "\n".join(log)) | |
| # ===================================================== | |
| # β‘ PART 2: SEO LOGIC | |
| # ===================================================== | |
| def generate_seo(code, ftype): | |
| if not seo_client: return "π Error: HF_TOKEN missing in Secrets." | |
| if not code: return "β οΈ Please paste code." | |
| prompt = f"Analyze this {ftype} code. Return valid JSON-LD and SEO Title/Description/Keywords." | |
| try: | |
| return seo_client.chat_completion("Qwen/Qwen2.5-Coder-32B-Instruct", messages=[{"role": "user", "content": prompt}], max_tokens=1000).choices[0].message.content | |
| except Exception as e: return f"β Error: {str(e)}" | |
| # ===================================================== | |
| # π§ PART 3: ROUTING & UI | |
| # ===================================================== | |
| def router(request: gr.Request): | |
| """ | |
| Determines which tool to show based on ?mode= URL parameter. | |
| """ | |
| params = request.query_params | |
| mode = params.get("mode") | |
| # STRICT MODE: If mode is missing or wrong, show Error Page | |
| if not mode: | |
| # Default fallback (Optional: Change to 'dl_col' if you want a default tool) | |
| return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False) | |
| if mode == "downloader": | |
| return gr.update(visible=True), gr.update(visible=False), gr.update(visible=False) | |
| elif mode == "seo": | |
| return gr.update(visible=False), gr.update(visible=True), gr.update(visible=False) | |
| else: | |
| # WRONG URL -> Error Page | |
| return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True) | |
| # ===================================================== | |
| # π₯οΈ MAIN APP | |
| # ===================================================== | |
| with gr.Blocks(css=custom_css, title="Lexical Space Tools", theme=gr.themes.Soft()) as app: | |
| # --- 1. DOWNLOADER UI --- | |
| with gr.Column(visible=False, elem_classes="container") as dl_col: | |
| gr.Markdown("# π UltraMax Downloader") | |
| with gr.Group(elem_classes="card"): | |
| with gr.Row(): | |
| url_input = gr.Textbox(label="URL", placeholder="Paste link...", scale=3, show_label=False) | |
| fetch_btn = gr.Button("π Fetch", variant="primary", scale=1) | |
| with gr.Row(): | |
| thumb = gr.Image(label="Preview", height=150, interactive=False, show_label=False) | |
| with gr.Column(): | |
| desc = gr.Markdown("### β³ Ready") | |
| status = gr.Label(value="Idle", show_label=False) | |
| with gr.Accordion("βοΈ Settings (Quality / Rename)", open=False): | |
| with gr.Row(): | |
| qual = gr.Dropdown(["Audio Only (Best)", "Video (1080p)", "Video (720p)"], value="Audio Only (Best)", label="Quality") | |
| eng = gr.Radio(["Auto", "V1 (Stable)", "V2 (Fast)"], value="Auto", label="Engine") | |
| fname = gr.Textbox(label="Filename (Optional)", placeholder="MyFile") | |
| cookies = gr.Textbox(label="Cookies", placeholder="Netscape format...", lines=1) | |
| dl_btn = gr.Button("β¬οΈ Download Now", variant="stop", interactive=False, size="lg") | |
| with gr.Group(elem_classes="card"): | |
| out_file = gr.File(label="Download") | |
| out_log = gr.Textbox(label="Logs", lines=2) | |
| # Events | |
| fetch_btn.click(fetch_metadata, [url_input], [thumb, desc, dl_btn, fname, status]) | |
| dl_btn.click(run_downloader, [eng, url_input, qual, fname, cookies], [out_file, status, out_log]) | |
| # --- 2. SEO UI --- | |
| with gr.Column(visible=False, elem_classes="container") as seo_col: | |
| gr.Markdown("# β‘ AI SEO Generator") | |
| with gr.Group(elem_classes="card"): | |
| ftype = gr.Radio(["python", "html"], label="Type", value="python") | |
| code_in = gr.Code(language="python", lines=15, label="Code") | |
| seo_btn = gr.Button("β¨ Generate", variant="primary") | |
| res = gr.Markdown(label="Result") | |
| ftype.change(lambda x: gr.Code(language=x), inputs=ftype, outputs=code_in) | |
| seo_btn.click(generate_seo, [code_in, ftype], [res]) | |
| # --- 3. ERROR / 404 UI --- | |
| with gr.Column(visible=False, elem_classes="container") as error_col: | |
| gr.HTML(""" | |
| <div class="error-box"> | |
| <h1>β οΈ Access Denied</h1> | |
| <p>No tool is available at this URL.</p> | |
| <p style="font-size: 1rem; color: #555;">Please check your link or contact the administrator.</p> | |
| </div> | |
| """) | |
| # --- ROUTING HANDLER --- | |
| # Checks URL on load and toggles visibility of columns | |
| app.load(fn=router, inputs=None, outputs=[dl_col, seo_col, error_col]) | |
| if __name__ == "__main__": | |
| app.queue(max_size=20).launch() |