'use strict'; /* eslint-disable no-unused-vars */ const { get, ed } = require('../utils/q'); const { fetchApiLatest, fetchApiUpcoming, fetchScene, fetchApiProfile } = require('./gamma'); const http = require('../utils/http'); const slugify = require('../utils/slugify'); function scrapeLatestNative(scenes, site) { return scenes.map((scene) => { const release = {}; release.entryId = scene.id; release.url = `${site.url}${scene.url}`; release.title = scene.name; release.date = ed(scene.release_date, 'YYYY-MM-DD'); release.duration = parseInt(scene.runtime, 10) * 60; release.actors = scene.cast?.map((actor) => ({ name: actor.stagename, gender: actor.gender.toLowerCase(), avatar: actor.placard, })) || []; release.stars = Number(scene.rating); release.poster = scene.placard_800 || scene.placard; return release; }); } function scrapeSceneNative({ html, q, qa }, url, _site) { const release = { url }; release.entryId = new URL(url).pathname.split('/')[2]; // eslint-disable-line prefer-destructuring release.title = q('.scene-h2-heading', true); release.description = q('.indie-model-p', true); const dateString = qa('h5').find((el) => /Released/.test(el.textContent)).textContent; release.date = ed(dateString, 'MMM DD, YYYY', /\w+ \d{1,2}, \d{4}/); const duration = qa('h5').find((el) => /Runtime/.test(el.textContent)).textContent; const [hours, minutes] = duration.match(/\d+/g); if (minutes) release.duration = (hours * 3600) + (minutes * 60); else release.duration = hours * 60; // scene shorter that 1hr, hour match are minutes release.actors = qa('h4 a[href*="/stars"], h4 a[href*="/celebs"]', true); release.tags = qa('h5 a[href*="/categories"]', true); const [poster, trailer] = html.match(/https:\/\/content.vivid.com(.*)(.jpg|.mp4)/g); release.poster = poster; if (trailer) { release.trailer = { src: trailer, }; } const channel = q('h5 a[href*="/sites"]', true); if (channel) release.channel = channel.replace(/\.\w+/, ''); return release; } async function fetchLatestNative(site, page = 1) { if (site.parameters?.useGamma) { return fetchApiLatest(site, page); } const apiUrl = `${site.url}/videos/api/?limit=50&offset=${(page - 1) * 50}&sort=datedesc`; const res = await http.get(apiUrl, { decodeJSON: true, }); if (res.statusCode === 200 && res.body.code === 200) { return scrapeLatestNative(res.body.responseData, site); } return null; } async function fetchUpcomingNative(site) { if (site.parameters?.useGamma) { return fetchApiUpcoming(site); } return null; } async function fetchSceneNative(url, site, release) { if (site.parameters?.useGamma) { return fetchScene(url, site, release); } const res = await get(url); return res.ok ? scrapeSceneNative(res.item, url, site) : res.status; } async function fetchSceneWrapper(url, site, release) { const scene = await fetchScene(url, site, release); if (scene.date - new Date(site.parameters?.lastNative) <= 0) { // scene is probably still available on Vivid site, use search API to get URL and original date const searchUrl = `${site.url}/videos/api/?limit=10&sort=datedesc&search=${encodeURI(scene.title)}`; const searchRes = await http.get(searchUrl, { decodeJSON: true, }); if (searchRes.statusCode === 200 && searchRes.body.code === 200) { const sceneMatch = searchRes.body.responseData.find((item) => slugify(item.name) === slugify(scene.title)); if (sceneMatch) { return { ...scene, url: `${site.url}${sceneMatch.url}`, date: ed(sceneMatch.release_date, 'YYYY-MM-DD'), }; } } } return scene; } module.exports = { fetchLatest: fetchApiLatest, fetchProfile: fetchApiProfile, fetchUpcoming: fetchApiUpcoming, fetchScene: fetchSceneWrapper, };