'use strict'; const unprint = require('unprint'); function scrapeAll(scenes, _channel) { return scenes.map(({ query }) => { const release = {}; release.url = query.url('.item-thumb a, .item-info h4 a'); release.entryId = new URL(release.url).pathname.match(/\/trailers\/(.*)\.html/)[1].toLowerCase(); release.title = query.content('.item-info h4 a, .item-info a[title]'); release.date = query.date('.date', 'YYYY-MM-DD'); release.duration = query.duration('.time'); release.photoCount = query.number('.time'); const photoCount = query.number('.item-thumb img.mainThumb', { attribute: 'cnt' }); if (photoCount) { [release.poster, ...release.photos] = Array.from({ length: photoCount }, (value, index) => [ query.img('.item-thumb img.mainThumb', { attribute: `src${index}_2x` }), query.img('.item-thumb img.mainThumb', { attribute: `src${index}_3x` }), // 3x is too big and usually inflated, try 2x first query.img('.item-thumb img.mainThumb', { attribute: `src${index}_1x` }), ]); } return release; }); } function scrapeScene({ query, html }, { url, entity, baseRelease }) { const release = {}; release.entryId = new URL(url).pathname.match(/\/trailers\/(.*)\.html/)[1].toLowerCase(); release.title = query.content('.videoDetails h3'); release.description = query.content('.videoDetails p'); release.date = query.date('.videoInfo', 'MMMM D, YYYY'); release.duration = query.duration('.videoInfo'); release.actors = query.all('.update_models a').map((actorEl) => ({ name: unprint.query.content(actorEl), url: unprint.query.url(actorEl, null), })); release.tags = query.contents('.featuring a[href*="categories/"]'); release.photoCount = query.number('.videoInfo', { match: /(\d+) photos/i, matchIndex: 1 }); release.trailer = unprint.prefixUrl(html.match(/src="(\/trailers\/.*\.mp4)"/)?.[1], entity.url); const posterUrl = unprint.prefixUrl(html.match(/poster="(\/content\/.*\.jpg)"/)?.[1], entity.url); const posterFallbacks = [ posterUrl.replace('-1x', '-2x'), posterUrl.replace('-1x', '-3x'), posterUrl, ]; // scene page poster does not appear on update page if (baseRelease?.poster) { release.photos = [posterFallbacks, ...(baseRelease.photos || [])]; } else { release.poster = posterFallbacks; } return release; } function scrapeProfile({ query }) { const profile = {}; profile.description = query.content('.profile-about') || null; profile.avatar = [ query.img('.profile-pic img', { attribute: 'src0_1x' }), // too big, not desirable unless 1x fails query.img('.profile-pic img', { attribute: 'src0_2x' }), query.img('.profile-pic img', { attribute: 'src0_3x' }), ]; return profile; } async function fetchLatest(channel, page = 1) { const url = `${channel.url}/categories/movies/${page}/latest/`; const res = await unprint.get(url, { selectAll: '.items .item-video' }); if (res.ok) { return scrapeAll(res.context, channel); } return res.status; } async function fetchProfile(actor, entity) { const url = actor.url || `${entity.url}/models/${actor.slug}.html`; const res = await unprint.get(url); if (res.ok) { return scrapeProfile(res.context); } return res.status; } module.exports = { fetchLatest, fetchProfile, scrapeScene, };