97 lines
2.5 KiB
JavaScript
97 lines
2.5 KiB
JavaScript
'use strict';
|
|
|
|
const unprint = require('unprint');
|
|
|
|
function scrapeAll(scenes, channel) {
|
|
return scenes.map(({ query }) => {
|
|
const release = {};
|
|
|
|
release.url = query.url('a.video-container__description--title, a.video-container__image');
|
|
release.entryId = new URL(release.url).pathname.split('/').at(-1);
|
|
|
|
release.title = query.content('.video-container__description--title');
|
|
|
|
release.actors = query.all('.video-container__description--author a').map((actorEl) => ({
|
|
name: unprint.query.content(actorEl),
|
|
url: unprint.query.url(actorEl, null, { origin: channel.url }),
|
|
}));
|
|
|
|
const poster = query.img('.video-container__image img');
|
|
|
|
if (poster) {
|
|
release.poster = [
|
|
poster.replace('/videoList', '/videoDetail2x'),
|
|
poster.replace('/videoList', '/videoDetail'),
|
|
poster,
|
|
];
|
|
}
|
|
|
|
return release;
|
|
});
|
|
}
|
|
|
|
function scrapeScene({ query }, { url, entity }) {
|
|
const release = {};
|
|
|
|
release.entryId = new URL(url).pathname.split('/').at(-1);
|
|
|
|
release.title = query.content('.video-detail__header--container h1');
|
|
release.description = query.content('.description p');
|
|
|
|
release.actors = query.all('.video-detail__description--author a:not(.logo)').map((actorEl) => ({
|
|
name: unprint.query.content(actorEl, '.title'),
|
|
url: unprint.query.url(actorEl, null, { origin: entity.url }),
|
|
}));
|
|
|
|
release.poster = query.img('#video', { attribute: 'data-poster' });
|
|
|
|
release.photos = query.imgs('.gallery-slider img').map((source) => [
|
|
source.replace('/galleryList', '/galleryDetail'),
|
|
source,
|
|
]);
|
|
|
|
release.trailer = query.videos('#video source')?.map((source) => ({
|
|
src: source,
|
|
quality: (source.includes('4k') && 2160)
|
|
|| (source.includes('1080') && 1080)
|
|
|| (source.includes('720') && 720) // not observed, but just in case
|
|
|| (source.includes('480') && 480), // not observed, but just in case
|
|
}));
|
|
|
|
return release;
|
|
}
|
|
|
|
function scrapeProfile({ query }) {
|
|
const profile = {};
|
|
|
|
profile.avatar = query.img('img.model-cover-photo');
|
|
|
|
return profile;
|
|
}
|
|
|
|
async function fetchLatest(channel, page = 1) {
|
|
const res = await unprint.get(`${channel.url}/newest?page=${page}`, { selectAll: '.videos .video-container' });
|
|
|
|
if (res.ok) {
|
|
return scrapeAll(res.context, channel);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
async function fetchProfile({ slug }, entity) {
|
|
const res = await unprint.get(`${entity.url}/model/${slug}`);
|
|
|
|
if (res.ok) {
|
|
return scrapeProfile(res.context, entity);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
module.exports = {
|
|
fetchLatest,
|
|
fetchProfile,
|
|
scrapeScene,
|
|
};
|