'use strict'; /* eslint-disable newline-per-chained-call */ const bhttp = require('bhttp'); const cheerio = require('cheerio'); const moment = require('moment'); function scrapeLatest(html, site) { const $ = cheerio.load(html, { normalizeWhitespace: true }); const sceneElements = $('.echThumb').toArray(); return sceneElements.map((element) => { const sceneLinkElement = $(element).find('.thmb_lnk'); const title = sceneLinkElement.attr('title'); const url = `https://bangbros.com${sceneLinkElement.attr('href')}`; const shootId = sceneLinkElement.attr('id') && sceneLinkElement.attr('id').split('-')[1]; const entryId = url.split('/')[3].slice(5); const date = moment.utc($(element).find('.thmb_mr_2 span.faTxt').text(), 'MMM D, YYYY').toDate(); const actors = $(element).find('.cast-wrapper a.cast').map((actorIndex, actorElement) => $(actorElement).text().trim()).toArray(); const photoElement = $(element).find('.rollover-image'); const poster = `https:${photoElement.attr('data-original')}`; const photosUrl = photoElement.attr('data-rollover-url'); const photosMaxIndex = photoElement.attr('data-rollover-max-index'); const photos = Array.from({ length: photosMaxIndex }, (val, index) => `https:${photosUrl}big${index + 1}.jpg`); const duration = moment.duration(`0:${$(element).find('.thmb_pic b.tTm').text()}`).asSeconds(); return { url, entryId, shootId, title, actors, date, duration, poster, photos, rating: null, site, }; }); } async function scrapeScene(html, url, site) { const $ = cheerio.load(html, { normalizeWhitespace: true }); const sceneElement = $('.playerSection'); const shootId = sceneElement.find('.vdoCast:contains("Release")').text().replace('Release: ', ''); const entryId = url.split('/')[3].slice(5); const title = sceneElement.find('.ps-vdoHdd h1').text(); const description = sceneElement.find('.vdoDesc').text().trim(); const [siteName, ...actors] = sceneElement.find('.vdoCast a').map((actorIndex, actorElement) => $(actorElement).text()).toArray(); const siteSlug = siteName.replace(/[\s']+/g, '').toLowerCase(); const poster = `https:${$('img#player-overlay-image').attr('src')}`; const trailer = `https:${$('source[type="video/mp4"]').attr('src')}`; const firstPhotoUrl = `https:${$('img[data-slider-index="1"]').attr('src')}`; // all scenes seem to have 12 album photos available, not always included on the page const photos = Array.from({ length: 12 }, (val, index) => firstPhotoUrl.replace(/big\d+/, `big${index + 1}`)); const tags = $('.vdoTags a').map((tagIndex, tagElement) => $(tagElement).text()).toArray(); const stars = Number(sceneElement.find('.bVdPl_it_like .bVdPl_txt').text().replace('% like', '')) / 20; return { url, shootId, entryId, title, description, actors, tags, poster, photos, trailer: { src: trailer, }, rating: { stars, }, site, channel: siteSlug === 'bangcasting' ? 'bangbroscasting' : siteSlug, }; } async function fetchLatest(site, page = 1) { const res = await bhttp.get(`${site.url}/${page}`); return scrapeLatest(res.body.toString(), site); } async function fetchScene(url, site) { const { origin } = new URL(url); const res = await bhttp.get(url); if (origin !== 'https://bangbros.com') { throw new Error('Cannot fetch from this URL. Please find the scene on https://bangbros.com and try again.'); } return scrapeScene(res.body.toString(), url, site); } module.exports = { fetchLatest, fetchScene, };