"""Cookie parsing and formatting utilities.""" from typing import Optional from pathlib import Path def parse_netscape_cookies(cookie_text: str) -> list[dict]: """Parse Netscape cookie format into a list of cookie dicts. Netscape format: domainflagpathsecureexpirationnamevalue Args: cookie_text: Cookie file content in Netscape format Returns: List of cookie dictionaries """ cookies = [] for line in cookie_text.strip().split("\n"): line = line.strip() # Skip comments and empty lines if not line or line.startswith("#"): continue parts = line.split("\t") if len(parts) < 7: continue cookies.append({ "domain": parts[0], "flag": parts[1] == "TRUE", "path": parts[2], "secure": parts[3] == "TRUE", "expiration": int(parts[4]) if parts[4] != "0" else None, "name": parts[5], "value": parts[6], }) return cookies def to_netscape_format(cookies: list[dict]) -> str: """Convert cookie list to Netscape format. Args: cookies: List of cookie dictionaries Returns: Cookie file content in Netscape format """ lines = ["# Netscape HTTP Cookie File"] for c in cookies: line = "\t".join([ c["domain"], "TRUE" if c.get("flag", True) else "FALSE", c.get("path", "/"), "TRUE" if c.get("secure", False) else "FALSE", str(c.get("expiration", 0) or 0), c["name"], c["value"], ]) lines.append(line) return "\n".join(lines) def write_cookie_file(cookies: list[dict], path: Path) -> None: """Write cookies to a file in Netscape format. Args: cookies: List of cookie dictionaries path: Path to write the cookie file """ content = to_netscape_format(cookies) path.parent.mkdir(parents=True, exist_ok=True) path.write_text(content) def get_platform_from_domain(domain: str) -> Optional[str]: """Detect platform from cookie domain. Args: domain: Cookie domain (e.g., '.patreon.com') Returns: Platform name or None """ domain_lower = domain.lower() if "patreon.com" in domain_lower: return "patreon" elif "subscribestar" in domain_lower: return "subscribestar" elif "hentai-foundry.com" in domain_lower: return "hentaifoundry" elif "discord.com" in domain_lower: return "discord" return None