166 lines
4.3 KiB
JavaScript
Executable File
166 lines
4.3 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
const unprint = require('unprint');
|
|
|
|
const { convert } = require('../utils/convert');
|
|
|
|
function scrapeAll(scenes) {
|
|
return scenes.map(({ query }) => {
|
|
const release = {};
|
|
|
|
release.url = query.url('.content-title a');
|
|
release.entryId = new URL(release.url).pathname.match(/\/view\/(\d+)/)[1];
|
|
|
|
release.title = query.content('.content-title a');
|
|
release.date = query.date('.content-date strong', 'DD/MM/YYYY');
|
|
release.duration = query.duration('.content-date');
|
|
|
|
release.actors = query.all('.content-models a').map((actorEl) => ({
|
|
name: unprint.query.content(actorEl),
|
|
url: unprint.query.url(actorEl, null),
|
|
}));
|
|
|
|
release.poster = query.img('.content-thumbnail img, .large-thumbnail img') || query.poster('.content-thumbnail video, .large-thumbnail video');
|
|
release.photos = query.imgs('.small-thumbnails img'); // actor page only
|
|
|
|
release.teaser = query.video('.vid-hover source');
|
|
|
|
return release;
|
|
});
|
|
}
|
|
|
|
async function fetchLatest(channel, page = 1) {
|
|
const res = await unprint.get(`https://tour.hitzefrei.com/videos?site=${channel.parameters.siteId}&page=${page}`, { selectAll: '.hitem' });
|
|
|
|
if (res.ok) {
|
|
return scrapeAll(res.context, channel);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
function scrapeScene({ query }, url) {
|
|
const release = {};
|
|
|
|
release.entryId = new URL(url).pathname.match(/\/view\/(\d+)/)[1];
|
|
|
|
release.title = query.content('.content-title');
|
|
release.description = query.content('.content-description p');
|
|
|
|
release.date = query.date('.content-metas span:nth-child(4)', 'DD/MM/YYYY');
|
|
release.duration = query.duration('.content-metas span:nth-child(2)');
|
|
release.likes = query.number('.content-metas span:nth-child(6)');
|
|
|
|
release.actors = query.all('.model-thumb a').map((actorEl) => ({
|
|
name: unprint.query.attribute(actorEl, 'img', 'alt'),
|
|
url: unprint.query.url(actorEl, null),
|
|
avatar: unprint.query.img(actorEl),
|
|
}));
|
|
|
|
release.poster = query.poster('.content-video video');
|
|
|
|
release.photos = query.urls('#photo-carousel a').map((photo) => [
|
|
photo.replace('/full', ''),
|
|
photo,
|
|
photo.replace('/full', '/thumbs'),
|
|
]);
|
|
|
|
release.trailer = query.video('.content-video source');
|
|
|
|
return release;
|
|
}
|
|
|
|
async function fetchScene(url) {
|
|
const res = await unprint.get(url, { select: '#content-details' });
|
|
|
|
if (res.ok) {
|
|
return scrapeScene(res.context, url);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
async function fetchActorScenes({ query }, accReleases = []) {
|
|
const releases = scrapeAll(unprint.initAll(query.all('.container-large-video-thumb')));
|
|
const nextPage = query.url('.pagination li:nth-last-child(2) a');
|
|
|
|
if (nextPage) {
|
|
const res = await unprint.get(nextPage);
|
|
|
|
if (res.ok) {
|
|
return fetchActorScenes(res.context, accReleases.concat(releases));
|
|
}
|
|
}
|
|
|
|
return accReleases.concat(releases);
|
|
}
|
|
|
|
async function scrapeProfile({ query }, _entity, include) {
|
|
const profile = {};
|
|
|
|
profile.dateOfBirth = query.date('.col-birtdate .stat-value, .col-birthdate .stat-value', 'YYYY-MM-DD'); // sic
|
|
profile.birthPlace = query.content('.col-birth .stat-value');
|
|
|
|
profile.measurements = query.content('.col-measurements .stat-value');
|
|
profile.height = convert(query.content('.col-height .stat-value'), 'cm');
|
|
profile.weight = convert(query.number('.col-weight .stat-value'), 'lb', 'kg');
|
|
|
|
profile.eyes = query.content('.col-eyes .stat-value');
|
|
profile.hair = query.content('.col-hair .stat-value');
|
|
|
|
profile.description = query.content('.model-profile .model-profile');
|
|
profile.avatar = query.img('.model-thumbnail img');
|
|
|
|
if (include.releases) {
|
|
profile.releases = await fetchActorScenes({ query });
|
|
}
|
|
|
|
return profile;
|
|
}
|
|
|
|
async function getActorUrl(baseActor) {
|
|
if (baseActor.url) {
|
|
return baseActor.url;
|
|
}
|
|
|
|
const res = await unprint.post('https://tour.hitzefrei.com/search-preview', {
|
|
q: baseActor.name,
|
|
}, {
|
|
headers: {
|
|
'Accept-Language': 'en-US',
|
|
},
|
|
});
|
|
|
|
if (res.ok) {
|
|
const actor = res.data.find((result) => result.type === 'model' && result.title === baseActor.name);
|
|
|
|
if (actor) {
|
|
return actor.url;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function fetchProfile(baseActor, entity, include) {
|
|
const actorUrl = await getActorUrl(baseActor);
|
|
|
|
if (actorUrl) {
|
|
const res = await unprint.get(actorUrl);
|
|
|
|
if (res.ok) {
|
|
return scrapeProfile(res.context, entity, include);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
module.exports = {
|
|
fetchLatest,
|
|
fetchScene,
|
|
fetchProfile,
|
|
};
|