Added Jay's POV scraper.

This commit is contained in:
ThePendulum 2020-01-10 22:10:11 +01:00
parent 53fcb6a5cd
commit f572f38b5c
16 changed files with 123 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -50,6 +50,11 @@ const networks = [
url: 'https://evilangel.com', url: 'https://evilangel.com',
description: 'Welcome to the award winning Evil Angel website, home to the most popular pornstars of today, yesterday and tomorrow in their most extreme and hardcore porn scenes to date. We feature almost 30 years of rough sex videos and hardcore anal porn like you\'ve never seen before, and have won countless AVN and XBiz awards including \'Best Site\' and \'Best Studio\'.', description: 'Welcome to the award winning Evil Angel website, home to the most popular pornstars of today, yesterday and tomorrow in their most extreme and hardcore porn scenes to date. We feature almost 30 years of rough sex videos and hardcore anal porn like you\'ve never seen before, and have won countless AVN and XBiz awards including \'Best Site\' and \'Best Studio\'.',
}, },
{
slug: 'jayrock',
name: 'JayRock Productions',
url: 'https://www.jayrockcontent.com',
},
{ {
slug: 'julesjordan', slug: 'julesjordan',
name: 'Jules Jordan', name: 'Jules Jordan',

View File

@ -1142,6 +1142,13 @@ function getSites(networksMap) {
parameters: JSON.stringify({ independent: true }), parameters: JSON.stringify({ independent: true }),
network_id: networksMap.evilangel, network_id: networksMap.evilangel,
}, },
// JAYS POV
{
slug: 'jayspov',
name: 'Jay\'s POV',
url: 'https://www.jayspov.net',
network_id: networksMap.jayrock,
},
// JULES JORDAN // JULES JORDAN
{ {
slug: 'julesjordan', slug: 'julesjordan',

View File

@ -8,6 +8,7 @@
"strict": 0, "strict": 0,
"no-unused-vars": ["error", {"argsIgnorePattern": "^_"}], "no-unused-vars": ["error", {"argsIgnorePattern": "^_"}],
"no-console": 0, "no-console": 0,
"no-underscore-dangle": 0,
"indent": "off", "indent": "off",
"template-curly-spacing": "off", "template-curly-spacing": "off",
"max-len": [2, {"code": 300, "tabWidth": 4, "ignoreUrls": true}], "max-len": [2, {"code": 300, "tabWidth": 4, "ignoreUrls": true}],

104
src/scrapers/jayspov.js Normal file
View File

@ -0,0 +1,104 @@
'use strict';
const Promise = require('bluebird');
const bhttp = require('bhttp');
const slugify = require('../utils/slugify');
async function fetchToken() {
const res = await bhttp.get('https://jayspov.net/activity');
const html = res.body.toString();
const time = html.match(/"aet":\d+/)[0].split(':')[1];
const ah = html.match(/"ah":"[\w-]+"/)[0].split(':')[1].slice(1, -1);
const token = ah.split('').reverse().join('');
return { time, token };
}
async function fetchActors(entryId, { token, time }) {
const url = `https://jayspov.net/sapi/${token}/${time}/model.getModelContent?_method=model.getModelContent&tz=1&fields[0]=modelId.stageName&fields[1]=_last&fields[2]=modelId.upsellLink&fields[3]=modelId.upsellText&limit=25&transitParameters[contentId]=${entryId}`;
const res = await bhttp.get(url);
if (res.statusCode === 200 && res.body.status === true) {
return Object.values(res.body.response.collection).map(actor => Object.values(actor.modelId.collection)[0].stageName);
}
return [];
}
async function fetchTrailerLocation(entryId) {
const url = `https://jayspov.net/api/download/${entryId}/hd1080/stream`;
const res = await bhttp.get(url, {
followRedirects: false,
});
if (res.statusCode === 302) {
return res.headers.location;
}
return null;
}
async function scrapeScene(scene, site, tokens) {
const release = {
entryId: scene.id,
title: scene.title,
duration: scene.length,
tokens, // attach tokens to reduce number of requests required for deep fetching
site,
};
release.url = `https://jayspov.net/scene/${release.entryId}/${slugify(release.title, true)}`;
release.date = new Date(scene.sites.collection[scene.id].publishDate);
release.poster = scene._resources.primary[0].url;
if (scene.tags) release.tags = Object.values(scene.tags.collection).map(tag => tag.alias);
if (scene._resources.base) release.photos = scene._resources.base.map(resource => resource.url);
const [actors, trailer] = await Promise.all([
fetchActors(release.entryId, tokens),
fetchTrailerLocation(release.entryId),
]);
release.actors = actors;
if (trailer) release.trailer = { src: trailer, quality: 1080 };
return release;
}
function scrapeLatest(scenes, site, tokens) {
return Promise.map(scenes, async scene => scrapeScene(scene, site, tokens), { concurrency: 10 });
}
async function fetchLatest(site) {
const { time, token } = await fetchToken();
const url = `https://jayspov.net/sapi/${token}/${time}/content.load?fields[0]=generatedContentLink&fields[1]=cName&fields[2]=title&fields[3]=_resources.primary.url&fields[4]=sites.publishDate&fields[5]=type&fields[6]=_resources.base.url&fields[7]=_resources.base&fields[8]=length&limit=7&metaFields[resources][thumb]=baseline.sprite.w225i&transitParameters[showOnHome]=true&transitParameters[v1]=OhUOlmasXD&transitParameters[v2]=OhUOlmasXD&transitParameters[preset]=videos`;
const res = await bhttp.get(url);
if (res.statusCode === 200 && res.body.status) {
return scrapeLatest(res.body.response.collection, site, { time, token });
}
return null;
}
async function fetchScene(url, site, release) {
const { time, token } = release?.tokens || await fetchToken(); // use attached tokens when deep fetching
const { pathname } = new URL(url);
const entryId = pathname.split('/')[2];
const res = await bhttp.get(`https://jayspov.net/sapi/${token}/${time}/content.load?_method=content.load&tz=1&filter[id][fields][0]=id&filter[id][values][0]=${entryId}&fields[0]=type&fields[1]=title&fields[2]=sites.publishDate&fields[3]=member&fields[4]=id&fields[5]=tags._last&fields[6]=tags.alias&fields[7]=tags&fields[8]=description&fields[9]=related.relatedContentId.id&fields[10]=related.relatedContentId.title&fields[11]=siteProps.ubs.joinUrl&fields[12]=extender.contentId&fields[13]=vr&fields[14]=backLinkProp.value&fields[15]=backLinkProp.public&limit=1&transitParameters[v1]=ykYa8ALmUD&transitParameters[preset]=scene`);
if (res.statusCode === 200 && res.body.status) {
return scrapeScene(res.body.response.collection[0], site, { time, token });
}
return null;
}
module.exports = {
fetchLatest,
fetchScene,
};

View File

@ -7,6 +7,7 @@ const bangbros = require('./bangbros');
const blowpass = require('./blowpass'); const blowpass = require('./blowpass');
const dogfart = require('./dogfart'); const dogfart = require('./dogfart');
const evilangel = require('./evilangel'); const evilangel = require('./evilangel');
const jayspov = require('./jayspov');
const kink = require('./kink'); const kink = require('./kink');
const mikeadriano = require('./mikeadriano'); const mikeadriano = require('./mikeadriano');
const mofos = require('./mofos'); const mofos = require('./mofos');
@ -40,6 +41,7 @@ module.exports = {
dogfart, dogfart,
dogfartnetwork: dogfart, dogfartnetwork: dogfart,
evilangel, evilangel,
jayspov,
julesjordan, julesjordan,
kellymadison, kellymadison,
kink, kink,

View File

@ -1,7 +1,9 @@
'use strict'; 'use strict';
function slugify(string) { function slugify(string, encode = false) {
return string.trim().toLowerCase().match(/\w+/g).join('-'); const slug = string.trim().toLowerCase().match(/\w+/g).join('-');
return encode ? encodeURI(slug) : slug;
} }
module.exports = slugify; module.exports = slugify;