- shooshtime: update parse_list_videos selectors for the site's redesigned
markup (div.card / a.title / a.image img / div.duration / div.list div.box
/ div.name a.text)
- hdporn92: mirror the site's own links.hls4||hls3||hls2 fallback and scan
every P.A.C.K.E.R. block instead of assuming the first one is the player
block; prefer a genuine .m3u8 candidate over a decoy .txt one
- camsoda: replace naive first-`{`/last-`}` JSON extraction with a proper
balanced-brace scan so trailing wrapper markup can't corrupt the parse
("key must be a string")
- sextb: fix mirror_url() double-prefixing the scheme when building Jina
mirror URLs (produced a malformed https://r.jina.ai/http://https://... URL)
- supjav: switch curl_cffi impersonation from chrome to safari18_0 - Cloudflare
blocks the chrome/firefox profiles outright but passes Safari
- hentaimama: resolve every card on a listing page (not just the first
perPage) and truncate after filtering, so a bulk "Coming soon" placeholder
batch at the front of the feed no longer empties the whole page; report a
provider error if literally every candidate fails
Refreshes graphify's graph and docs/provider-catalog.md with the new
technical details for all six providers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTqf6orbHZ9rFFpVpcgzcR
melonstube is a meta-search aggregator that redirects out to ~120
third-party hosts. A live crawl of /new, /popular, and /rating
(~3,350 out-links) found the previous "assume yt-dlp can resolve it"
fallback was hiding real failures on the highest-traffic hosts:
- eporner.com is ~34% of all melonstube traffic by itself, and like
the eporner channel (fixed earlier), serves a restricted preview
clip without its hash/xhr dance.
- fapcat.com/momvids.com 403 a plain fetch (Cloudflare).
- Several others just needed real extraction instead of a guess.
Per-card enrichment now dispatches by destination host to:
- Eporner: reuses eporner's own hash/xhr + Referer resolution, moved
to src/util/eporner_resolve.rs so both providers' single-provider
builds still compile (HOT_TUB_PROVIDER=<id> only compiles the one
selected provider module; src/util/* always compiles).
- Kvs (pornfreenow, analdin, babepump, w1mp, fetishshrine, pervclips,
xozilla, ok.xxx, ebonypeek, xgroovy): a shared get_file extractor,
the same KVS backend several other Hot Tub providers already scrape.
- KvsCfGated (fapcat, momvids): same extractor via the Safari18
bypass client melonstube.com itself already needs.
- XhamsterMirror (xh.partners): a genuine xHamster mirror instance,
Referer built from the actual resolved host.
- SomePorn: HLS playlist URL built from the page's video id directly.
- Pornone: direct <source> tag extraction.
flirt4free.com (a live-cam page, not a VOD) moved into the dropped-
host bucket alongside the existing junk/join.* hosts.
Enrichment is bounded (concurrency, a 10s per-card timeout, and
capped to the requested perPage rather than the full ~240-card page)
so a slow or rate-limited destination can't stall the response.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Root cause found live: eporner's CDN mp4 URLs enforce a Referer check
independent of the hash/xhr resolution — a request with no Referer or
one pointing at eporner.com gets the real file, but any other Referer
gets a 302 to a static .../na.mp4 ("not available") decoy. Since our
VideoFormat entries declared no http_headers at all, playback fell
through to whatever default Referer the client happened to send,
occasionally tripping this check and showing the short "this video is
only available at eporner.com" clip.
Verified against a live video: fetching a resolved format URL with an
unrelated Referer reproduces the exact na.mp4 redirect; with the
correct Referer it serves the full file. Each format now explicitly
declares Referer: https://www.eporner.com/ so client-side defaults
can't trip the check.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTqf6orbHZ9rFFpVpcgzcR
melonstube.com started fronting itself with Cloudflare bot management
(a real Turnstile challenge) since this provider was written, so the
shared Requester's Firefox151 emulation got blocked on every path and
the provider returned 0 items.
A/B-probed several browser TLS fingerprints live: Chrome120/124 pass
the plain listing pages but still 403 on /category/* and the
/searching/by-form search POST, while Safari18 passes everywhere.
Listing/search fetches now try a dedicated Safari18-emulated client
first and fall back to the shared Requester if Cloudflare's rules
change again (same pattern as lulustream.rs/doodstream.rs).
Also fixes get_videos ignoring perPage entirely (always returned the
full ~120-card page); it now truncates to the requested size.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTqf6orbHZ9rFFpVpcgzcR
ripnsfw.com serves its entire catalogue as a published-Google-Sheet CSV
with no native pagination/search API, so the provider fetches and
parses that CSV once (cached 180s) and does feed/search/pagination/sort
in memory. Each row's Doodstream/Lulustream embed links resolve to
formats[] via the existing (previously unused) doodstream/lulustream
redirect proxies.
Also fixes check.py's follow_proxy_redirect, which used HEAD even
though these redirect-proxy routes only accept GET/POST, so it never
actually resolved the redirect; extends the CF-protected host list
(suffix matching + ripnsfw.com's client-only-SPA 404 page, dood.video,
tnmr.org) so known sandbox/CDN-IP-reputation failures are reported as
warnings instead of errors.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QTqf6orbHZ9rFFpVpcgzcR
New channel: hotbunny (AI-generated hentai, hotbunny.ai JSON API).
Includes thumbnail proxy (/proxy/hotbunny-thumb/) since assets.hotbunny.ai
is CF bot-managed. check.py updated to treat CF-protected format URLs as
warnings rather than errors.
requester.rs: store_response_cookies now honours the Domain attribute in
Set-Cookie headers — cookies scoped to .domain.com are registered against
the parent domain so the wreq Jar returns them for sub.domain.com requests
automatically, without per-provider workarounds.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
kwiky.com (ICF/StreamMate platform) short-form cam clips. Two-step API
(ID list → metadata batch), XSRF token auth cached with double-checked
RwLock, direct MP4 formats from media.icfcdn.com, 48 curated tags via
keywordSearch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bare keyword queries no longer hijack to a category archive when the
query matches a category name (sexy/ass/tiktok/...); only an explicit
cat:/category: prefix or the categories filter routes to an archive.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>