88 lines
2.3 KiB
JavaScript
88 lines
2.3 KiB
JavaScript
'use strict';
|
|
|
|
const knex = require('./knex');
|
|
const slugify = require('./utils/slugify');
|
|
const bulkInsert = require('./utils/bulk-insert');
|
|
|
|
async function matchReleaseTags(releases) {
|
|
const rawTags = releases
|
|
.map(release => release.tags).flat()
|
|
.filter(Boolean);
|
|
|
|
const casedTags = [...new Set(
|
|
rawTags
|
|
.concat(rawTags.map(tag => tag.toLowerCase()))
|
|
.concat(rawTags.map(tag => tag.toUpperCase())),
|
|
)];
|
|
|
|
const tagEntries = await knex('tags')
|
|
.select('tags.id', 'tags.name', 'tags.alias_for')
|
|
.whereIn('tags.name', casedTags);
|
|
|
|
const tagIdsBySlug = tagEntries
|
|
.reduce((acc, tag) => ({
|
|
...acc,
|
|
[slugify(tag.name)]: tag.alias_for || tag.id,
|
|
}), {});
|
|
|
|
return tagIdsBySlug;
|
|
}
|
|
|
|
async function getEntityTags(releases) {
|
|
const entityIds = releases.map(release => release.entity?.id).filter(Boolean);
|
|
const entityTags = await knex('entities_tags').whereIn('entity_id', entityIds);
|
|
|
|
const entityTagIdsByEntityId = entityTags.reduce((acc, entityTag) => {
|
|
if (!acc[entityTag.entity_id]) {
|
|
acc[entityTag.entity_id] = [];
|
|
}
|
|
|
|
acc[entityTag.entity_id].push(entityTag.tag_id);
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
return entityTagIdsByEntityId;
|
|
}
|
|
|
|
function buildReleaseTagAssociations(releases, tagIdsBySlug, entityTagIdsByEntityId, type) {
|
|
const tagAssociations = releases
|
|
.map((release) => {
|
|
const entityTagIds = entityTagIdsByEntityId[release.entity?.id] || [];
|
|
const releaseTags = release.tags || [];
|
|
|
|
const releaseTagIds = releaseTags.every(tag => typeof tag === 'number')
|
|
? releaseTags // obsolete scraper returned pre-matched tags
|
|
: releaseTags.map(tag => tagIdsBySlug[slugify(tag)]);
|
|
|
|
const tags = [...new Set(
|
|
// filter duplicates and empties
|
|
releaseTagIds
|
|
.concat(entityTagIds)
|
|
.filter(Boolean),
|
|
)]
|
|
.map(tagId => ({
|
|
[`${type}_id`]: release.id,
|
|
tag_id: tagId,
|
|
}));
|
|
|
|
return tags;
|
|
})
|
|
.flat();
|
|
|
|
return tagAssociations;
|
|
}
|
|
|
|
async function associateReleaseTags(releases, type = 'release') {
|
|
const tagIdsBySlug = await matchReleaseTags(releases);
|
|
const EntityTagIdsByEntityId = await getEntityTags(releases);
|
|
|
|
const tagAssociations = buildReleaseTagAssociations(releases, tagIdsBySlug, EntityTagIdsByEntityId, type);
|
|
|
|
await bulkInsert(`${type}s_tags`, tagAssociations, false);
|
|
}
|
|
|
|
module.exports = {
|
|
associateReleaseTags,
|
|
};
|