From f1caa77e4bdac500254bf8ab14420dcb6948a399 Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Thu, 5 Mar 2026 02:00:43 +0100 Subject: [PATCH] Added scene tags table to manticore scenes tool. --- src/tools/manticore-scenes.js | 97 +++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/src/tools/manticore-scenes.js b/src/tools/manticore-scenes.js index 0fa2b5ff..981c01e0 100644 --- a/src/tools/manticore-scenes.js +++ b/src/tools/manticore-scenes.js @@ -41,7 +41,7 @@ async function fetchScenes() { studios.name as studio_name, grandparents.id as parent_network_id, COALESCE(JSON_AGG(DISTINCT (actors.id, actors.name)) FILTER (WHERE actors.id IS NOT NULL), '[]') as actors, - COALESCE(JSON_AGG(DISTINCT (tags.id, tags.name, tags.priority, tags_aliases.name)) FILTER (WHERE tags.id IS NOT NULL), '[]') as tags, + COALESCE(JSON_AGG(DISTINCT (tags.id, tags.name, tags.priority, tags_aliases.name, local_tags.actor_id)) FILTER (WHERE tags.id IS NOT NULL), '[]') as tags, COALESCE(JSON_AGG(DISTINCT (movies.id, movies.title)) FILTER (WHERE movies.id IS NOT NULL), '[]') as movies, COALESCE(JSON_AGG(DISTINCT (series.id, series.title)) FILTER (WHERE series.id IS NOT NULL), '[]') as series, COALESCE(JSON_AGG(DISTINCT (releases_fingerprints.hash)) FILTER (WHERE releases_fingerprints.hash IS NOT NULL), '[]') as fingerprints, @@ -136,6 +136,14 @@ async function init() { dupe_index int )`); + await utilsApi.sql('drop table if exists scenes_tags'); + await utilsApi.sql(`create table scenes_tags ( + id int, + scene_id int, + tag_id int, + actor_id int + )`); + console.log('Recreated scenes table'); console.log('Fetching scenes from primary database'); @@ -143,49 +151,62 @@ async function init() { console.log('Fetched scenes from primary database'); - const docs = scenes.map((scene) => { + const docs = scenes.flatMap((scene) => { const flatActors = scene.actors.flatMap((actor) => actor.f2.match(/[\w']+/g)); // match word characters to filter out brackets etc. const flatTags = scene.tags.filter((tag) => tag.f3 > 6).flatMap((tag) => (tag.f4 ? `${tag.f2} ${tag.f4}` : tag.f2).match(/[\w']+/g)); // only make top tags searchable to minimize cluttered results const filteredTitle = filterTitle(scene.title, [...flatActors, ...flatTags]); - return { - replace: { - index: 'scenes', - id: scene.id, - doc: { - title: scene.title || undefined, - title_filtered: filteredTitle || undefined, - date: scene.date ? Math.round(scene.date.getTime() / 1000) : undefined, - created_at: Math.round(scene.created_at.getTime() / 1000), - effective_date: Math.round((scene.date || scene.created_at).getTime() / 1000), - is_showcased: scene.showcased, - entry_id: scene.entry_id || undefined, - shoot_id: scene.shoot_id || undefined, - channel_id: scene.channel_id, - channel_slug: scene.channel_slug, - channel_name: [].concat(scene.channel_name, scene.channel_aliases).join(' '), - network_id: scene.network_id || undefined, - network_slug: scene.network_slug || undefined, - network_name: [].concat(scene.network_name, scene.network_aliases).join(' ') || undefined, - studio_id: scene.studio_id || undefined, - studio_slug: scene.studio_slug || undefined, - studio_name: scene.studio_name || undefined, - entity_ids: [scene.channel_id, scene.network_id, scene.parent_network_id, scene.studio_id].filter(Boolean), // manticore does not support OR, this allows IN - actor_ids: scene.actors.map((actor) => actor.f1), - actors: scene.actors.map((actor) => actor.f2).join(), - tag_ids: scene.tags.map((tag) => tag.f1), - tags: flatTags.join(' '), - movie_ids: scene.movies.map((movie) => movie.f1), - movies: scene.movies.map((movie) => movie.f2).join(' '), - serie_ids: scene.series.map((serie) => serie.f1), - series: scene.series.map((serie) => serie.f2).join(' '), - fingerprints: scene.fingerprints.join(' '), - meta: scene.date ? format(scene.date, 'y yy M MM MMM MMMM d dd') : undefined, - stashed: scene.stashed || 0, - dupe_index: scene.dupe_index || 0, + return [ + { + replace: { + index: 'scenes', + id: scene.id, + doc: { + title: scene.title || undefined, + title_filtered: filteredTitle || undefined, + date: scene.date ? Math.round(scene.date.getTime() / 1000) : undefined, + created_at: Math.round(scene.created_at.getTime() / 1000), + effective_date: Math.round((scene.date || scene.created_at).getTime() / 1000), + is_showcased: scene.showcased, + entry_id: scene.entry_id || undefined, + shoot_id: scene.shoot_id || undefined, + channel_id: scene.channel_id, + channel_slug: scene.channel_slug, + channel_name: [].concat(scene.channel_name, scene.channel_aliases).join(' '), + network_id: scene.network_id || undefined, + network_slug: scene.network_slug || undefined, + network_name: [].concat(scene.network_name, scene.network_aliases).join(' ') || undefined, + studio_id: scene.studio_id || undefined, + studio_slug: scene.studio_slug || undefined, + studio_name: scene.studio_name || undefined, + entity_ids: [scene.channel_id, scene.network_id, scene.parent_network_id, scene.studio_id].filter(Boolean), // manticore does not support OR, this allows IN + actor_ids: scene.actors.map((actor) => actor.f1), + actors: scene.actors.map((actor) => actor.f2).join(), + tag_ids: scene.tags.map((tag) => tag.f1), + tags: flatTags.join(' '), + movie_ids: scene.movies.map((movie) => movie.f1), + movies: scene.movies.map((movie) => movie.f2).join(' '), + serie_ids: scene.series.map((serie) => serie.f1), + series: scene.series.map((serie) => serie.f2).join(' '), + fingerprints: scene.fingerprints.join(' '), + meta: scene.date ? format(scene.date, 'y yy M MM MMM MMMM d dd') : undefined, + stashed: scene.stashed || 0, + dupe_index: scene.dupe_index || 0, + }, }, }, - }; + ...scene.tags.map((tag) => ({ + replace: { + index: 'scenes_tags', + // id: scene.id, + doc: { + scene_id: scene.id, + tag_id: tag.f1, + actor_id: tag.f5, + }, + }, + })), + ]; }); // const accData = chunk(docs, 10000).reduce(async (chain, docsChunk, index, array) => {