goon/app/api
goon-foss d716b0c75d feat(pornbusy): browse scraper + loadvid POST-manifest producer
pornbusy.com exposes every field as a discrete itemprop node (title,
duration, uploadDate, thumbnail, description) plus a dedicated
<div id="video-actors"> cast block with no sidebar pollution. Measured
orphan risk is low: 80% of a 100-scene sample have a performer that
already carries a tpdb/stashdb ref, and 21% of titles strongly match
scenes we already hold. No studio field exists on the site.

Homepage pagination is broken (pages 1/2/3 return an identical set), so
the listing is driven off sitemap_index.xml -> 10 post-sitemaps sorted by
lastmod, chunked in crawl_page the same way the PlayTube base does it.

Playback dispatches on embedURL and covers ~69% of the catalog: the
seekplayer family (already handled by the engine after the earlier host
regex widening) and zpi.cx (the embedURL is the file itself), plus loadvid
at ~41%, which needed new plumbing.

loadvid hands back the CONTENT of an m3u8 over POST /videos/resolve-token
(CSRF + videoToken from the embed page) and has no manifest URL at all:
GET on that endpoint is 405 and the guessable .m3u8 paths are 404. So
make_token grew an optional `producer` marker and /proxy/hls calls the
producer instead of GETting a URL. Segments in the returned manifest are
absolute and fully portable (verified: 206 on a Range request with no
headers, no referer, no token), so the phone still pulls them straight
from the CDN and only the manifest travels through the VPS.

upload18 (~12%) and the tail are deliberately left unresolved: their token
embeds the fetcher's /24, so resolving server-side would force the whole
video through the VPS.

Verified: 19 scenes/page, 19/19 with duration, 17/19 with cast, 19/19 with
tags (names read from the title attribute since an icon element precedes
the anchor text), playback 8/8 via loadvid, and /proxy/hls returning a
116KB manifest with 869 absolute segments. Pilot ingest of 3 pages: 59
seen, 35 merged into existing scenes, 24 new, 0 errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-07-27 08:45:00 +02:00
..
__init__.py Initial commit 2026-05-20 10:10:22 +02:00
admin.py Initial commit 2026-05-20 10:10:22 +02:00
admin_html.py Initial commit 2026-05-20 10:10:22 +02:00
blacklist.py feat(api): device-scope user state (favorites/progress/blacklists) 2026-06-10 08:58:01 +02:00
bug_reports.py feat(bug-reports): two-way replies (device-scoped) + admin reply endpoint 2026-06-12 11:35:44 +02:00
device.py feat(api): device-scope user state (favorites/progress/blacklists) 2026-06-10 08:58:01 +02:00
expo_updates.py session work: bug-report fixes + WIP cleanup 2026-05-25 22:02:52 +02:00
favorites.py refactor(review): dedup favorites/list visibility + SQL-aggregate count, share mobile isNew 2026-07-02 09:41:37 +02:00
me.py feat(sync): device-to-device backup of favorites & state 2026-07-14 22:41:35 +03:00
movies.py fix(movies): dedup playback sources by target (cross-mirror dupes) 2026-06-21 22:26:50 +02:00
playback.py feat(pornbusy): browse scraper + loadvid POST-manifest producer 2026-07-27 08:45:00 +02:00
playback_events.py fix(watchporn): re-resolve stale CDN URL in-player, drop WebView page fallback 2026-07-05 01:18:08 +02:00
saved_searches.py feat(api): per-device saved searches (keyword favorites) 2026-06-16 13:52:18 +02:00
scene_favorites.py feat(api): device-scope user state (favorites/progress/blacklists) 2026-06-10 08:58:01 +02:00
scenes.py fix: keep-screen-on podczas odtwarzania + on-demand miniaturki youporn 2026-07-26 17:00:31 +02:00
schemas.py fix(review): player recovery deadlocks, quick-play re-fire, backfill gaps, em-dashes 2026-07-02 09:20:40 +02:00
seo.py feat(seo): public HTML SEO router + templates; add CLAUDE.md; ignore .nimbalyst 2026-05-31 16:29:59 +02:00
sources.py feat(sources): remove 0dayxx + pornditt + pornhat entirely 2026-06-22 12:23:29 +02:00
stream_proxy.py feat(pornbusy): browse scraper + loadvid POST-manifest producer 2026-07-27 08:45:00 +02:00
taxonomies.py feat(sources): remove 0dayxx + pornditt + pornhat entirely 2026-06-22 12:23:29 +02:00
watch.py feat(api): device-scope user state (favorites/progress/blacklists) 2026-06-10 08:58:01 +02:00