From 1f5bbb6ce55de9c096cdce3e9c511d6253b55e21 Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Tue, 7 Jul 2026 01:05:18 +0200 Subject: [PATCH] Redirecting aliased actors and tags. --- pages/actors/@actorId/+onBeforeRender.js | 4 ++++ pages/admin/actors/+Page.vue | 2 +- pages/tags/@tagId/+onBeforeRender.js | 9 +++++++-- src/actors.js | 4 +++- src/movies.js | 2 +- src/scenes.js | 4 ++-- src/tags.js | 3 +++ 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pages/actors/@actorId/+onBeforeRender.js b/pages/actors/@actorId/+onBeforeRender.js index 94227ed..0067c1e 100644 --- a/pages/actors/@actorId/+onBeforeRender.js +++ b/pages/actors/@actorId/+onBeforeRender.js @@ -47,6 +47,10 @@ export async function onBeforeRender(pageContext) { throw render(404, `Cannot find actor '${pageContext.routeParams.actorId}'.`); } + if (actor.alias && !Object.hasOwn(pageContext.urlParsed.search, 'inspect')) { + throw redirect(`/actor/${actor.alias.id}/${actor.alias.slug}`); + } + const [actorReleases, campaigns, countries] = await Promise.all([ fetchReleases(pageContext), getRandomCampaigns([ diff --git a/pages/admin/actors/+Page.vue b/pages/admin/actors/+Page.vue index 6ea27f6..57a0b5d 100644 --- a/pages/admin/actors/+Page.vue +++ b/pages/admin/actors/+Page.vue @@ -60,7 +60,7 @@ > {{ actor.id }} diff --git a/pages/tags/@tagId/+onBeforeRender.js b/pages/tags/@tagId/+onBeforeRender.js index 3cb2c24..578b512 100644 --- a/pages/tags/@tagId/+onBeforeRender.js +++ b/pages/tags/@tagId/+onBeforeRender.js @@ -1,3 +1,4 @@ +import { redirect } from 'vike/abort'; /* eslint-disable-line import/extensions */ import markdownIt from 'markdown-it'; import markdownItClass from '@toycode/markdown-it-class'; @@ -42,9 +43,13 @@ async function fetchReleases(pageContext) { export async function onBeforeRender(pageContext) { const tagSlug = pageContext.routeParams.tagSlug; + const [tag] = await fetchTagsById([tagSlug], {}, pageContext.user, { restriction: pageContext.restriction }); - const [[tag], tagReleases, campaigns] = await Promise.all([ - fetchTagsById([tagSlug], {}, pageContext.user, { restriction: pageContext.restriction }), + if (tag.aliasFor) { + throw redirect(`/tag/${tag.aliasFor}`); + } + + const [tagReleases, campaigns] = await Promise.all([ fetchReleases(pageContext), getRandomCampaigns([ { tagSlugs: [tagSlug], minRatio: 0.75, maxRatio: 1.25 }, diff --git a/src/actors.js b/src/actors.js index 824daf3..726fe35 100644 --- a/src/actors.js +++ b/src/actors.js @@ -254,10 +254,12 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) { knex.raw('row_to_json(sfw_media) as sfw_avatar'), // knex.raw('json_agg(aliases) filter (where aliases.id is not null) as aliases'), knex.raw('json_agg(row_to_json(aliases)::jsonb || jsonb_build_object(\'entity\', row_to_json(alias_entities))) filter (where aliases.id is not null) as aliases'), + knex.raw('row_to_json(aliased) as alias'), knex.raw('row_to_json(media_biometrics) as biometrics'), ) .leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id') .leftJoin('actors as aliases', 'aliases.alias_for', 'actors.id') + .leftJoin('actors as aliased', 'aliased.id', 'actors.alias_for') .leftJoin('entities as alias_entities', 'alias_entities.id', 'aliases.entity_id') .leftJoin('countries as birth_countries', 'birth_countries.alpha2', 'actors.birth_country_alpha2') .leftJoin('countries as residence_countries', 'residence_countries.alpha2', 'actors.residence_country_alpha2') @@ -265,7 +267,7 @@ export async function fetchActorsById(actorIds, options = {}, reqUser) { .leftJoin('media as sfw_media', 'sfw_media.id', 'avatars.sfw_media_id') .leftJoin('media_biometrics', 'media_biometrics.media_id', 'actors.avatar_media_id') .leftJoin('entities', 'entities.id', 'actors.entity_id') - .groupBy('actors.id', 'avatars.id', 'sfw_media.id', 'media_biometrics.id', 'entities.id', 'actors_meta.stashed', 'birth_countries.alpha2', 'residence_countries.alpha2'); + .groupBy('actors.id', 'aliased.id', 'avatars.id', 'sfw_media.id', 'media_biometrics.id', 'entities.id', 'actors_meta.stashed', 'birth_countries.alpha2', 'residence_countries.alpha2'); } }), knex('actors_profiles') diff --git a/src/movies.js b/src/movies.js index ecd6a58..92061ab 100644 --- a/src/movies.js +++ b/src/movies.js @@ -422,7 +422,7 @@ export async function fetchMovies(filters, rawOptions, reqUser, context) { const [aggActors, aggTags, aggChannels] = await Promise.all([ options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { shadllow: true, order: ['slug', 'asc'], append: actorCounts }, reqUser) : [], - options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [], + options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(tags.name)'), 'asc'], append: tagCounts }, reqUser, context) : [], options.aggregateChannels ? fetchEntitiesById(result.aggregations.channelIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }, reqUser, context) : [], ]); diff --git a/src/scenes.js b/src/scenes.js index 0eae6fb..4a6ed92 100644 --- a/src/scenes.js +++ b/src/scenes.js @@ -689,8 +689,8 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) { const [aggActors, aggTags, aggActorTags, aggChannels] = await Promise.all([ options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { shallow: true, order: ['slug', 'asc'], append: actorCounts }, reqUser) : [], - options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [], - options.aggregateTags ? fetchTagsById(result.aggregations.actorTagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [], + options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(tags.name)'), 'asc'], append: tagCounts }, reqUser, context) : [], + options.aggregateTags ? fetchTagsById(result.aggregations.actorTagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(tags.name)'), 'asc'], append: tagCounts }, reqUser, context) : [], options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }, reqUser, context) : [], ]); diff --git a/src/tags.js b/src/tags.js index 481acff..44b0e1a 100644 --- a/src/tags.js +++ b/src/tags.js @@ -16,6 +16,7 @@ function curateTag(tag, context = {}) { priority: tag.priority, poster: tag.poster && curateMedia(tag.poster), photos: tag.photos?.map((photo) => curateMedia(photo)) || [], + aliasFor: tag.alias_slug, alerts: { only: context?.alerts?.filter((alert) => alert.is_only).flatMap((alert) => alert.alert_ids) || [], multi: context?.alerts?.filter((alert) => !alert.is_only).flatMap((alert) => alert.alert_ids) || [], @@ -76,6 +77,8 @@ export async function fetchTags(options = {}, context = {}) { export async function fetchTagsById(tagIds, options = {}, reqUser, context = {}) { const [tags, posters, photos, alerts] = await Promise.all([ knex('tags') + .select('tags.*', 'aliases.slug as alias_slug') + .leftJoin('tags as aliases', 'aliases.id', 'tags.alias_for') .whereIn('tags.id', tagIds.filter((tagId) => typeof tagId === 'number')) .orWhereIn('tags.slug', tagIds.filter((tagId) => typeof tagId === 'string')) .modify((builder) => {