Files
traxxx/src/scrapers/assylum.js
T

140 lines
4.4 KiB
JavaScript
Executable File

'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,
};