traxxx-web/utils/process-summary-template.js

101 lines
2.7 KiB
JavaScript
Raw Normal View History

import { format } from 'date-fns';
import { parse } from 'yaml';
import slugify from '#/utils/slugify.js';
2024-08-26 04:15:22 +00:00
import ellipsis from '#/utils/ellipsis.js';
const genderMap = {
f: 'female',
m: 'male',
t: 'transsexual',
o: 'other',
u: null,
};
const propProcessors = {
channel: (sceneInfo) => sceneInfo.channel?.name || sceneInfo.network?.name,
network: (sceneInfo) => sceneInfo.network?.name || sceneInfo.channel?.name,
actors: (sceneInfo, options) => {
const genders = (options.genders || 'fmtou').split('').map((genderKey) => genderMap[genderKey]);
return sceneInfo.actors
.filter((actor) => genders.includes(actor.gender))
.map((actor) => actor.name);
},
tags: (sceneInfo, options) => sceneInfo.tags
.filter((tag) => {
2024-08-26 04:15:22 +00:00
if (options.include && !options.include.includes(tag.slug)) {
return false;
}
2024-08-26 04:15:22 +00:00
if (options.exclude?.includes(tag.slug)) {
return false;
}
if (options.priority && tag.priority < options.priority) {
return false;
}
return true;
})
.map((tag) => tag.name),
movie: (sceneInfo) => sceneInfo.movies[0]?.title,
date: (sceneInfo, options) => format(sceneInfo.effectiveDate, options.format || 'yyyy-MM-dd'),
};
2024-08-26 04:15:22 +00:00
function curateValue(value, item) {
return [].concat(value) // account for both arrays (actors, tags) and strings (title, channel)
.slice(0, item.limit || Infinity)
.map((listValue) => (item.slugify ? slugify(listValue, item.slugify) : listValue))
.map((listValue) => ellipsis(listValue, item.slice || Infinity, item.ellipsis || ''))
.join(item.delimit || ', ');
}
function traverseTemplate(chain, release, {
delimit = ' ',
wrap = ['', ''],
} = {}) {
const results = chain.reduce((result, item) => {
2024-08-26 04:15:22 +00:00
const keys = typeof item === 'string' ? item : item.key;
if ((item.channels && !item.channels.includes(release.channel?.slug)) || item.notChannels?.includes(release.channel?.slug)) {
return result;
}
2024-08-26 04:15:22 +00:00
if ((item.networks && !item.networks.includes(release.network?.slug)) || item.notNetworks?.includes(release.network?.slug)) {
return result;
}
2024-08-26 04:15:22 +00:00
if (keys) {
const value = keys.split('|').reduce((acc, key) => acc
|| propProcessors[key]?.(release, typeof item === 'string' ? { key } : item)
|| release[key], null);
2024-08-26 04:15:22 +00:00
return result.concat(curateValue(value, item));
}
if (item.items) {
2024-08-26 04:15:22 +00:00
const group = traverseTemplate(item.items, release, {
delimit: item.delimit,
wrap: item.wrap,
});
2024-08-26 04:15:22 +00:00
return result.concat(curateValue(group, item));
}
2024-08-26 04:15:22 +00:00
return result;
}, []);
if (results.length > 0) {
2024-08-26 04:15:22 +00:00
return `${wrap[0] || ''}${results.filter(Boolean).join(delimit)}${wrap[1] || ''}`;
}
return '';
}
2024-08-26 04:15:22 +00:00
export default function processSummaryTemplate(template, release) {
const chain = parse(template);
return traverseTemplate(chain, release);
}