'use strict'; const unprint = require('unprint'); const slugify = require('../utils/slugify'); function scrapeAll(scenes) { return scenes.map(({ query }) => { const release = {}; release.url = query.url('.title') || query.url('.thumb a'); release.entryId = new URL(release.url).pathname.replaceAll('/', ''); release.title = query.content('.title') || query.attribute('.title', 'title') || query.attribute('.thumb a', 'title'); release.duration = query.duration('.time'); release.actors = query.all('.cast a').map((el) => ({ name: unprint.query.content(el), url: unprint.query.url(el, null), })); release.poster = query.img('.thumb img'); /* not accurate enough const [, year, month] = release.poster?.match(/uploads\/(\d{4})\/(\d{2})/) || []; if (year) { release.date = new Date(year, month - 1, 1); release.datePrecision = 'month'; } */ return release; }); } function scrapeScene({ query }, { url }) { const release = {}; release.entryId = new URL(url).pathname.replaceAll('/', ''); release.title = query.content('.topVideo .right .title'); release.description = query.content('.topVideo .right .descript'); release.date = query.date('.topVideo .right .row', 'DD/MM/YYYY', { match: /\d{2}\/\d{2}\/\d{4}/ }); release.duration = query.duration('.topVideo .right .row'); release.actors = query.all('.infosVideo .left a[href*="/modelos"]').map((el) => ({ name: unprint.query.attribute(el, '.img img', 'title') || unprint.query.content(el).trim(), url: unprint.query.url(el, null), avatar: unprint.query.img(el, '.img img'), })); release.poster = query.img('.topVideo .player img'); release.covers = query.imgs('#singleBackground img'); release.tags = query.contents('.infosVideo .left a[href*="/categoria"]'); release.studio = slugify(query.content('//strong[contains(text(), "Produtora")]/following-sibling::p'), ''); if (query.content('.infosVideo .left').includes('1080p')) { release.qualities = [1080]; } return release; } function scrapeProfile({ query }, url) { const profile = { url }; profile.avatar = query.img('.model .photo img'); profile.scenes = scrapeAll(unprint.initAll(query.all('.single .itemsingle'))); return profile; } async function fetchLatest(channel, page) { const res = await unprint.get(`${channel.url}/videos/page/${page}/?filter=ultimos`, { selectAll: '.single .itemsingle', timeout: 30000, }); if (res.ok) { return scrapeAll(res.context, channel); } return res.status; } async function fetchProfile(actor, { entity }) { const url = actor.url || `${entity.url}/modelos/${actor.slug}/`; const res = await unprint.get(url, { maxRedirects: 0, // will attempt to redirect invalid URL to relevant scene page }); if (res.ok) { return scrapeProfile(res.context, url); } return res.status; } module.exports = { fetchLatest, fetchProfile, scrapeScene: { scraper: scrapeScene, unprint: true, }, };