#!/usr/bin/env -S uv run --script # /// script # dependencies = [] # /// """ shot-scraper wrapper that uses Firefox cookies via cookiefire. Usage: shotscraper https://example.com -o out.png shotscraper -P jtm https://private.com -o private.png """ import json import os import subprocess import sys import tempfile def parse_netscape_cookies(cookie_text): """Convert Netscape cookie format to Playwright storage_state format.""" cookies = [] for line in cookie_text.strip().split('\n'): if line.startswith('#') or not line.strip(): continue parts = line.split('\t') if len(parts) >= 7: domain, _, path, secure, expires, name, value = parts[:7] # playwright requires -1 (session) or positive unix timestamp in seconds # firefox stores milliseconds, so divide by 1000 exp = float(expires) if exp <= 0: exp = -1 elif exp > 9999999999: # looks like milliseconds exp = exp / 1000 cookies.append({ "name": name, "value": value, "domain": domain, "path": path, "expires": exp, "httpOnly": False, "secure": secure.upper() == "TRUE", "sameSite": "Lax", }) return {"cookies": cookies, "origins": []} def main(): args = sys.argv[1:] profile = "jtm" passthrough = [] # extract -P profile from args i = 0 while i < len(args): if args[i] == "-P" and i + 1 < len(args): next_arg = args[i + 1] # don't treat URLs as profile names if next_arg.startswith("http://") or next_arg.startswith("https://"): passthrough.append(next_arg) i += 2 else: profile = next_arg i += 2 else: passthrough.append(args[i]) i += 1 # get cookies from firefox try: cookie_text = subprocess.check_output( ["cookiefire", profile], text=True ) except subprocess.CalledProcessError as e: print(f"cookiefire failed: {e}", file=sys.stderr) sys.exit(1) storage_state = parse_netscape_cookies(cookie_text) # write to temp file with tempfile.NamedTemporaryFile( mode='w', suffix='.json', delete=False ) as f: json.dump(storage_state, f) auth_file = f.name try: cmd = ["shot-scraper", "--auth", auth_file] + passthrough result = subprocess.run(cmd) sys.exit(result.returncode) finally: os.unlink(auth_file) if __name__ == "__main__": main()