From 131f7447450c3cf2c80fb184a52d5aabea43730a Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Wed, 21 Oct 2026 02:30:33 +0200 Subject: [PATCH] Fixed Team Skeet deep scrape and URL format, added duration. --- seeds/02_sites.js | 93 ++++++++++++++++++++++++++++++++++++--- src/scrapers/teamskeet.js | 35 +++++++-------- 2 files changed, 102 insertions(+), 26 deletions(-) diff --git a/seeds/02_sites.js b/seeds/02_sites.js index fd17bb8c..0153259d 100755 --- a/seeds/02_sites.js +++ b/seeds/02_sites.js @@ -8517,6 +8517,33 @@ const sites = [ id: 'hookup-pad', }, }, + { + slug: 'thepickupvan', + name: 'The Pickup Van', + url: 'https://www.mylf.com/series/the-pickup-van', + parent: 'mylf', + parameters: { + id: 'the-pickup-van', + }, + }, + { + slug: 'motherfucker', + name: 'Motherfucker', + url: 'https://www.mylf.com/series/motherfucker', + parent: 'mylf', + parameters: { + id: 'motherfucker', + }, + }, + { + slug: 'bluecollarbabes', + name: 'Blue Collar Babes', + url: 'https://www.mylf.com/series/blue-collar-babes', + parent: 'mylf', + parameters: { + id: 'blue-collar-babes', + }, + }, /* premium */ { slug: 'analmom', @@ -12397,13 +12424,6 @@ const sites = [ url: 'https://www.teamskeet.com/series/bad-milfs', parent: 'teamskeet', }, - { - slug: 'blackstepdad', - name: 'Black StepDad', - url: 'https://www.teamskeet.com/series/black-stepdad', - alias: ['bsd'], - parent: 'teamskeet', - }, { slug: 'exxxtrasmall', name: 'Exxxtra Small', @@ -12783,6 +12803,44 @@ const sites = [ url: 'https://www.teamskeet.com/series/passport-bros', parent: 'teamskeet', }, + { + slug: 'underthetable', + name: 'Under the Table', + url: 'https://www.teamskeet.com/series/under-the-table', + parent: 'teamskeet', + }, + { + slug: 'mydirtyuncle', + name: 'My Dirty Uncle', + url: 'https://www.teamskeet.com/series/my-dirty-uncle', + tags: ['family'], + parent: 'teamskeet', + }, + { + slug: 'mormongirlz', + name: 'Mormon Girlz', + url: 'https://www.teamskeet.com/series/mormon-girlz', + tags: ['religion'], + parent: 'teamskeet', + }, + { + slug: 'breedingmaterial', + name: 'Breeding Material', + url: 'https://www.teamskeet.com/series/breeding-material', + parent: 'teamskeet', + }, + { + slug: 'teamskeetsingles', + name: 'TeamSkeet Singels', + url: 'https://www.teamskeet.com/series/teamskeet-singles', + parent: 'teamskeet', + }, + { + slug: 'sheseducedme', + name: 'She Seduced Me', + url: 'https://www.teamskeet.com/series/she-seduced-me', + parent: 'teamskeet', + }, // PERVZ { slug: 'pervzfeatures', @@ -12859,6 +12917,12 @@ const sites = [ url: 'https://www.pervz.com/series/pervdriver', parent: 'pervz', }, + { + slug: 'charmed', + name: 'Charmed', + url: 'https://www.pervz.com/series/charmed', + parent: 'pervz', + }, // SWAPPZ { slug: 'swappzfeatures', @@ -12925,6 +12989,13 @@ const sites = [ parent: 'freeuse', tags: ['free-use', 'pov'], }, + { + slug: 'freeusesingles', + name: 'Freeuse Singles', + url: 'https://www.freeuse.com/series/freeuse-singles', + parent: 'freeuse', + tags: ['free-use'], + }, // FAMILY STROKES { slug: 'familystrokes', @@ -13006,6 +13077,14 @@ const sites = [ tags: ['family', 'milf'], parent: 'familystrokes', }, + { + slug: 'blackstepdad', + name: 'Black StepDad', + url: 'https://www.familystrokes.com/series/black-stepdad', + alias: ['bsd'], + tags: ['family'], + parent: 'familystrokes', + }, // SAY UNCLE { slug: 'blackgodz', diff --git a/src/scrapers/teamskeet.js b/src/scrapers/teamskeet.js index d41b8e2c..c9d3a3c5 100755 --- a/src/scrapers/teamskeet.js +++ b/src/scrapers/teamskeet.js @@ -33,7 +33,8 @@ async function fetchTrailerUrl(videoId, entity) { const token = res.data.token; if (token) { - return `https://customer-bk3o9te23pydwwcb.cloudflarestream.com/${token}/manifest/video.mpd?parentOrigin=${entity.origin}`; + // ffmpeg fails to read the DASH manifest over a single connection, HLS works + return `https://customer-bk3o9te23pydwwcb.cloudflarestream.com/${token}/manifest/video.m3u8?parentOrigin=${entity.origin}`; } } @@ -46,11 +47,12 @@ async function scrapeScene(scene, channel, _parameters, includeTrailers) { // release.entryId = scene.id; // legacy release.entryId = scene.itemId; - release.url = `${channel.type === 'network' || channel.parameters?.layout === 'organic' ? channel.url : channel.parent.url}/movies/${release.entryId}`; + release.url = `${channel.type === 'network' || channel.parameters?.layout === 'organic' ? channel.url : channel.parent.url}/movies/${scene.id || release.entryId}`; // numeric item ID URL 404s, id is the slug release.title = scene.title; release.description = scene.description; release.date = unprint.extractDate(scene.publishedDate, 'YYYY-MM-DD'); + release.duration = scene.d; release.actors = scene.models?.map((model) => ({ name: model.modelName || model.name || model.title, @@ -113,27 +115,22 @@ async function fetchScene(url, channel, baseScene, { parameters, includeTrailers return baseScene; } - const sceneSlug = new URL(url).pathname.match(/\/([\w-]+$)/)[1]; + const sceneSlug = new URL(url).pathname.match(/\/([\w-]+)\/?$/)?.[1]; - const res = await unprint.get(url, { - parser: { - runScripts: 'dangerously', - }, - }); + if (!sceneSlug) { + return null; + } - if (res.ok) { - const videos = res.context.window.__INITIAL_STATE__?.content?.videosContent; + // scene page no longer embeds state, look up the scene in the elastic API by its slug instead + // legacy URLs use the numeric item ID, which 404s on the site but can still be looked up + const isItemId = /^\d+$/.test(sceneSlug); + const res = await unprint.get(`https://tours-store.psmcdn.net/${parameters.endpoint}/_search?q=(${isItemId ? `itemId:${sceneSlug}` : `id:"${sceneSlug}"`} AND type:video)&size=1`); - res.context.window.fetch = () => {}; // suppress fetch missing error + if (res.ok && res.data?.hits) { + const scene = res.data.hits.hits.find(({ _source: hit }) => (isItemId ? String(hit.itemId) : hit.id) === sceneSlug)?._source; - if (!videos) { - return null; - } - - const video = videos?.[sceneSlug] || Object.values(videos)[0]; - - if (video) { - return scrapeScene(video, channel, parameters, includeTrailers); + if (scene) { + return scrapeScene(scene, channel, parameters, includeTrailers); } return null;