'use strict'; const qu = require('../utils/qu'); const slugify = require('../utils/slugify'); const { feetInchesToCm, lbsToKg } = require('../utils/convert'); function scrapeAll(scenes, entity) { return scenes.map(({ query }) => { const release = {}; release.url = query.url('.videoPic a'); release.entryId = query.q('.videoPic img', 'id').match(/set-target-(\d+)/)[1]; release.title = query.q('h3 a', true); release.description = query.q('.runtime + p', true); release.date = query.date('.date', 'MM-DD-YYYY'); release.duration = query.dur('.runtime'); release.actors = query.all('.tour_update_models a', true); release.poster = query.img('.videoPic img'); release.entity = entity; return release; }); } function scrapeScene({ query }) { const release = {}; release.entryId = query.q('.trailerLeft img', 'id').match(/set-target-(\d+)/)[1]; release.title = query.q('.infoHeader h1', true); release.description = query.q('.infoBox p', true); release.actors = query.all('.tour_update_models a', true); release.poster = query.img('.posterimg'); release.photos = query.imgs('.trailerSnaps img').slice(1); // first photo is poster in lower quality const trailer = query.q('script')?.textContent.match(/\/trailers\/.+\.mp4/)?.[0]; if (trailer) { release.trailer = { src: `https://pervcity.com${trailer}`, }; } return release; } function scrapeProfile({ query }) { const profile = {}; const bio = query.all('.moreInfo li').reduce((acc, el) => ({ ...acc, [slugify(query.q(el, 'span', true), '_')]: query.text(el), }), {}); profile.description = query.q('.aboutModel p', true); profile.dateOfBirth = qu.extractDate(bio.date_of_birth, ['MMMM D, YYYY', 'DD-MMM-YY']); profile.birthPlace = bio.birth_location; profile.ethnicity = bio.ethnicity; profile.height = feetInchesToCm(bio.height); profile.weight = lbsToKg(bio.weight); profile.eyes = bio.eye_color; profile.hairColor = bio.hair_color; profile.avatar = query.img('.starPic img'); profile.releases = scrapeAll(qu.initAll(query.all('.aboutScenes .videoBlock'))); return profile; } async function fetchLatest(channel, page = 1) { if (channel.parameters?.siteId) { const url = `https://pervcity.com/search.php?site[]=${channel.parameters.siteId}&page=${page}`; const res = await qu.getAll(url, '.videoBlock'); return res.ok ? scrapeAll(res.items, channel) : res.status; } return null; } async function fetchUpcoming(channel) { const url = 'https://pervcity.com'; const res = await qu.getAll(url, '.upcoming .videoBlock'); return res.ok ? scrapeAll(res.items, channel.parent) : res.status; } async function fetchScene(url, entity) { const res = await qu.get(url, '.trailerArea'); return res.ok ? scrapeScene(res.item, entity) : res.status; } async function fetchProfile({ name: actorName }) { const url = `https://pervcity.com/models/${slugify(actorName)}.html`; const res = await qu.get(url); if (res.ok) { return scrapeProfile(res.item); } const url2 = `https://pervcity.com/models/${slugify(actorName, '')}.html`; const res2 = await qu.get(url2); if (res2.ok) { return scrapeProfile(res2.item); } return res2.status; } module.exports = { fetchLatest, fetchScene, fetchProfile, fetchUpcoming, };