Compare commits

..

No commits in common. "3f30f80d348fa27dd06bb2de3fcfa1e734fa87a0" and "3c14bb26c2fc21c841a69dc62cf7b685cecd6c19" have entirely different histories.

4 changed files with 15 additions and 47 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "traxxx",
"version": "1.107.0",
"version": "1.106.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "traxxx",
"version": "1.107.0",
"version": "1.106.2",
"description": "All the latest porn releases in one place",
"main": "src/app.js",
"scripts": {

View File

@ -156,7 +156,6 @@ const sites = [
network: '21sextury',
parameters: {
referer: 'https://www.21sextury.com',
mobile: 'https://m.analteenangels.com/',
},
},
{
@ -165,10 +164,7 @@ const sites = [
url: 'https://www.assholefever.com',
description: 'Welcome to AssholeFever, the most hardcore anal site on the net. Watch your favorite pornstars and anal sluts from all over the world in big booty hardcore porn, anal gape, beads, anal creampie and more! Look inside if you dare!',
network: '21sextury',
parameters: {
networkReferer: true,
mobile: 'https://m.assholefever.com/',
},
parameters: { networkReferer: true },
},
{
slug: 'buttplays',
@ -197,7 +193,6 @@ const sites = [
parameters: {
referer: 'https://www.21sextury.com',
scene: 'https://www.21sextury.com/en/video',
mobile: 'https://m.dpfanatics.com',
photos: 'https://www.21sextury.com/en/photo',
},
},
@ -209,7 +204,6 @@ const sites = [
network: '21sextury',
parameters: {
referer: 'https://www.21sextury.com',
mobile: 'https://m.dpfanatics.com/',
},
},
{
@ -221,7 +215,6 @@ const sites = [
parameters: {
referer: 'https://www.21sextury.com',
scene: 'https://www.21sextury.com/en/video',
mobile: 'https://m.footsiebabes.com',
photos: 'https://www.21sextury.com/en/photo',
},
},

View File

@ -31,15 +31,13 @@ async function fetchPhotos(url) {
return res.body.toString();
}
function scrapePhotos(html, includeThumbnails = true) {
function scrapePhotos(html) {
const $ = cheerio.load(html, { normalizeWhitespace: true });
return $('.preview .imgLink, .pgFooterThumb a').toArray().map((linkEl) => {
const url = $(linkEl).attr('href');
if (/\/join|\/createaccount/.test(url)) {
if (!includeThumbnails) return null;
// URL links to join page instead of full photo, extract thumbnail
// /createaccount is used by e.g. Tricky Spa native site
const src = $(linkEl).find('img').attr('src');
@ -59,10 +57,10 @@ function scrapePhotos(html, includeThumbnails = true) {
// URL links to full photo
return url;
}).filter(Boolean);
});
}
async function getPhotos(albumPath, site, includeThumbnails = true) {
async function getPhotos(albumPath, site) {
const albumUrl = getAlbumUrl(albumPath, site);
if (!albumUrl) {
@ -72,7 +70,7 @@ async function getPhotos(albumPath, site, includeThumbnails = true) {
try {
const html = await fetchPhotos(albumUrl);
const $ = cheerio.load(html, { normalizeWhitespace: true });
const photos = scrapePhotos(html, includeThumbnails);
const photos = scrapePhotos(html, site);
const lastPage = $('.Gamma_Paginator a.last').attr('href')?.match(/\d+$/)[0];
@ -83,7 +81,7 @@ async function getPhotos(albumPath, site, includeThumbnails = true) {
const pageUrl = `${albumUrl}/${page}`;
const pageHtml = await fetchPhotos(pageUrl);
return scrapePhotos(pageHtml, includeThumbnails);
return scrapePhotos(pageHtml, site);
}, {
concurrency: 2,
});
@ -186,10 +184,9 @@ function scrapeAll(html, site, networkUrl, hasTeaser = true) {
});
}
async function scrapeScene(html, url, site, scrapedRelease, mobileHtml) {
async function scrapeScene(html, url, site, scrapedRelease) {
const $ = cheerio.load(html, { normalizeWhitespace: true });
const m$ = mobileHtml && cheerio.load(mobileHtml, { normalizeWhitespace: true });
const release = { $, url };
const release = { $ };
const json = $('script[type="application/ld+json"]').html();
const videoJson = $('script:contains("window.ScenePlayerOptions")').html();
@ -238,14 +235,7 @@ async function scrapeScene(html, url, site, scrapedRelease, mobileHtml) {
if (videoData.picPreview && new URL(videoData.picPreview).pathname.length > 1) release.poster = videoData.picPreview; // sometimes links to just https://images02-fame.gammacdn.com/
const photoLink = $('.picturesItem a').attr('href');
const mobilePhotos = m$ ? m$('.preview-displayer a img').map((photoIndex, photoEl) => $(photoEl).attr('src')).toArray() : [];
if (photoLink) {
const photos = await getPhotos(photoLink, site, mobilePhotos.length < 3); // only get thumbnails when less than 3 mobile photos are available
release.photos = [...photos, ...mobilePhotos];
} else {
release.photos = mobilePhotos;
}
if (photoLink) release.photos = await getPhotos(photoLink, site);
const trailer = `${videoData.playerOptions.host}${videoData.url}`;
release.trailer = [
@ -467,13 +457,9 @@ async function fetchUpcoming(site) {
return scrapeAll(res.body.toString(), site, null, false);
}
function getDeepUrl(url, site, release, mobile = false) {
function getDeepUrl(url, site, release) {
const pathname = release?.path || new URL(url).pathname;
if (mobile) {
return `${site.parameters.mobile}${pathname}`;
}
if (site.parameters?.deep === 'network') {
return `${site.network.url}${pathname}`;
}
@ -491,24 +477,13 @@ async function fetchScene(url, site, release) {
}
const deepUrl = getDeepUrl(url, site, release);
const mobileUrl = site.parameters?.mobile && getDeepUrl(url, site, release, true);
console.log(mobileUrl);
if (deepUrl) {
const [res, mobileRes] = await Promise.all([
bhttp.get(deepUrl),
mobileUrl && bhttp.get(mobileUrl, {
headers: {
// don't redirect to main site
'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Mobile Safari/537.36',
},
}),
]);
const res = await bhttp.get(deepUrl);
if (res.statusCode === 200) {
const mobileBody = mobileRes.statusCode === 200 ? mobileRes.body.toString() : null;
const scene = await scrapeScene(res.body.toString(), url, site, release, mobileBody);
const scene = await scrapeScene(res.body.toString(), url, site, release);
return { ...scene, deepUrl };
}
}