109 lines
3.5 KiB
JavaScript
109 lines
3.5 KiB
JavaScript
'use strict';
|
|
|
|
const logger = require('./logger')(__filename);
|
|
const knex = require('./knex');
|
|
const slugify = require('./utils/slugify');
|
|
const capitalize = require('./utils/capitalize');
|
|
|
|
function toBaseActors(actorsOrNames, release) {
|
|
return actorsOrNames.map((actorOrName) => {
|
|
const name = capitalize(actorOrName.name || actorOrName);
|
|
const slug = slugify(name);
|
|
|
|
const baseActor = {
|
|
name,
|
|
slug,
|
|
hasSingleName: name.split(/\s+/).length === 1,
|
|
network: release.site.network,
|
|
slugWithNetworkSlug: `${slug}-${release.site.network.slug}`,
|
|
};
|
|
|
|
if (actorOrName.name) {
|
|
return {
|
|
...actorOrName,
|
|
...baseActor,
|
|
};
|
|
}
|
|
|
|
return baseActor;
|
|
});
|
|
}
|
|
|
|
function curateActorEntry(baseActor) {
|
|
if (baseActor.hasSingleName) {
|
|
logger.warn(`Assigning single name actor '${baseActor.name}' to network '${baseActor.network.name}'`);
|
|
|
|
// attach network ID to allow separating actors with the same name
|
|
return {
|
|
name: baseActor.name,
|
|
slug: baseActor.slugWithNetworkSlug,
|
|
network_id: baseActor.network.id,
|
|
};
|
|
}
|
|
|
|
return {
|
|
name: baseActor.name,
|
|
slug: baseActor.slug,
|
|
};
|
|
}
|
|
|
|
function curateActorEntries(baseActors) {
|
|
return baseActors.map(baseActor => curateActorEntry(baseActor));
|
|
}
|
|
|
|
async function getOrCreateActors(baseActors) {
|
|
const existingActors = await knex('actors')
|
|
.select('id', 'name', 'slug', 'network_id')
|
|
.whereIn('slug', baseActors.map(baseActor => baseActor.slug))
|
|
.whereNull('network_id')
|
|
.orWhereIn(['slug', 'network_id'], baseActors.map(baseActor => [baseActor.slugWithNetworkSlug, baseActor.network.id]));
|
|
|
|
const existingActorSlugs = new Set(existingActors.map(actor => actor.slug));
|
|
const uniqueBaseActors = baseActors.filter(baseActor => !existingActorSlugs.has(baseActor.slug) && !existingActorSlugs.has(baseActor.slugWithNetworkSlug));
|
|
|
|
const curatedActorEntries = curateActorEntries(uniqueBaseActors);
|
|
const newActors = await knex('actors').insert(curatedActorEntries, ['id', 'name', 'slug', 'network_id']);
|
|
|
|
if (Array.isArray(newActors)) {
|
|
return newActors.concat(existingActors);
|
|
}
|
|
|
|
return existingActors;
|
|
}
|
|
|
|
async function associateActors(releases) {
|
|
const baseActorsByReleaseId = releases.reduce((acc, release) => {
|
|
if (release.actors) {
|
|
acc[release.id] = toBaseActors(release.actors, release);
|
|
}
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
const baseActors = Object.values(baseActorsByReleaseId).flat();
|
|
|
|
if (baseActors.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const baseActorsBySlug = baseActors.reduce((acc, baseActor) => ({ ...acc, [baseActor.slug]: baseActor }), {});
|
|
const uniqueBaseActors = Object.values(baseActorsBySlug);
|
|
|
|
const actors = await getOrCreateActors(uniqueBaseActors);
|
|
const actorIdsBySlug = actors.reduce((acc, actor) => ({ ...acc, [actor.slug]: actor.id }), {});
|
|
|
|
const releaseActorAssociations = Object.entries(baseActorsByReleaseId)
|
|
.map(([releaseId, releaseActors]) => releaseActors
|
|
.map(releaseActor => ({
|
|
release_id: releaseId,
|
|
actor_id: actorIdsBySlug[releaseActor.slug] || actorIdsBySlug[releaseActor.slugWithNetworkSlug],
|
|
})))
|
|
.flat();
|
|
|
|
await knex.raw(`${knex('releases_actors').insert(releaseActorAssociations).toString()} ON CONFLICT DO NOTHING;`);
|
|
}
|
|
|
|
module.exports = {
|
|
associateActors,
|
|
};
|