Compare commits
17 Commits
62dcaba875
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 244dc4fff6 | |||
| 4b39f787c9 | |||
| fb92b9c973 | |||
| 181358db7d | |||
| 3790567d44 | |||
| b3af993236 | |||
| 7ae2bb7635 | |||
| a75f0662ad | |||
| ffd68d5037 | |||
| adf9e2334c | |||
| 4125811017 | |||
| 4e8356b072 | |||
| bad116cdc0 | |||
| 9eac6871a4 | |||
| 3b694689f3 | |||
| 1604ddaa78 | |||
| 16181923b6 |
@@ -82,6 +82,13 @@
|
|||||||
:src="`/logos/${actor.entity.slug}/favicon_dark.png`"
|
:src="`/logos/${actor.entity.slug}/favicon_dark.png`"
|
||||||
class="favicon"
|
class="favicon"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="actor.alias && actor.alias.name !== actor.name"
|
||||||
|
v-tooltip="`Credited as '${actor.alias.name}'`"
|
||||||
|
icon="at-sign"
|
||||||
|
class="alias"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -258,4 +265,11 @@ const favorited = ref(props.actor.stashes.some((actorStash) => actorStash.id ===
|
|||||||
height: .75rem;
|
height: .75rem;
|
||||||
margin-left: .25rem;
|
margin-left: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alias {
|
||||||
|
height: 100%;
|
||||||
|
fill: var(--glass-weak-20);
|
||||||
|
padding: 0 .25rem;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -19,10 +19,16 @@
|
|||||||
>{{ avatar.sharpness.toFixed(2) }}</span>
|
>{{ avatar.sharpness.toFixed(2) }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
:title="`Added ${format(avatar.createdAt, 'yyyy-MM-dd')}, may not reflect photo age`"
|
||||||
|
class="avatar-date"
|
||||||
|
>{{ format(avatar.createdAt, '\'\'yy-MM') }}</span>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
:href="getPath(avatar)"
|
:href="getPath(avatar)"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="avatar-zoom"
|
class="avatar-zoom"
|
||||||
|
@click.stop
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon="search"
|
icon="search"
|
||||||
@@ -32,6 +38,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { format } from 'date-fns';
|
||||||
import getPath from '#/src/get-path.js';
|
import getPath from '#/src/get-path.js';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
@@ -89,7 +96,8 @@ defineProps({
|
|||||||
}
|
}
|
||||||
|
|
||||||
.avatar-meta,
|
.avatar-meta,
|
||||||
.avatar-credit {
|
.avatar-credit,
|
||||||
|
.avatar-date {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@@ -112,4 +120,10 @@ defineProps({
|
|||||||
bottom: .75rem;
|
bottom: .75rem;
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.avatar-date {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "traxxx-web",
|
"name": "traxxx-web",
|
||||||
"version": "0.50.13",
|
"version": "0.50.21",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "0.50.13",
|
"version": "0.50.21",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@brillout/json-serializer": "^0.5.8",
|
"@brillout/json-serializer": "^0.5.8",
|
||||||
"@dicebear/collection": "^7.0.5",
|
"@dicebear/collection": "^7.0.5",
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
"overrides": {
|
"overrides": {
|
||||||
"vite": "$vite"
|
"vite": "$vite"
|
||||||
},
|
},
|
||||||
"version": "0.50.13",
|
"version": "0.50.21",
|
||||||
"imports": {
|
"imports": {
|
||||||
"#/*": "./*.js"
|
"#/*": "./*.js"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -466,18 +466,18 @@ const fields = computed(() => [
|
|||||||
type: 'augmentation',
|
type: 'augmentation',
|
||||||
note: 'Provide explicit evidence, such as social media posts, visible scarring, or before/after. Avoid "it\'s obvious".',
|
note: 'Provide explicit evidence, such as social media posts, visible scarring, or before/after. Avoid "it\'s obvious".',
|
||||||
value: {
|
value: {
|
||||||
naturalBoobs: actor.value?.naturalBoobs || null,
|
naturalBoobs: actor.value?.naturalBoobs ?? null,
|
||||||
boobsVolume: actor.value?.boobsVolume || null,
|
boobsVolume: actor.value?.boobsVolume || null,
|
||||||
boobsImplant: actor.value?.boobsImplant || null,
|
boobsImplant: actor.value?.boobsImplant || null,
|
||||||
boobsPlacement: actor.value?.boobsPlacement || null,
|
boobsPlacement: actor.value?.boobsPlacement || null,
|
||||||
boobsIncision: actor.value?.boobsIncision || null,
|
boobsIncision: actor.value?.boobsIncision || null,
|
||||||
boobsSurgeon: actor.value?.boobsSurgeon || null,
|
boobsSurgeon: actor.value?.boobsSurgeon || null,
|
||||||
naturalButt: actor.value?.naturalButt || null,
|
naturalButt: actor.value?.naturalButt ?? null,
|
||||||
buttVolume: actor.value?.buttVolume || null,
|
buttVolume: actor.value?.buttVolume || null,
|
||||||
buttImplant: actor.value?.buttImplant || null,
|
buttImplant: actor.value?.buttImplant || null,
|
||||||
naturalLips: actor.value?.naturalLips || null,
|
naturalLips: actor.value?.naturalLips ?? null,
|
||||||
lipsVolume: actor.value?.lipsVolume || null,
|
lipsVolume: actor.value?.lipsVolume || null,
|
||||||
naturalLabia: actor.value?.naturalLabia || null,
|
naturalLabia: actor.value?.naturalLabia ?? null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,13 @@
|
|||||||
:key="`actor-${actor.id}`"
|
:key="`actor-${actor.id}`"
|
||||||
class="actor"
|
class="actor"
|
||||||
>
|
>
|
||||||
<td class="actor-id ellipsis">{{ actor.id }}</td>
|
<td class="actor-id ellipsis">
|
||||||
|
<a
|
||||||
|
:href="`/actor/${actor.id}/${actor.slug}`"
|
||||||
|
target="_blank"
|
||||||
|
class="nolink"
|
||||||
|
>{{ actor.id }}</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td
|
<td
|
||||||
v-tooltip="actor.entity?.name || 'Global'"
|
v-tooltip="actor.entity?.name || 'Global'"
|
||||||
|
|||||||
@@ -62,11 +62,22 @@ const keyMap = {
|
|||||||
const socialsOrder = ['onlyfans', 'fansly', 'twitter', 'instagram', 'loyalfans', 'manyvids', 'pornhub', 'linktree', null];
|
const socialsOrder = ['onlyfans', 'fansly', 'twitter', 'instagram', 'loyalfans', 'manyvids', 'pornhub', 'linktree', null];
|
||||||
|
|
||||||
export function curateActor(actor, context = {}) {
|
export function curateActor(actor, context = {}) {
|
||||||
|
if (!actor) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: actor.id,
|
id: actor.id,
|
||||||
slug: actor.slug,
|
slug: actor.slug,
|
||||||
name: actor.name,
|
name: actor.name,
|
||||||
aliases: actor.aliases || [],
|
aliases: actor.aliases || [], // used for profile pages
|
||||||
|
alias: actor.alias
|
||||||
|
? {
|
||||||
|
id: actor.alias.id,
|
||||||
|
slug: actor.alias.slug,
|
||||||
|
name: actor.alias.name,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
gender: actor.gender,
|
gender: actor.gender,
|
||||||
age: actor.age,
|
age: actor.age,
|
||||||
ethnicity: actor.ethnicity,
|
ethnicity: actor.ethnicity,
|
||||||
@@ -234,7 +245,7 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) {
|
|||||||
knex.raw('COALESCE(residence_countries.alias, residence_countries.name) as residence_country_name'),
|
knex.raw('COALESCE(residence_countries.alias, residence_countries.name) as residence_country_name'),
|
||||||
knex.raw('row_to_json(entities) as entity'),
|
knex.raw('row_to_json(entities) as entity'),
|
||||||
knex.raw('row_to_json(sfw_media) as sfw_avatar'),
|
knex.raw('row_to_json(sfw_media) as sfw_avatar'),
|
||||||
knex.raw('json_agg(aliases) as aliases'),
|
knex.raw('json_agg(aliases) filter (where aliases.id is not null) as aliases'),
|
||||||
)
|
)
|
||||||
.leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id')
|
.leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id')
|
||||||
.leftJoin('actors as aliases', 'aliases.alias_for', 'actors.id')
|
.leftJoin('actors as aliases', 'aliases.alias_for', 'actors.id')
|
||||||
@@ -598,8 +609,11 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
|
|||||||
|
|
||||||
const trx = await knex.transaction();
|
const trx = await knex.transaction();
|
||||||
|
|
||||||
let mergedProfiles;
|
let mergedProfiles = [];
|
||||||
let mergedScenes;
|
let mergedSceneActors = [];
|
||||||
|
let existingSceneActors = [];
|
||||||
|
let duplicateSourceActors = [];
|
||||||
|
let mergedActorStashes = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [existingProfiles] = await Promise.all([
|
const [existingProfiles] = await Promise.all([
|
||||||
@@ -613,19 +627,42 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
|
|||||||
trx('actors_avatars')
|
trx('actors_avatars')
|
||||||
.update('actor_id', targetActorId)
|
.update('actor_id', targetActorId)
|
||||||
.whereIn('actor_id', sourceActorIds),
|
.whereIn('actor_id', sourceActorIds),
|
||||||
trx('stashes_actors')
|
|
||||||
.update('actor_id', targetActorId)
|
|
||||||
.whereIn('actor_id', sourceActorIds)
|
|
||||||
.returning('id'),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// assign source actor profiles to target actor, unless a profile for that entity is already present
|
||||||
mergedProfiles = await trx('actors_profiles')
|
mergedProfiles = await trx('actors_profiles')
|
||||||
.update('actor_id', targetActorId)
|
.update('actor_id', targetActorId)
|
||||||
.whereIn('actor_id', sourceActorIds)
|
.whereIn('actor_id', sourceActorIds)
|
||||||
.whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id))
|
.whereNotIn('entity_id', existingProfiles.map((profile) => profile.entity_id))
|
||||||
.returning('id');
|
.returning('id');
|
||||||
|
|
||||||
mergedScenes = await trx('releases_actors')
|
// find releases that have more than one source actor assigned
|
||||||
|
duplicateSourceActors = await trx('releases_actors')
|
||||||
|
.select('release_id', knex.raw('array_agg(actor_id) as actor_ids'))
|
||||||
|
.whereIn('actor_id', sourceActorIds)
|
||||||
|
.groupBy('release_id')
|
||||||
|
.having(trx.raw('COUNT(DISTINCT actor_id) > 1'));
|
||||||
|
|
||||||
|
if (duplicateSourceActors.length > 0) {
|
||||||
|
// some scenes have multiple source actors assigned, which will cause a conflict after merging; we will need to remove all but one
|
||||||
|
await trx('releases_actors')
|
||||||
|
.whereIn('release_id', duplicateSourceActors.map((sceneActor) => sceneActor.release_id))
|
||||||
|
.whereIn('actor_id', duplicateSourceActors.flatMap((sceneActor) => sceneActor.actor_ids.slice(1)))
|
||||||
|
.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// find scenes that already have target actor assigned
|
||||||
|
existingSceneActors = await trx('releases_actors')
|
||||||
|
.where('actor_id', targetActorId);
|
||||||
|
|
||||||
|
// delete release source actors for scenes that already have the target actor assigned
|
||||||
|
await trx('releases_actors')
|
||||||
|
.whereIn('release_id', existingSceneActors.map((sceneActor) => sceneActor.release_id))
|
||||||
|
.whereIn('actor_id', sourceActorIds)
|
||||||
|
.delete();
|
||||||
|
|
||||||
|
// alias release source actors to target actors
|
||||||
|
mergedSceneActors = await trx('releases_actors')
|
||||||
.update({
|
.update({
|
||||||
actor_id: targetActorId,
|
actor_id: targetActorId,
|
||||||
alias_id: knex.raw('actor_id'),
|
alias_id: knex.raw('actor_id'),
|
||||||
@@ -633,6 +670,40 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
|
|||||||
.whereIn('actor_id', sourceActorIds)
|
.whereIn('actor_id', sourceActorIds)
|
||||||
.returning('release_id');
|
.returning('release_id');
|
||||||
|
|
||||||
|
const [targetActorStashes, sourceActorStashes] = await Promise.all([
|
||||||
|
trx('stashes_actors')
|
||||||
|
.where('actor_id', targetActorId),
|
||||||
|
trx('stashes_actors')
|
||||||
|
.whereIn('actor_id', sourceActorIds),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// remove source actors from stashes that already contain target actor
|
||||||
|
await trx('stashes_actors')
|
||||||
|
.whereIn('stash_id', targetActorStashes.map((stash) => stash.stash_id))
|
||||||
|
.whereIn('actor_id', sourceActorIds)
|
||||||
|
.delete();
|
||||||
|
|
||||||
|
// find stashes that have more than one source actor assigned
|
||||||
|
const duplicateStashActors = await trx('stashes_actors')
|
||||||
|
.select('stash_id', knex.raw('array_agg(actor_id order by created_at) as actor_ids'))
|
||||||
|
.whereIn('actor_id', sourceActorStashes.map((actorStash) => actorStash.actor_id))
|
||||||
|
.groupBy('stash_id')
|
||||||
|
.having(trx.raw('COUNT(DISTINCT actor_id) > 1'));
|
||||||
|
|
||||||
|
if (duplicateStashActors.length > 0) {
|
||||||
|
// some stashes have multiple source actors assigned, which will cause a conflict after merging; we will need to remove all but one
|
||||||
|
await trx('stashes_actors')
|
||||||
|
.whereIn('stash_id', duplicateStashActors.map((actorStash) => actorStash.stash_id))
|
||||||
|
.whereIn('actor_id', duplicateStashActors.flatMap((actorStash) => actorStash.actor_ids.slice(1)))
|
||||||
|
.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we update an existing entry instead of creating a new one, so the original stash date is preserved
|
||||||
|
mergedActorStashes = await trx('stashes_actors')
|
||||||
|
.update('actor_id', targetActorId)
|
||||||
|
.whereIn('actor_id', sourceActorIds)
|
||||||
|
.returning('stash_id');
|
||||||
|
|
||||||
await trx.commit();
|
await trx.commit();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await trx.rollback();
|
await trx.rollback();
|
||||||
@@ -649,14 +720,19 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
|
|||||||
}, { refreshView: false });
|
}, { refreshView: false });
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
syncScenes(mergedScenes.map((scene) => scene.release_id)),
|
syncScenes([
|
||||||
|
...mergedSceneActors.map((sceneActor) => sceneActor.release_id),
|
||||||
|
...existingSceneActors.map((sceneActor) => sceneActor.release_id),
|
||||||
|
...duplicateSourceActors.map((sceneActor) => sceneActor.release_id),
|
||||||
|
]),
|
||||||
syncActors([targetActorId, ...sourceActorIds]),
|
syncActors([targetActorId, ...sourceActorIds]),
|
||||||
syncStashes('actor', [targetActorId, ...sourceActorIds]),
|
syncStashes('actor', [targetActorId, ...sourceActorIds]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scenes: mergedScenes.length,
|
scenes: mergedSceneActors.length,
|
||||||
profiles: mergedProfiles.length,
|
profiles: mergedProfiles.length,
|
||||||
|
stashes: mergedActorStashes.length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import initServer from './web/server.js';
|
import initServer from './web/server.js';
|
||||||
import { initCaches } from './cache.js';
|
import { initCaches } from './cache.js';
|
||||||
|
import { initSyncCron } from './sync.js';
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
await initCaches();
|
await initCaches();
|
||||||
|
|
||||||
initServer();
|
initServer();
|
||||||
|
initSyncCron();
|
||||||
}
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|||||||
@@ -32,5 +32,6 @@ export function curateMedia(media, context = {}) {
|
|||||||
type: context.type || null,
|
type: context.type || null,
|
||||||
sfw: curateMedia(media.sfw_media),
|
sfw: curateMedia(media.sfw_media),
|
||||||
isRestricted: context.isRestricted,
|
isRestricted: context.isRestricted,
|
||||||
|
createdAt: media.created_at,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,16 +209,19 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
|||||||
'actors.*',
|
'actors.*',
|
||||||
knex.raw('row_to_json(avatars) as avatar'),
|
knex.raw('row_to_json(avatars) as avatar'),
|
||||||
knex.raw('row_to_json(sfw_media) as sfw_avatar'),
|
knex.raw('row_to_json(sfw_media) as sfw_avatar'),
|
||||||
|
knex.raw('row_to_json(aliases) as alias'),
|
||||||
|
knex.raw('case when aliases.id is not null then json_build_object(\'id\', aliases.id, \'name\', aliases.name, \'slug\', aliases.slug) end as alias'),
|
||||||
'countries.name as birth_country_name',
|
'countries.name as birth_country_name',
|
||||||
'countries.alias as birth_country_alias',
|
'countries.alias as birth_country_alias',
|
||||||
'releases_actors.release_id',
|
'releases_actors.release_id',
|
||||||
)
|
)
|
||||||
.leftJoin('actors', 'actors.id', 'releases_actors.actor_id')
|
.leftJoin('actors', 'actors.id', 'releases_actors.actor_id')
|
||||||
|
.leftJoin('actors as aliases', 'aliases.id', 'releases_actors.alias_id')
|
||||||
.leftJoin('media as avatars', 'avatars.id', 'actors.avatar_media_id')
|
.leftJoin('media as avatars', 'avatars.id', 'actors.avatar_media_id')
|
||||||
.leftJoin('media as sfw_media', 'sfw_media.id', 'avatars.sfw_media_id')
|
.leftJoin('media as sfw_media', 'sfw_media.id', 'avatars.sfw_media_id')
|
||||||
.leftJoin('countries', 'countries.alpha2', 'actors.birth_country_alpha2')
|
.leftJoin('countries', 'countries.alpha2', 'actors.birth_country_alpha2')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.groupBy('actors.id', 'releases_actors.release_id', 'avatars.id', 'countries.name', 'countries.alias', 'sfw_media.id'),
|
.groupBy('actors.id', 'aliases.id', 'releases_actors.release_id', 'avatars.id', 'countries.name', 'countries.alias', 'sfw_media.id'),
|
||||||
directors: knex('releases_directors')
|
directors: knex('releases_directors')
|
||||||
.whereIn('release_id', sceneIds)
|
.whereIn('release_id', sceneIds)
|
||||||
.leftJoin('actors as directors', 'directors.id', 'releases_directors.director_id'),
|
.leftJoin('actors as directors', 'directors.id', 'releases_directors.director_id'),
|
||||||
|
|||||||
26
src/sync.js
26
src/sync.js
@@ -114,6 +114,7 @@ export async function syncManticoreScenes(sceneIds) {
|
|||||||
studios.name as studio_name,
|
studios.name as studio_name,
|
||||||
grandparents.id as parent_network_id,
|
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 (actors.id, actors.name)) FILTER (WHERE actors.id IS NOT NULL), '[]') as actors,
|
||||||
|
COALESCE(JSON_AGG(DISTINCT (actors_aliases.id, actors_aliases.name)) FILTER (WHERE actors_aliases.id IS NOT NULL), '[]') as actors_aliases,
|
||||||
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)) 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 (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 (series.id, series.title)) FILTER (WHERE series.id IS NOT NULL), '[]') as series,
|
||||||
@@ -135,6 +136,7 @@ export async function syncManticoreScenes(sceneIds) {
|
|||||||
LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id
|
LEFT JOIN releases_tags AS local_tags ON local_tags.release_id = releases.id
|
||||||
LEFT JOIN actors ON local_actors.actor_id = actors.id
|
LEFT JOIN actors ON local_actors.actor_id = actors.id
|
||||||
LEFT JOIN actors AS directors ON local_directors.director_id = directors.id
|
LEFT JOIN actors AS directors ON local_directors.director_id = directors.id
|
||||||
|
LEFT JOIN actors AS actors_aliases ON actors_aliases.id = local_actors.alias_id
|
||||||
LEFT JOIN tags ON local_tags.tag_id = tags.id
|
LEFT JOIN tags ON local_tags.tag_id = tags.id
|
||||||
LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true
|
LEFT JOIN tags as tags_aliases ON local_tags.tag_id = tags_aliases.alias_for AND tags_aliases.secondary = true
|
||||||
LEFT JOIN movies_scenes ON movies_scenes.scene_id = releases.id
|
LEFT JOIN movies_scenes ON movies_scenes.scene_id = releases.id
|
||||||
@@ -185,6 +187,8 @@ export async function syncManticoreScenes(sceneIds) {
|
|||||||
const flatTags = scene.tags.filter((tag) => tag.f3 > 6).flatMap((tag) => [tag.f2].concat(tag.f4)).filter(Boolean); // only make top tags searchable to minimize cluttered results
|
const flatTags = scene.tags.filter((tag) => tag.f3 > 6).flatMap((tag) => [tag.f2].concat(tag.f4)).filter(Boolean); // only make top tags searchable to minimize cluttered results
|
||||||
const filteredTitle = filterTitle(scene.title, [...flatActors, ...flatTags]);
|
const filteredTitle = filterTitle(scene.title, [...flatActors, ...flatTags]);
|
||||||
|
|
||||||
|
// TODO: reconsider how direct vs indirect tags are stored and searched
|
||||||
|
|
||||||
return {
|
return {
|
||||||
replace: {
|
replace: {
|
||||||
index: 'scenes',
|
index: 'scenes',
|
||||||
@@ -207,8 +211,8 @@ export async function syncManticoreScenes(sceneIds) {
|
|||||||
studio_slug: scene.studio_slug || undefined,
|
studio_slug: scene.studio_slug || undefined,
|
||||||
studio_name: scene.studio_name || 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
|
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),
|
actor_ids: scene.actors.map((actor) => actor.f1), // don't include aliases in ID or they would show up in filters
|
||||||
actors: scene.actors.map((actor) => actor.f2).join(),
|
actors: Array.from(new Set([...scene.actors.map((actor) => actor.f2), ...scene.actors_aliases.map((actor) => actor.f2)])).join(),
|
||||||
tag_ids: scene.tags.map((tag) => tag.f1),
|
tag_ids: scene.tags.map((tag) => tag.f1),
|
||||||
tags: flatTags.join(' '), // only make top tags searchable to minimize cluttered results
|
tags: flatTags.join(' '), // only make top tags searchable to minimize cluttered results
|
||||||
movie_ids: scene.movies.map((movie) => movie.f1),
|
movie_ids: scene.movies.map((movie) => movie.f1),
|
||||||
@@ -470,11 +474,13 @@ export async function syncQueue() {
|
|||||||
logger[process.tasks > 0 ? 'info' : 'verbose'](`Processed ${tasks.length} sync items`);
|
logger[process.tasks > 0 ? 'info' : 'verbose'](`Processed ${tasks.length} sync items`);
|
||||||
}
|
}
|
||||||
|
|
||||||
CronJob.from({
|
export function initSyncCron() {
|
||||||
cronTime: config.sync.crontab,
|
CronJob.from({
|
||||||
async onTick() {
|
cronTime: config.sync.crontab,
|
||||||
syncQueue();
|
async onTick() {
|
||||||
},
|
syncQueue();
|
||||||
start: config.sync.enabled,
|
},
|
||||||
runOnInit: true,
|
start: config.sync.enabled,
|
||||||
});
|
runOnInit: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user