"""HentaiFoundry — two quirks colocated. 1. post_url: HF sidecars omit `url` entirely; `src` is the image URL. Synthesize the permalink from `user` + `index` (/pictures/user//). 2. augment_cookies: gallery-dl's HF extractor checks `self.cookies.get("PHPSESSID", domain="www.hentai-foundry.com")` with `requests`' EXACT domain matching. The extension's pre-v1.0.5 `cookies.js` aggressively rewrote every captured cookie to the leading-dot subdomain-wide form (`.hentai-foundry.com`), which fails the exact lookup even though the cookie IS sent on actual HTTP requests (RFC 6265 subdomain matching). The extractor falls into an unauthenticated `?enterAgree=1` HEAD that 401s. Inject host-only duplicates of PHPSESSID + YII_CSRF_TOKEN so the lookup succeeds. """ from .base import GD_DEFAULTS, PlatformInfo, str_field, str_id_value _HOST_ONLY_NAMES = ("PHPSESSID", "YII_CSRF_TOKEN") def derive_post_url(data: dict) -> str | None: user = str_field(data.get("user")) or str_field(data.get("artist")) idx = str_id_value(data.get("index")) if user and idx: return f"https://www.hentai-foundry.com/pictures/user/{user}/{idx}" return None def augment_cookies(netscape: str) -> str: body = netscape.rstrip("\n") if not body: return netscape lines = body.split("\n") existing_host_only: set[str] = set() by_name: dict[str, list[str]] = {} for raw in lines: if not raw or raw.startswith("#"): continue parts = raw.split("\t") if len(parts) < 7: continue domain, _flag, _path, _secure, _exp, name, _value = parts[:7] if name not in _HOST_ONLY_NAMES: continue if domain == "www.hentai-foundry.com": existing_host_only.add(name) elif domain in (".hentai-foundry.com", "hentai-foundry.com"): by_name.setdefault(name, []).append(raw) appended: list[str] = [] for name in _HOST_ONLY_NAMES: if name in existing_host_only or name not in by_name: continue # Duplicate the first subdomain-wide line as host-only on # www.hentai-foundry.com. Same value + expiry; flag=FALSE marks # the entry host-only in netscape format. parts = by_name[name][0].split("\t") parts[0] = "www.hentai-foundry.com" parts[1] = "FALSE" appended.append("\t".join(parts[:7])) if not appended: return netscape return body + "\n" + "\n".join(appended) + "\n" INFO = PlatformInfo( key="hentaifoundry", name="Hentai Foundry", description="Download artwork from Hentai Foundry artists", auth_type="cookies", requires_auth=False, url_pattern=r"^https?://(www\.)?hentai-foundry\.com/", url_examples=[ "https://www.hentai-foundry.com/user/example_artist", "https://www.hentai-foundry.com/pictures/user/example_artist", ], default_config={**GD_DEFAULTS, "content_types": ["pictures"]}, derive_post_url=derive_post_url, augment_cookies=augment_cookies, )