121 lines
3.0 KiB
JavaScript
Executable File
121 lines
3.0 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
const unprint = require('unprint');
|
|
|
|
const slugify = require('../utils/slugify');
|
|
|
|
function scrapeProfile({ query }) {
|
|
const profile = {};
|
|
|
|
const bio = Object.fromEntries(query.all('.profile-meta-list li').map((bioEl) => [
|
|
slugify(unprint.query.content(bioEl, 'span:first-child'), '_'),
|
|
unprint.query.content(bioEl, 'span:last-child'),
|
|
]).filter(([_key, value]) => value?.toLowerCase() !== 'unknown'));
|
|
|
|
profile.description = query.content('#description div[data-test="biography"]');
|
|
|
|
profile.dateOfBirth = unprint.extractDate(bio.date_of_birth, 'MMMM D, YYYY');
|
|
profile.age = unprint.extractNumber(bio.age);
|
|
|
|
profile.birthPlace = bio.place_of_birth;
|
|
profile.nationality = bio.nationality;
|
|
profile.ethnicity = bio.ethnicity;
|
|
|
|
profile.eyes = bio.eye_color;
|
|
profile.hairColor = bio.hair_color;
|
|
|
|
[profile.bust, profile.cup] = bio.bra?.match(/(\d+)([a-z]+)/i)?.slice(1) || [];
|
|
|
|
// TODO: differentiate between bust and bra band size
|
|
if (!profile.bust) {
|
|
profile.bust = bio.bust;
|
|
}
|
|
|
|
if (!profile.cup) {
|
|
profile.cup = bio.cup;
|
|
}
|
|
|
|
profile.bust = unprint.extractNumber(bio.bra);
|
|
profile.cup = bio.cup;
|
|
profile.waist = unprint.extractNumber(bio.waist);
|
|
profile.hip = unprint.extractNumber(bio.hip);
|
|
|
|
profile.height = unprint.extractNumber(bio.height);
|
|
profile.weight = unprint.extractNumber(bio.weight);
|
|
|
|
profile.foot = unprint.extractNumber(bio.shoe_size);
|
|
|
|
profile.socials = query.urls('.profile-meta-item .teaser__link');
|
|
|
|
if (/yes/i.test(bio.tattoos)) profile.hasTattoos = true;
|
|
if (/no/i.test(bio.tattoos)) profile.hasTattoos = false;
|
|
|
|
profile.tattoos = bio.tattoo_locations;
|
|
|
|
if (/yes/i.test(bio.piercings)) profile.hasPiercings = true;
|
|
if (/no/i.test(bio.piercings)) profile.hasPiercings = false;
|
|
|
|
profile.piercings = bio.piercing_locations;
|
|
|
|
if (/natural/i.test(bio.boobs)) profile.naturalBoobs = true;
|
|
if (/fake/i.test(bio.boobs)) profile.naturalBoobs = false;
|
|
|
|
if (/natural/i.test(bio.butt)) profile.naturalButt = true;
|
|
if (/fake/i.test(bio.butt)) profile.naturalButt = false;
|
|
|
|
const avatar = query.img('.dashboard-image-container img');
|
|
|
|
if (!avatar?.match(/placeholder/i)) {
|
|
profile.avatar = avatar;
|
|
}
|
|
|
|
return profile;
|
|
}
|
|
|
|
async function getActorUrl(actor) {
|
|
if (actor.url) {
|
|
return actor.url;
|
|
}
|
|
|
|
const res = await unprint.post('https://www.freeones.com/xhr/search', {
|
|
performerTypes: ['babe', 'male', 'trans'],
|
|
query: actor.name,
|
|
recipe: 'subject',
|
|
size: 12,
|
|
});
|
|
|
|
if (res.ok) {
|
|
const model = res.data.hits?.find((result) => slugify(result.name) === actor.slug);
|
|
|
|
if (model?.url) {
|
|
return `https://www.freeones.com${model.url}/bio`;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
async function fetchProfile(actor) {
|
|
const res = await unprint.get(`https://freeones.com/${actor.slug}/bio`);
|
|
|
|
if (res.ok) {
|
|
return scrapeProfile(res.context);
|
|
}
|
|
|
|
const actorUrl = await getActorUrl(actor);
|
|
|
|
if (actorUrl) {
|
|
const actorRes = await unprint.get(actorUrl);
|
|
|
|
if (actorRes.ok) {
|
|
return scrapeProfile(actorRes.context);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
module.exports = {
|
|
fetchProfile,
|
|
};
|