Compare commits
10
Commits
fef686f977
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98121e6162 | ||
|
|
e447a0b6da | ||
|
|
530d45448a | ||
|
|
6a0759693c | ||
|
|
83c78ade5d | ||
|
|
eebe8eef89 | ||
|
|
a22a7288c1 | ||
|
|
40d56c515d | ||
|
|
b8ad6bb10b | ||
|
|
131f744745 |
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.256.0",
|
"version": "1.256.5",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.256.0",
|
"version": "1.256.5",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.458.0",
|
"@aws-sdk/client-s3": "^3.458.0",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.256.0",
|
"version": "1.256.5",
|
||||||
"description": "All the latest porn releases in one place",
|
"description": "All the latest porn releases in one place",
|
||||||
"main": "src/app.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ const networks = [
|
|||||||
{
|
{
|
||||||
slug: 'familystrokes',
|
slug: 'familystrokes',
|
||||||
name: 'Family Strokes',
|
name: 'Family Strokes',
|
||||||
url: 'https://www.familystrokes.com/',
|
url: 'https://www.familystrokes.com',
|
||||||
parent: 'paperstreetmedia',
|
parent: 'paperstreetmedia',
|
||||||
parameters: {
|
parameters: {
|
||||||
endpoint: 'familybundle',
|
endpoint: 'familybundle',
|
||||||
|
|||||||
+87
-11
@@ -8517,6 +8517,33 @@ const sites = [
|
|||||||
id: 'hookup-pad',
|
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 */
|
/* premium */
|
||||||
{
|
{
|
||||||
slug: 'analmom',
|
slug: 'analmom',
|
||||||
@@ -8551,12 +8578,9 @@ const sites = [
|
|||||||
{
|
{
|
||||||
slug: 'mylfdom',
|
slug: 'mylfdom',
|
||||||
name: 'MYLF Dom',
|
name: 'MYLF Dom',
|
||||||
url: 'https://www.mylfdom.com',
|
url: 'https://www.mylf.com/series/mylfdom-ts',
|
||||||
tags: ['bdsm', 'milf'],
|
tags: ['bdsm', 'milf'],
|
||||||
parent: 'mylf',
|
parent: 'mylf',
|
||||||
parameters: {
|
|
||||||
endpoint: 'mylf_dom',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// NAUGHTY AMERICA
|
// NAUGHTY AMERICA
|
||||||
{
|
{
|
||||||
@@ -12397,13 +12421,6 @@ const sites = [
|
|||||||
url: 'https://www.teamskeet.com/series/bad-milfs',
|
url: 'https://www.teamskeet.com/series/bad-milfs',
|
||||||
parent: 'teamskeet',
|
parent: 'teamskeet',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
slug: 'blackstepdad',
|
|
||||||
name: 'Black StepDad',
|
|
||||||
url: 'https://www.teamskeet.com/series/black-stepdad',
|
|
||||||
alias: ['bsd'],
|
|
||||||
parent: 'teamskeet',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
slug: 'exxxtrasmall',
|
slug: 'exxxtrasmall',
|
||||||
name: 'Exxxtra Small',
|
name: 'Exxxtra Small',
|
||||||
@@ -12783,6 +12800,44 @@ const sites = [
|
|||||||
url: 'https://www.teamskeet.com/series/passport-bros',
|
url: 'https://www.teamskeet.com/series/passport-bros',
|
||||||
parent: 'teamskeet',
|
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 Singles',
|
||||||
|
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
|
// PERVZ
|
||||||
{
|
{
|
||||||
slug: 'pervzfeatures',
|
slug: 'pervzfeatures',
|
||||||
@@ -12859,6 +12914,12 @@ const sites = [
|
|||||||
url: 'https://www.pervz.com/series/pervdriver',
|
url: 'https://www.pervz.com/series/pervdriver',
|
||||||
parent: 'pervz',
|
parent: 'pervz',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slug: 'charmed',
|
||||||
|
name: 'Charmed',
|
||||||
|
url: 'https://www.pervz.com/series/charmed',
|
||||||
|
parent: 'pervz',
|
||||||
|
},
|
||||||
// SWAPPZ
|
// SWAPPZ
|
||||||
{
|
{
|
||||||
slug: 'swappzfeatures',
|
slug: 'swappzfeatures',
|
||||||
@@ -12925,6 +12986,13 @@ const sites = [
|
|||||||
parent: 'freeuse',
|
parent: 'freeuse',
|
||||||
tags: ['free-use', 'pov'],
|
tags: ['free-use', 'pov'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slug: 'freeusesingles',
|
||||||
|
name: 'Freeuse Singles',
|
||||||
|
url: 'https://www.freeuse.com/series/freeuse-singles',
|
||||||
|
parent: 'freeuse',
|
||||||
|
tags: ['free-use'],
|
||||||
|
},
|
||||||
// FAMILY STROKES
|
// FAMILY STROKES
|
||||||
{
|
{
|
||||||
slug: 'familystrokes',
|
slug: 'familystrokes',
|
||||||
@@ -13006,6 +13074,14 @@ const sites = [
|
|||||||
tags: ['family', 'milf'],
|
tags: ['family', 'milf'],
|
||||||
parent: 'familystrokes',
|
parent: 'familystrokes',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
slug: 'blackstepdad',
|
||||||
|
name: 'Black StepDad',
|
||||||
|
url: 'https://www.familystrokes.com/series/black-stepdad',
|
||||||
|
alias: ['bsd'],
|
||||||
|
tags: ['family'],
|
||||||
|
parent: 'familystrokes',
|
||||||
|
},
|
||||||
// SAY UNCLE
|
// SAY UNCLE
|
||||||
{
|
{
|
||||||
slug: 'blackgodz',
|
slug: 'blackgodz',
|
||||||
|
|||||||
+18
-21
@@ -33,7 +33,8 @@ async function fetchTrailerUrl(videoId, entity) {
|
|||||||
const token = res.data.token;
|
const token = res.data.token;
|
||||||
|
|
||||||
if (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,17 +47,18 @@ async function scrapeScene(scene, channel, _parameters, includeTrailers) {
|
|||||||
// release.entryId = scene.id; // legacy
|
// release.entryId = scene.id; // legacy
|
||||||
release.entryId = scene.itemId;
|
release.entryId = scene.itemId;
|
||||||
|
|
||||||
release.url = `${channel.type === 'network' || channel.parameters?.layout === 'organic' ? channel.url : channel.parent.url}/movies/${release.entryId}`;
|
release.url = `${channel.origin}/movies/${scene.id || release.entryId}`; // numeric item ID URL 404s, id is the slug
|
||||||
|
|
||||||
release.title = scene.title;
|
release.title = scene.title;
|
||||||
release.description = scene.description;
|
release.description = scene.description;
|
||||||
release.date = unprint.extractDate(scene.publishedDate, 'YYYY-MM-DD');
|
release.date = unprint.extractDate(scene.publishedDate, 'YYYY-MM-DD');
|
||||||
|
release.duration = scene.d;
|
||||||
|
|
||||||
release.actors = scene.models?.map((model) => ({
|
release.actors = scene.models?.map((model) => ({
|
||||||
name: model.modelName || model.name || model.title,
|
name: model.modelName || model.name || model.title,
|
||||||
avatar: model.img,
|
avatar: model.img,
|
||||||
gender: model.gender,
|
gender: model.gender,
|
||||||
url: `${channel.url}/models/${model.modelId || model.id}`,
|
url: `${channel.origin}/models/${model.modelId || model.id}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (scene.img) {
|
if (scene.img) {
|
||||||
@@ -92,7 +94,7 @@ function scrapeAll(scenes, channel, parameters) {
|
|||||||
|
|
||||||
async function fetchLatest(channel, page = 1, { parameters }) {
|
async function fetchLatest(channel, page = 1, { parameters }) {
|
||||||
// url: 'https://www.pervz.com/series/pervz-features',
|
// url: 'https://www.pervz.com/series/pervz-features',
|
||||||
const seriesId = parameters.id || new URL(channel.url).pathname.match(/\/series\/([a-z-]+)/)?.[1];
|
const seriesId = parameters.id || new URL(channel.url).pathname.match(/\/series\/([\w-]+)/)?.[1];
|
||||||
|
|
||||||
const url = seriesId
|
const url = seriesId
|
||||||
? `https://tours-store.psmcdn.net/${parameters.endpoint}/_search?q=(site.seo.seoSlug:"${seriesId}" AND type:video)&sort=publishedDate:desc&size=30&from=${(page - 1) * 30}`
|
? `https://tours-store.psmcdn.net/${parameters.endpoint}/_search?q=(site.seo.seoSlug:"${seriesId}" AND type:video)&sort=publishedDate:desc&size=30&from=${(page - 1) * 30}`
|
||||||
@@ -113,27 +115,22 @@ async function fetchScene(url, channel, baseScene, { parameters, includeTrailers
|
|||||||
return baseScene;
|
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, {
|
if (!sceneSlug) {
|
||||||
parser: {
|
return null;
|
||||||
runScripts: 'dangerously',
|
}
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res.ok) {
|
// scene page no longer embeds state, look up the scene in the elastic API by its slug instead
|
||||||
const videos = res.context.window.__INITIAL_STATE__?.content?.videosContent;
|
// 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) {
|
if (scene) {
|
||||||
return null;
|
return scrapeScene(scene, channel, parameters, includeTrailers);
|
||||||
}
|
|
||||||
|
|
||||||
const video = videos?.[sceneSlug] || Object.values(videos)[0];
|
|
||||||
|
|
||||||
if (video) {
|
|
||||||
return scrapeScene(video, channel, parameters, includeTrailers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+5
-4
@@ -79,13 +79,14 @@ function withRelations(queryBuilder, withMedia) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function matchTags(rawTags) {
|
async function matchTags(rawTags) {
|
||||||
const tags = rawTags
|
const tags = Array.from(new Set(rawTags
|
||||||
.map((tag) => tag?.trim().match(/[a-z0-9()-]+/ig)?.join(' ').toLowerCase())
|
.map((tag) => (typeof tag === 'string' ? tag : null)?.trim().match(/[a-z0-9()-]+/ig)?.join(' ').toLowerCase())
|
||||||
.filter(Boolean);
|
.filter(Boolean)));
|
||||||
|
|
||||||
|
// array binding, large batches can easily exceed the bindings limit otherwise
|
||||||
const tagEntries = await knex('tags')
|
const tagEntries = await knex('tags')
|
||||||
.select('tags.id', 'tags.name', 'tags.alias_for', 'tags.implied_tag_ids')
|
.select('tags.id', 'tags.name', 'tags.alias_for', 'tags.implied_tag_ids')
|
||||||
.whereIn(knex.raw('lower(tags.name)'), tags);
|
.whereRaw('lower(tags.name) = ANY(:tags)', { tags });
|
||||||
|
|
||||||
const tagIdsBySlug = tagEntries
|
const tagIdsBySlug = tagEntries
|
||||||
.reduce((acc, tag) => ({
|
.reduce((acc, tag) => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user