forked from DebaucheryLibrarian/traxxx
210 lines
6.0 KiB
JavaScript
Executable File
210 lines
6.0 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
const unprint = require('unprint');
|
|
const { decode } = require('html-entities');
|
|
|
|
const slugify = require('../utils/slugify');
|
|
const { feetInchesToCm, femaleFeetUsToEu } = require('../utils/convert');
|
|
|
|
function scrapeScene(data, channel, parameters) {
|
|
const release = {};
|
|
|
|
release.entryId = data.cms_set_id;
|
|
release.url = `${parameters.scene || channel.url}/video/${data.cms_set_id}`;
|
|
|
|
release.title = data.name;
|
|
release.description = data.description;
|
|
|
|
release.date = unprint.extractDate(data.added_nice, 'YYYY-MM-DD');
|
|
release.duration = Number(data.lengths.total);
|
|
|
|
release.actors = data.data_types.find((dataType) => dataType.data_type === 'Models' || dataType.data_type === 'Talent')?.data_values.map((actor) => ({
|
|
name: actor.name,
|
|
url: `${channel.url}/model/${actor.cms_data_value_id}?models=${encodeURI(actor.name)}`, // slug does not work unless it's also the ID
|
|
}));
|
|
|
|
release.directors = data.data_types.find((dataType) => dataType.data_type === 'Videographers')?.data_values.map((director) => ({
|
|
name: director.name,
|
|
// url: `${channel.url}/model/${director.slug}?models=${director.name}`,
|
|
}));
|
|
|
|
release.tags = data.data_types
|
|
.filter((dataType) => dataType.data_type === 'Tags' || dataType.data_type === 'Category')
|
|
.flatMap((tags) => tags.data_values.map((tag) => tag.name));
|
|
|
|
const poster = data.preview_formatted.thumb;
|
|
const teaser = data.preview_formatted.clip?.[0];
|
|
const trailer = data.preview_formatted.trailer?.formats?.[0]?.content?.[0];
|
|
|
|
if (poster) {
|
|
release.poster = Object.keys(poster)
|
|
.filter((key) => poster[key].length > 0)
|
|
.toSorted((keyA, keyB) => keyB.split('-')[0] - keyA.split('-')[0])
|
|
.map((key) => unprint.prefixUrl(`${poster[key][0].fileuri}?${poster[key][0].signature}`, parameters.cdn));
|
|
}
|
|
|
|
release.caps = data.content
|
|
?.filter((item) => item.content_type === 'image' && item.content?.[0])
|
|
.map((item) => [
|
|
item.content[0],
|
|
...(item.thumb
|
|
? Object.keys(item.thumb).toSorted((keyA, keyB) => keyB.split('-')[0] - keyA.split('-')[0]).map((key) => item.thumb[key][0]).filter(Boolean)
|
|
: []),
|
|
])
|
|
.map((sources) => sources.map((source) => ({
|
|
src: unprint.prefixUrl(`${source.fileuri}?${source.signature}`, parameters.cdn),
|
|
expectType: {
|
|
'application/octet-stream': 'image/jpeg',
|
|
},
|
|
})));
|
|
|
|
if (teaser && teaser.fileuri !== trailer?.fileuri) {
|
|
release.teaser = unprint.prefixUrl(`${teaser.fileuri}?${teaser.signature}`, parameters.cdn);
|
|
}
|
|
|
|
if (trailer) {
|
|
release.trailer = unprint.prefixUrl(`${trailer.fileuri}?${trailer.signature}`, parameters.cdn);
|
|
}
|
|
|
|
release.channel = slugify(data.data_types.find((dataType) => dataType.data_type === 'Series')?.data_values[0]?.name, '');
|
|
|
|
return release;
|
|
}
|
|
|
|
async function fetchLatest(channel, page = 1, { parameters }) {
|
|
const query = new URLSearchParams({
|
|
cms_area_id: parameters.areaId,
|
|
cms_block_id: parameters.blockId,
|
|
count: 100,
|
|
start: (page - 1) * 100,
|
|
orderby: 'published_desc',
|
|
content_type: 'video',
|
|
// unsure what this does
|
|
status: 'enabled',
|
|
cms_set_ids: undefined,
|
|
data_types: 1,
|
|
content_count: 1,
|
|
data_type_search: parameters.seriesId && JSON.stringify({ 7: parameters.seriesId.toString() }), // doesn't seem relevant
|
|
}).toString();
|
|
|
|
const url = `https://azianistudios.com/tour_api.php/content/sets?${query}`;
|
|
|
|
const res = await unprint.get(url, {
|
|
headers: {
|
|
Referer: channel.url,
|
|
'x-nats-cms-area-id': parameters.areaId,
|
|
},
|
|
});
|
|
|
|
if (res.ok && res.data.success) {
|
|
return res.data.sets.map((data) => scrapeScene(data, channel, parameters));
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
async function fetchScene(url, entity, _baseRelease, { parameters }) {
|
|
const entryId = new URL(url).pathname.match(/\/video\/(\w+)/)[1];
|
|
|
|
const query = new URLSearchParams({
|
|
cms_set_ids: entryId,
|
|
cms_area_id: parameters.areaId,
|
|
cms_block_id: parameters.blockId,
|
|
content: 1,
|
|
orderby: 'published_desc',
|
|
content_type: 'video',
|
|
// unsure what this does
|
|
data_types: 1,
|
|
content_count: 1,
|
|
}).toString();
|
|
|
|
const apiUrl = `https://azianistudios.com/tour_api.php/content/sets?${query}`;
|
|
|
|
const res = await unprint.get(apiUrl, {
|
|
headers: {
|
|
Referer: entity.url,
|
|
'x-nats-cms-area-id': parameters.areaId,
|
|
},
|
|
});
|
|
|
|
if (res.ok && res.data.success) {
|
|
return scrapeScene(res.data.sets[0], entity, parameters);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
function scrapeProfile(data, entity, parameters) {
|
|
const profile = {};
|
|
|
|
const bio = Object.fromEntries(Object.values(data.data_detail_values).map((detail) => [
|
|
slugify(detail.name, '_'),
|
|
decode(detail.value || detail.content_formatted || detail.content),
|
|
]));
|
|
|
|
profile.url = `${entity.url}/model/${data.cms_data_value_id}`;
|
|
profile.entryId = data.cms_data_value_id;
|
|
|
|
profile.description = data.description;
|
|
|
|
profile.gender = bio.gender?.toLowerCase();
|
|
profile.age = bio.age;
|
|
profile.dateOfBirth = unprint.extractDate(`${bio.born} 0`, 'MMMM Do YYYY', { match: /\w+ \d+\w{2} \d{1,4}/ });
|
|
|
|
profile.measurements = bio.measurements;
|
|
profile.height = feetInchesToCm(bio.height);
|
|
profile.foot = femaleFeetUsToEu(bio.foot_size);
|
|
|
|
profile.hairColor = bio.hair_color;
|
|
profile.eyeColor = bio.eye_color;
|
|
|
|
const avatar = bio.thumbnail?.image[0];
|
|
|
|
if (avatar) {
|
|
profile.avatar = {
|
|
src: `${parameters.cdn}${avatar.fileuri}?${avatar.signature}`,
|
|
expectType: {
|
|
'application/octet-stream': 'image/jpeg',
|
|
},
|
|
};
|
|
}
|
|
|
|
return profile;
|
|
}
|
|
|
|
async function fetchProfile({ url }, { entity, parameters }) {
|
|
if (!url) {
|
|
// no easy search option
|
|
return null;
|
|
}
|
|
|
|
const actorId = new URL(url).pathname.match(/model\/(\d+)/)[1];
|
|
|
|
const query = new URLSearchParams({
|
|
cms_data_value_ids: actorId,
|
|
cms_block_id: entity.parameters.modelBlockId,
|
|
cms_data_type_id: 4,
|
|
}).toString();
|
|
|
|
const apiUrl = `https://azianistudios.com/tour_api.php/content/data-values?${query}`;
|
|
|
|
const res = await unprint.get(apiUrl, {
|
|
headers: {
|
|
Referer: entity.url,
|
|
'x-nats-cms-area-id': entity.parameters.areaId,
|
|
},
|
|
});
|
|
|
|
if (res.ok && res.data.success) {
|
|
return scrapeProfile(res.data.data_values[0], entity, parameters);
|
|
}
|
|
|
|
return res.status;
|
|
}
|
|
|
|
module.exports = {
|
|
fetchLatest,
|
|
fetchProfile,
|
|
fetchScene,
|
|
};
|