'use strict'; const unprint = require('unprint'); // paths are relative, read raw attributes instead of resolved URLs const raw = { forceGetAttribute: true }; function extractActors(actorString) { return actorString ?.replace(/.*:|\(.*\)|\d+(-|\s)year(-|\s)old|nurses?|tangled/ig, '') // remove Patient:, (date) and other nonsense .split(/\band\b|\bvs\b|\/|,|&/ig) .map((actor) => actor.trim()) .filter((actor) => !!actor && !/\banal\b|\bschool\b|\bgamer\b|\breturn\b|\bfor\b|\bare\b|\bpart\b|realdoll|bimbo|p\d+/ig.test(actor)) || []; } function matchActors(actorString, models) { if (!actorString) { return []; } return models.filter((model) => new RegExp(model.name, 'i').test(actorString)); } function scrapeLatest(scenes, site, models) { return scenes.map(({ query }) => { const release = {}; const pathname = query.attribute('a.itemimg', 'href', raw).slice(1); [release.entryId] = pathname.split('/').slice(-1); release.url = `${site.url}${pathname}`; release.title = query.attribute('.itemimg img', 'alt') || query.content('h4 a'); release.description = query.content('.mas_longdescription'); release.date = query.date('.movie_info2', 'MM/DD/YY', { match: /\d{2}\/\d{2}\/\d{2}/ }); const actorString = query.content('.mas_description'); const actors = matchActors(actorString, models); if (actors.length > 0) release.actors = actors; else release.actors = extractActors(actorString); const posterPath = query.attribute('.itemimg img', 'src', raw); release.poster = `${site.url}/${posterPath}`; return release; }); } function scrapeScene({ html, query }, url, site, include, models) { const release = { url }; [release.entryId] = url.split('/').slice(-1); release.title = query.content('.mas_title'); release.description = query.content('.mas_longdescription'); release.date = query.date('.mas_description', 'MMMM DD, YYYY', { match: /\w+ \d{1,2}, \d{4}/ }); if (models) { const actorString = query.content('.mas_description').replace(/\w+ \d{1,2}, \d{4}/, ''); const actors = matchActors(actorString, models); if (actors.length > 0) release.actors = actors; else release.actors = extractActors(actorString); } release.tags = query.contents('.tags a'); release.photos = query.attributes('.stills img', 'src', raw).map((photoPath) => `${site.url}/${photoPath}`); const posterIndex = 'splash:'; const poster = html.slice(html.indexOf('faceimages/', posterIndex), html.indexOf('.jpg', posterIndex) + 4); if (poster) release.poster = `${site.url}/${poster}`; const trailerIndex = html.indexOf('video/mp4'); const trailer = html.slice(html.indexOf('/content', trailerIndex), html.indexOf('.mp4', trailerIndex) + 4); if (trailer) release.trailer = { src: `${site.url}${trailer}` }; return release; } function extractModels({ element }, site) { const models = unprint.initAll(element, '.item'); return models.map(({ query }) => { const actor = { gender: 'female' }; const avatar = query.element('.itemimg img'); actor.avatar = `${site.url}/${avatar.src}`; actor.name = avatar.alt .split(':').slice(-1)[0] .replace(/xtreme girl|nurse/ig, '') .trim(); const actorPath = query.attribute('.itemimg', 'href', raw); actor.url = `${site.url}${actorPath.slice(1)}`; return actor; }); } async function fetchModels(site, page = 1, accModels = []) { const url = `${site.url}/?models/${page}`; const res = await unprint.get(url); if (res.ok) { const models = extractModels(res.context, site); const nextPage = res.context.query.contents('.pagenumbers') .map((pageX) => Number(pageX)) .filter(Boolean) // remove << and >> .includes(page + 1); if (nextPage) { return fetchModels(site, page + 1, accModels.concat(models)); } return accModels.concat(models, { name: 'Dr. Gray' }); } return []; } async function fetchLatest(site, page = 1, include, { beforeFetchLatest }) { const url = `${site.url}/show.php?a=${site.parameters.a}_${page}`; const res = await unprint.get(url, { selectAll: '.item' }); return res.ok ? scrapeLatest(res.context, site, beforeFetchLatest) : res.status; } async function fetchScene(url, site, release, include, beforeFetchLatest) { const models = beforeFetchLatest || await fetchModels(site); const res = await unprint.get(url); return res.ok ? scrapeScene(res.context, url, site, include, models) : res.status; } module.exports = { fetchLatest, fetchScene, beforeFetchLatest: fetchModels, };