Fix six dead providers (shooshtime, hdporn92, camsoda, sextb, supjav, hentaimama)

- 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
This commit is contained in:
Simon
2026-09-22 13:56:36 +00:00
parent c244461d0b
commit c40b48b0db
8 changed files with 356 additions and 78 deletions

View File

@@ -811,13 +811,13 @@ impl ShooshtimeProvider {
fn parse_list_videos(&self, html: &str) -> Result<Vec<VideoItem>> {
let document = Html::parse_document(html);
let card_selector = Self::selector("div.item.thumb")?;
let video_link_selector = Self::selector("a[href*=\"/videos/\"]")?;
let image_selector = Self::selector("img")?;
let duration_selector = Self::selector("span.duration")?;
let title_selector = Self::selector("span.description, span.description.secondary")?;
let info_selector = Self::selector("ul.info li.val")?;
let uploader_selector = Self::selector("ul.info a[href*=\"/members/\"]")?;
let card_selector = Self::selector("div.card")?;
let video_link_selector = Self::selector("a.title")?;
let image_selector = Self::selector("a.image img")?;
let duration_selector = Self::selector("div.duration")?;
let title_selector = Self::selector("a.title")?;
let info_selector = Self::selector("div.list div.box")?;
let uploader_selector = Self::selector("div.name a.text")?;
let mut items = Vec::new();