traxxx/src/scrapers/badoink.js

99 lines
3.5 KiB
JavaScript

'use strict';
const qu = require('../utils/qu');
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;
release.actors = query.all('.video-card-details--cast a').map(el => ({
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;
release.actors = query.all('.video-actors a').map(el => ({
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;
}
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;
}
module.exports = {
fetchLatest,
scrapeScene,
};