Spaces:
Build error
Build error
| #!/usr/bin/env python3 | |
| """Mint a cf_clearance cookie for miruro.tv and write it into backend/.env. | |
| Usage: | |
| pip install nodriver | |
| python scripts/mint_cf_clearance.py [--domain www.miruro.tv] [--timeout 60] | |
| The script opens a real (undetected) Chrome window, lets Cloudflare's JS | |
| challenge complete, extracts the `cf_clearance` cookie, and writes/updates | |
| `CF_CLEARANCE=` in backend/.env. | |
| Notes: | |
| * Mint on the SAME machine/network that runs the backend (the cookie is | |
| bound to your IP + User-Agent). | |
| * If Cloudflare shows an interactive CAPTCHA (Turnstile), solve it in the | |
| opened window — the script waits for you. | |
| * The cookie expires — re-run periodically. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import re | |
| import sys | |
| import time | |
| from pathlib import Path | |
| BACKEND_ENV = Path(__file__).resolve().parent.parent / "backend" / ".env" | |
| COOKIE_NAME = "cf_clearance" | |
| def find_cookie(cookies: list[dict]) -> str | None: | |
| for c in cookies: | |
| if c.get("name") == COOKIE_NAME: | |
| return c.get("value") | |
| return None | |
| def write_env(domain: str, value: str) -> None: | |
| BACKEND_ENV.parent.mkdir(parents=True, exist_ok=True) | |
| text = BACKEND_ENV.read_text(encoding="utf-8") if BACKEND_ENV.exists() else "" | |
| if not re.search(r"^\s*CF_CLEARANCE\s*=", text, flags=re.MULTILINE): | |
| text = text.rstrip() + f"\nCF_CLEARANCE={value}\n" | |
| else: | |
| text = re.sub( | |
| r"^\s*CF_CLEARANCE\s*=.*$", | |
| f"CF_CLEARANCE={value}", | |
| text, | |
| flags=re.MULTILINE, | |
| ) | |
| BACKEND_ENV.write_text(text, encoding="utf-8") | |
| print(f"✔ Wrote CF_CLEARANCE to {BACKEND_ENV} ({len(value)} chars)") | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description="Mint a cf_clearance cookie for Miruro") | |
| parser.add_argument("--domain", default="www.miruro.tv") | |
| parser.add_argument("--timeout", type=int, default=60, help="max seconds to wait") | |
| args = parser.parse_args() | |
| try: | |
| import nodriver as uc | |
| except ImportError: | |
| print("nodriver is required. Install it with: pip install nodriver") | |
| return 1 | |
| print(f"Opening {args.domain} in an undetected Chrome window…") | |
| print("If a CAPTCHA appears, solve it manually in the window.") | |
| async def run(): | |
| browser = await uc.start() | |
| try: | |
| tab = await browser.get(f"https://{args.domain}/") | |
| deadline = time.monotonic() + args.timeout | |
| while time.monotonic() < deadline: | |
| cookies = await tab.cookies.all() | |
| value = find_cookie(cookies) | |
| if value: | |
| write_env(args.domain, value) | |
| return 0 | |
| time.sleep(2) | |
| print(f"✖ No {COOKIE_NAME} cookie within {args.timeout}s. " | |
| "Try increasing --timeout or solving an interactive CAPTCHA.") | |
| return 1 | |
| finally: | |
| await browser.stop() | |
| try: | |
| import asyncio | |
| return asyncio.run(run()) | |
| except KeyboardInterrupt: | |
| print("\nAborted.") | |
| return 1 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |