2021-02-03 01:59:39 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const qu = require('../utils/qu');
|
2021-02-03 20:03:35 +00:00
|
|
|
const slugify = require('../utils/slugify');
|
|
|
|
const { convert } = require('../utils/convert');
|
2021-02-03 01:59:39 +00:00
|
|
|
|
|
|
|
function getPoster(posterSources) {
|
|
|
|
if (posterSources?.[0]) {
|
|
|
|
const { origin, pathname } = new URL(posterSources[0]);
|
|
|
|
|
|
|
|
return [
|
|
|
|
`${origin}${pathname}`,
|
|
|
|
...posterSources,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function scrapeAll(scenes, channel) {
|
|
|
|
return scenes.map(({ query }) => {
|
|
|
|
const release = {};
|
|
|
|
|
|
|
|
release.url = query.url('a', 'href', { origin: channel.url });
|
|
|
|
release.entryId = query.q(null, 'data-video-card-scene-id') || query.q('video', 'data-video-preview-scene-id') || new URL(release.url).pathname.match(/(\d+)\/?$/)?.[1];
|
|
|
|
|
|
|
|
release.title = query.cnt('.video-card-title span') || query.q('.video-card-title', 'title');
|
|
|
|
release.description = query.cnt('.video-card-description');
|
|
|
|
|
|
|
|
release.date = query.date('.video-card-upload-date', 'YYYY-MM-DD HH:mm:ss', null, 'content') || query.date('.video-card-upload-date', 'MMMM DD, YYYY');
|
|
|
|
release.duration = query.duration('.video-card-duration', null, 'content') || query.number('.video-card-duration') * 60;
|
|
|
|
|
2021-11-20 22:59:15 +00:00
|
|
|
release.actors = query.all('.video-card-details--cast a').map((el) => ({
|
2021-02-03 01:59:39 +00:00
|
|
|
name: qu.query.cnt(el),
|
|
|
|
url: qu.query.url(el, null, 'href', { origin: channel.url }),
|
|
|
|
}));
|
|
|
|
|
|
|
|
release.tags = query.cnts('.video-card-tags a');
|
|
|
|
|
|
|
|
const posterSources = query.srcset('picture source', 'data-srcset') || [query.img('.video-card-image', 'data-src')];
|
|
|
|
release.poster = getPoster(posterSources);
|
|
|
|
|
|
|
|
release.teaser = query.video('video') || (channel.parameters?.teasers !== false ? `https://p.badoinkvr.com/d/scene_files/${release.entryId}/preview/preview.mp4` : null);
|
|
|
|
|
|
|
|
return release;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function scrapeScene({ query }, url, channel) {
|
|
|
|
const release = {};
|
|
|
|
|
|
|
|
release.entryId = new URL(url).pathname.match(/(\d+)\/?$/)?.[1];
|
|
|
|
|
|
|
|
release.title = query.cnt('.video-title', '.breadcrumbs__item:last-child [itemprop=name]');
|
|
|
|
release.description = query.cnt('.video-description');
|
|
|
|
|
|
|
|
release.date = query.date('.video-upload-date', 'YYYY-MM-DD HH:mm:ss', null, 'content') || query.date('.video-upload-date', 'MMMM DD, YYYY', /\w+ \d{1,2}, \d{4}/);
|
|
|
|
release.duration = query.duration('.video-duration', null, 'content') || query.number('.video-duration') * 60;
|
|
|
|
|
2021-11-20 22:59:15 +00:00
|
|
|
release.actors = query.all('.video-actors a').map((el) => ({
|
2021-02-03 01:59:39 +00:00
|
|
|
name: qu.query.cnt(el),
|
|
|
|
url: qu.query.url(el, null, 'href', { origin: channel.url }),
|
|
|
|
}));
|
|
|
|
|
|
|
|
release.tags = query.cnts('.video-tags a');
|
|
|
|
|
|
|
|
const posterSources = query.srcset('.video-image-container picture source', 'srcset') || [query.img('.video-image')];
|
|
|
|
release.poster = getPoster(posterSources);
|
|
|
|
|
|
|
|
const photos = query.imgs('.gallery .gallery-item', 'data-big-image');
|
|
|
|
const extraPhotoCount = query.number('.gallery .gallery-item:last-child', /\d+/, 'data-desktop-text');
|
|
|
|
const lastPhoto = photos.slice(-1)[0];
|
|
|
|
const photosHaveIndex = /_\d+\./.test(lastPhoto);
|
|
|
|
|
|
|
|
release.photos = [
|
|
|
|
...photos,
|
|
|
|
...Array.from(photosHaveIndex ? { length: extraPhotoCount } : [], (value, index) => lastPhoto.replace(/_\d+\./, `_${index + photos.length + 1}.`)),
|
|
|
|
];
|
|
|
|
|
|
|
|
release.teaser = channel.parameters?.teasers !== false ? `https://p.badoinkvr.com/d/scene_files/${release.entryId}/preview/preview.mp4` : null;
|
|
|
|
|
|
|
|
return release;
|
|
|
|
}
|
|
|
|
|
2021-02-03 20:03:35 +00:00
|
|
|
function scrapeProfile({ query }, url, entity) {
|
|
|
|
const profile = { url };
|
|
|
|
|
|
|
|
const bio = query.all('.girl-details-stats-item').reduce((acc, el) => ({
|
|
|
|
...acc,
|
|
|
|
[slugify(qu.query.cnt(el, '.girl-details-stat'))]: qu.query.cnt(el, '.girl-details-stat-value'),
|
|
|
|
}), {});
|
|
|
|
|
|
|
|
profile.description = query.cnt('.girl-details-bio');
|
|
|
|
|
|
|
|
profile.age = bio.age;
|
|
|
|
profile.birthPlace = bio.country;
|
|
|
|
profile.ethnicity = bio.ethnicity;
|
|
|
|
|
|
|
|
profile.height = convert(bio.height, 'cm');
|
|
|
|
profile.weight = convert(bio.weight, 'lb', 'kg');
|
|
|
|
|
|
|
|
profile.measurements = bio.measurements;
|
|
|
|
|
|
|
|
profile.hairColor = bio.hair;
|
|
|
|
profile.eyes = bio.eyes;
|
|
|
|
|
|
|
|
const avatarSources = query.srcset('.girl-details-photo-content picture source', 'srcset') || [query.img('.girl-details-photo')];
|
|
|
|
|
|
|
|
profile.avatar = getPoster(avatarSources);
|
|
|
|
profile.social = query.urls('.girl-details-social-media-list a');
|
|
|
|
|
|
|
|
profile.scenes = scrapeAll(qu.initAll(query.all('.video-card')), entity);
|
|
|
|
|
|
|
|
return profile;
|
|
|
|
}
|
|
|
|
|
2021-02-03 01:59:39 +00:00
|
|
|
async function fetchLatest(channel, page) {
|
|
|
|
const res = await qu.getAll(`${channel.url}/${channel.parameters?.latest || 'vrpornvideos'}/${page}`, '.video-card', {
|
|
|
|
Cookie: 'affsubid=12345-;', // required to show teaser video, exact number doesn't seem to matter
|
|
|
|
});
|
|
|
|
|
|
|
|
if (res.ok) {
|
|
|
|
return scrapeAll(res.items, channel);
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.status;
|
|
|
|
}
|
|
|
|
|
2021-02-03 20:03:35 +00:00
|
|
|
async function fetchProfile(baseActor, { entity }) {
|
|
|
|
const url = `${entity.url}/${entity.parameters?.actor || 'pornstar'}/${slugify(baseActor.name, '')}/`;
|
|
|
|
const res = await qu.get(url);
|
|
|
|
|
|
|
|
if (res.ok) {
|
|
|
|
return scrapeProfile(res.item, url, entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.status;
|
|
|
|
}
|
|
|
|
|
2021-02-03 01:59:39 +00:00
|
|
|
module.exports = {
|
|
|
|
fetchLatest,
|
2021-02-03 20:03:35 +00:00
|
|
|
fetchProfile,
|
2021-02-03 01:59:39 +00:00
|
|
|
scrapeScene,
|
|
|
|
};
|