Added Teste de Fudelidade.
| After Width: | Height: | Size: 5.6 KiB | 
| After Width: | Height: | Size: 5.6 KiB | 
| After Width: | Height: | Size: 5.6 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 3.5 KiB | 
| After Width: | Height: | Size: 3.5 KiB | 
| After Width: | Height: | Size: 12 KiB | 
| After Width: | Height: | Size: 12 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 4.1 KiB | 
| After Width: | Height: | Size: 6.1 KiB | 
| After Width: | Height: | Size: 6.1 KiB | 
|  | @ -0,0 +1,109 @@ | |||
| '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'))); | ||||
| 
 | ||||
| 	console.log(profile); | ||||
| 	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}/models/${actor.slug}/`; | ||||
| 	const res = await unprint.get(url); | ||||
| 
 | ||||
| 	if (res.ok) { | ||||
| 		return scrapeProfile(res.context, url); | ||||
| 	} | ||||
| 
 | ||||
| 	return res.status; | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| 	fetchLatest, | ||||
| 	fetchProfile, | ||||
| 	scrapeScene: { | ||||
| 		scraper: scrapeScene, | ||||
| 		unprint: true, | ||||
| 	}, | ||||
| }; | ||||