Added studios to filters and scene page.
This commit is contained in:
parent
c3362e614e
commit
60c7e2a876
|
@ -63,7 +63,8 @@
|
||||||
--text: #222;
|
--text: #222;
|
||||||
--text-light: #fff;
|
--text-light: #fff;
|
||||||
|
|
||||||
--link: #48f;
|
/* --link: #48f; */
|
||||||
|
--link: var(--primary);
|
||||||
|
|
||||||
--male: #0af;
|
--male: #0af;
|
||||||
--female: #f0a;
|
--female: #f0a;
|
||||||
|
|
|
@ -131,14 +131,14 @@ const entities = computed(() => {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel.parent && !acc[channel.parent.id] && channel.type === 'channel') {
|
if (!acc[channel.id] && channel.parent && !acc[channel.parent.id] && (channel.type === 'channel' || channel.type === 'studio')) {
|
||||||
acc[channel.parent.id] = {
|
acc[channel.parent.id] = {
|
||||||
...channel.parent,
|
...channel.parent,
|
||||||
children: [],
|
children: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel.parent && channel.type === 'channel') {
|
if (!acc[channel.id] && channel.parent && (channel.type === 'channel' || channel.type === 'studio')) {
|
||||||
acc[channel.parent.id].children.push(channel);
|
acc[channel.parent.id].children.push(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ import { parse } from 'path-to-regexp';
|
||||||
import navigate from '#/src/navigate.js';
|
import navigate from '#/src/navigate.js';
|
||||||
import { get } from '#/src/api.js';
|
import { get } from '#/src/api.js';
|
||||||
import events from '#/src/events.js';
|
import events from '#/src/events.js';
|
||||||
|
import entityPrefixes from '#/src/entities-prefixes.js';
|
||||||
import { getActorIdentifier, parseActorIdentifier } from '#/src/query.js';
|
import { getActorIdentifier, parseActorIdentifier } from '#/src/query.js';
|
||||||
|
|
||||||
import Filters from '#/components/filters/filters.vue';
|
import Filters from '#/components/filters/filters.vue';
|
||||||
|
@ -211,6 +212,8 @@ const aggActors = ref(pageProps.aggActors || []);
|
||||||
const aggTags = ref(pageProps.aggTags || []);
|
const aggTags = ref(pageProps.aggTags || []);
|
||||||
const aggChannels = ref(pageProps.aggChannels || []);
|
const aggChannels = ref(pageProps.aggChannels || []);
|
||||||
|
|
||||||
|
console.log(aggChannels.value);
|
||||||
|
|
||||||
const currentPage = ref(Number(routeParams.page));
|
const currentPage = ref(Number(routeParams.page));
|
||||||
const scope = ref(routeParams.scope || props.defaultScope);
|
const scope = ref(routeParams.scope || props.defaultScope);
|
||||||
const total = ref(Number(pageProps.sceneTotal || pageProps.total));
|
const total = ref(Number(pageProps.sceneTotal || pageProps.total));
|
||||||
|
@ -277,7 +280,8 @@ async function search(options = {}) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const entity = filters.value.entity || pageEntity;
|
const entity = filters.value.entity || pageEntity;
|
||||||
const entitySlug = entity?.type === 'network' ? `_${entity.slug}` : entity?.slug;
|
// const entitySlug = entity?.type === 'network' ? `_${entity.slug}` : entity?.slug;
|
||||||
|
const entitySlug = `${entityPrefixes[entity.type]}${entity.slug}`;
|
||||||
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
|
@ -286,7 +290,8 @@ async function search(options = {}) {
|
||||||
years: filters.value.years.join(',') || undefined,
|
years: filters.value.years.join(',') || undefined,
|
||||||
actors: filters.value.actors.map((filterActor) => getActorIdentifier(filterActor)).join(',') || undefined, // don't include page actor ID in query, already a parameter
|
actors: filters.value.actors.map((filterActor) => getActorIdentifier(filterActor)).join(',') || undefined, // don't include page actor ID in query, already a parameter
|
||||||
tags: filters.value.tags.join(',') || undefined,
|
tags: filters.value.tags.join(',') || undefined,
|
||||||
e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || undefined),
|
// e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || undefined),
|
||||||
|
e: filters.value.entity ? `${entityPrefixes[filters.value.entity.type]}${filters.value.entity.slug}` : undefined,
|
||||||
}, { redirect: false });
|
}, { redirect: false });
|
||||||
|
|
||||||
const res = await get('/scenes', {
|
const res = await get('/scenes', {
|
||||||
|
|
|
@ -109,6 +109,16 @@
|
||||||
class="row tags nolist"
|
class="row tags nolist"
|
||||||
:title="scene.tags.map((tag) => tag.name).join(', ')"
|
:title="scene.tags.map((tag) => tag.name).join(', ')"
|
||||||
>
|
>
|
||||||
|
<li
|
||||||
|
v-if="scene.shootId"
|
||||||
|
class="tag shoot"
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
:href="scene.studio ? `/studio/${scene.studio.slug}` : null"
|
||||||
|
class="nolink"
|
||||||
|
>{{ scene.shootId }}</Link>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
v-for="tag in scene.tags"
|
v-for="tag in scene.tags"
|
||||||
:key="`tag-${scene.id}-${tag.id}`"
|
:key="`tag-${scene.id}-${tag.id}`"
|
||||||
|
@ -304,4 +314,10 @@ const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.id ===
|
||||||
color: var(--glass-strong-10);
|
color: var(--glass-strong-10);
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shoot {
|
||||||
|
color: var(--primary);
|
||||||
|
font-size: .75rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -76,6 +76,19 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="children-container">
|
<div class="children-container">
|
||||||
|
<div
|
||||||
|
v-show="expanded"
|
||||||
|
class="expand-container expand-top"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="expand"
|
||||||
|
@click="expanded = !expanded"
|
||||||
|
>
|
||||||
|
<span class="expand-text">Collapse channels</span>
|
||||||
|
<Icon icon="arrow-up3" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
v-if="entity.children.length > 0"
|
v-if="entity.children.length > 0"
|
||||||
ref="children"
|
ref="children"
|
||||||
|
@ -252,7 +265,7 @@ const entityUrl = (() => {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
border: none;
|
border: none;
|
||||||
background: var(--grey-dark-50);
|
background: var(--grey-dark-40);
|
||||||
color: var(--highlight-strong-30);
|
color: var(--highlight-strong-30);
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -274,6 +287,17 @@ const entityUrl = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.expand-top {
|
||||||
|
height: 0;
|
||||||
|
top: 3.5rem;
|
||||||
|
bottom: auto;
|
||||||
|
position: sticky;
|
||||||
|
|
||||||
|
.expand {
|
||||||
|
height: 2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.domains-bar {
|
.domains-bar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { render } from 'vike/abort'; /* eslint-disable-line import/extensions */
|
import { render } from 'vike/abort'; /* eslint-disable-line import/extensions */
|
||||||
|
|
||||||
import { fetchEntitiesById } from '#/src/entities.js';
|
import { fetchEntitiesById } from '#/src/entities.js';
|
||||||
|
import entityPrefixes from '#/src/entities-prefixes.js';
|
||||||
import { fetchScenes } from '#/src/scenes.js';
|
import { fetchScenes } from '#/src/scenes.js';
|
||||||
import { fetchMovies } from '#/src/movies.js';
|
import { fetchMovies } from '#/src/movies.js';
|
||||||
import { curateScenesQuery } from '#/src/web/scenes.js';
|
import { curateScenesQuery } from '#/src/web/scenes.js';
|
||||||
|
@ -35,7 +36,8 @@ async function fetchReleases(pageContext, entityId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function onBeforeRender(pageContext) {
|
export async function onBeforeRender(pageContext) {
|
||||||
const entityId = await redis.hGet('traxxx:entities:id_by_slug', pageContext.routeParams.entityType === 'network' ? `_${pageContext.routeParams.entitySlug}` : pageContext.routeParams.entitySlug);
|
// const entityId = await redis.hGet('traxxx:entities:id_by_slug', pageContext.routeParams.entityType === 'network' ? `_${pageContext.routeParams.entitySlug}` : pageContext.routeParams.entitySlug);
|
||||||
|
const entityId = await redis.hGet('traxxx:entities:id_by_slug', `${entityPrefixes[pageContext.routeParams.entityType]}${pageContext.routeParams.entitySlug}`);
|
||||||
|
|
||||||
if (!entityId) {
|
if (!entityId) {
|
||||||
throw render(404, `Cannot find ${pageContext.routeParams.entityType} '${pageContext.routeParams.entitySlug}'.`);
|
throw render(404, `Cannot find ${pageContext.routeParams.entityType} '${pageContext.routeParams.entitySlug}'.`);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { match } from 'path-to-regexp';
|
import { match } from 'path-to-regexp';
|
||||||
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
||||||
|
|
||||||
const path = '/:entityType(channel|network)/:entitySlug/:domain(scenes|movies|series)?/:scope?/:page?';
|
const path = '/:entityType(channel|network|studio)/:entitySlug/:domain(scenes|movies|series)?/:scope?/:page?';
|
||||||
const urlMatch = match(path, { decode: decodeURIComponent });
|
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||||
|
|
||||||
export default (pageContext) => {
|
export default (pageContext) => {
|
||||||
|
|
|
@ -205,6 +205,18 @@
|
||||||
{{ scene.shootId }}
|
{{ scene.shootId }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="scene.studio"
|
||||||
|
class="detail"
|
||||||
|
>
|
||||||
|
<h3 class="heading">Studio</h3>
|
||||||
|
|
||||||
|
<a
|
||||||
|
:href="`/studio/${scene.studio.slug}`"
|
||||||
|
class="link"
|
||||||
|
>{{ scene.studio.name }}</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="scene.qualities.length > 0"
|
v-if="scene.qualities.length > 0"
|
||||||
class="detail"
|
class="detail"
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
export default {
|
||||||
|
channel: '',
|
||||||
|
network: '_',
|
||||||
|
studio: '*',
|
||||||
|
info: '@',
|
||||||
|
};
|
|
@ -1,16 +1,10 @@
|
||||||
import knex from './knex.js';
|
import knex from './knex.js';
|
||||||
import redis from './redis.js';
|
import redis from './redis.js';
|
||||||
import initLogger from './logger.js';
|
import initLogger from './logger.js';
|
||||||
|
import entityPrefixes from './entities-prefixes.js';
|
||||||
|
|
||||||
const logger = initLogger();
|
const logger = initLogger();
|
||||||
|
|
||||||
const entityPrefixes = {
|
|
||||||
channel: '',
|
|
||||||
network: '_',
|
|
||||||
studio: '*',
|
|
||||||
info: '@',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function curateEntity(entity, context) {
|
export function curateEntity(entity, context) {
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -79,6 +79,13 @@ function curateScene(rawScene, assets) {
|
||||||
type: assets.channel.network_type,
|
type: assets.channel.network_type,
|
||||||
hasLogo: assets.channel.network_has_logo,
|
hasLogo: assets.channel.network_has_logo,
|
||||||
} : null,
|
} : null,
|
||||||
|
studio: assets.studio ? {
|
||||||
|
id: assets.studio.id,
|
||||||
|
slug: assets.studio.slug,
|
||||||
|
name: assets.studio.name,
|
||||||
|
type: assets.studio.type,
|
||||||
|
hasLogo: assets.studio.has_logo,
|
||||||
|
} : null,
|
||||||
affiliate: assets.channel.affiliate ? {
|
affiliate: assets.channel.affiliate ? {
|
||||||
id: assets.channel.affiliate.id,
|
id: assets.channel.affiliate.id,
|
||||||
url: assets.channel.affiliate.url,
|
url: assets.channel.affiliate.url,
|
||||||
|
@ -132,6 +139,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
const {
|
const {
|
||||||
scenes,
|
scenes,
|
||||||
channels,
|
channels,
|
||||||
|
studios,
|
||||||
actors,
|
actors,
|
||||||
directors,
|
directors,
|
||||||
tags,
|
tags,
|
||||||
|
@ -161,6 +169,10 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
.leftJoin('entities as networks', 'networks.id', 'channels.parent_id')
|
.leftJoin('entities as networks', 'networks.id', 'channels.parent_id')
|
||||||
.leftJoin('affiliates', knex.raw('affiliates.entity_id in (channels.id, networks.id)'))
|
.leftJoin('affiliates', knex.raw('affiliates.entity_id in (channels.id, networks.id)'))
|
||||||
.groupBy('channels.id', 'networks.id', 'affiliates.id'),
|
.groupBy('channels.id', 'networks.id', 'affiliates.id'),
|
||||||
|
studios: knex('releases')
|
||||||
|
.whereIn('releases.id', sceneIds)
|
||||||
|
.leftJoin('entities as studios', 'studios.id', 'releases.studio_id'),
|
||||||
|
// .leftJoin('entities as networks', 'networks.id', 'studios.parent_id'),
|
||||||
actors: knex('releases_actors')
|
actors: knex('releases_actors')
|
||||||
.select(
|
.select(
|
||||||
'actors.*',
|
'actors.*',
|
||||||
|
@ -265,6 +277,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const sceneChannel = channels.find((entity) => entity.id === scene.entity_id);
|
const sceneChannel = channels.find((entity) => entity.id === scene.entity_id);
|
||||||
|
const sceneStudio = studios.find((entity) => entity.id === scene.studio_id);
|
||||||
const sceneActors = actors.filter((actor) => actor.release_id === sceneId);
|
const sceneActors = actors.filter((actor) => actor.release_id === sceneId);
|
||||||
const sceneDirectors = directors.filter((director) => director.release_id === sceneId);
|
const sceneDirectors = directors.filter((director) => director.release_id === sceneId);
|
||||||
const sceneTags = tags.filter((tag) => tag.release_id === sceneId);
|
const sceneTags = tags.filter((tag) => tag.release_id === sceneId);
|
||||||
|
@ -280,6 +293,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) {
|
||||||
|
|
||||||
return curateScene(scene, {
|
return curateScene(scene, {
|
||||||
channel: sceneChannel,
|
channel: sceneChannel,
|
||||||
|
studio: sceneStudio,
|
||||||
actors: sceneActors,
|
actors: sceneActors,
|
||||||
directors: sceneDirectors,
|
directors: sceneDirectors,
|
||||||
tags: sceneTags,
|
tags: sceneTags,
|
||||||
|
@ -339,7 +353,8 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||||
:yearsFacet:
|
:yearsFacet:
|
||||||
:actorsFacet:
|
:actorsFacet:
|
||||||
:tagsFacet:
|
:tagsFacet:
|
||||||
:channelsFacet:;
|
:channelsFacet:
|
||||||
|
:studiosFacet:;
|
||||||
show meta;
|
show meta;
|
||||||
`, {
|
`, {
|
||||||
query: knexManticore(filters.stashId ? 'scenes_stashed' : 'scenes')
|
query: knexManticore(filters.stashId ? 'scenes_stashed' : 'scenes')
|
||||||
|
@ -470,6 +485,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||||
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids order by count(*) desc limit ?', [aggSize]) : null,
|
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids order by count(*) desc limit ?', [aggSize]) : null,
|
||||||
tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids order by count(*) desc limit ?', [aggSize]) : null,
|
tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids order by count(*) desc limit ?', [aggSize]) : null,
|
||||||
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id order by count(*) desc limit ?', [aggSize]) : null,
|
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id order by count(*) desc limit ?', [aggSize]) : null,
|
||||||
|
studiosFacet: options.aggregateChannels ? knex.raw('facet scenes.studio_id order by count(*) desc limit ?', [aggSize]) : null,
|
||||||
maxMatches: config.database.manticore.maxMatches,
|
maxMatches: config.database.manticore.maxMatches,
|
||||||
maxQueryTime: config.database.manticore.maxQueryTime,
|
maxQueryTime: config.database.manticore.maxQueryTime,
|
||||||
}).toString();
|
}).toString();
|
||||||
|
@ -507,6 +523,13 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||||
?.data.map((row) => ({ key: row.channel_id || row['scenes.channel_id'], doc_count: row['count(*)'] }))
|
?.data.map((row) => ({ key: row.channel_id || row['scenes.channel_id'], doc_count: row['count(*)'] }))
|
||||||
|| [];
|
|| [];
|
||||||
|
|
||||||
|
const studioIds = results
|
||||||
|
.find((result) => (result.columns[0].studio_id || result.columns[0]['scenes.studio_id']) && result.columns[1]['count(*)'])
|
||||||
|
?.data
|
||||||
|
.map((row) => ({ key: row.studio_id || row['scenes.studio_id'], doc_count: row['count(*)'] }))
|
||||||
|
.filter((row) => !!row.key)
|
||||||
|
|| [];
|
||||||
|
|
||||||
const total = Number(results.at(-1).data.find((entry) => entry.Variable_name === 'total_found')?.Value) || 0;
|
const total = Number(results.at(-1).data.find((entry) => entry.Variable_name === 'total_found')?.Value) || 0;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -517,6 +540,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||||
actorIds,
|
actorIds,
|
||||||
tagIds,
|
tagIds,
|
||||||
channelIds,
|
channelIds,
|
||||||
|
studioIds,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -540,19 +564,24 @@ export async function fetchScenes(filters, rawOptions, reqUser) {
|
||||||
console.timeEnd('manticore sql');
|
console.timeEnd('manticore sql');
|
||||||
|
|
||||||
const aggYears = options.aggregateYears && result.aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
const aggYears = options.aggregateYears && result.aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count }));
|
||||||
|
const entityIds = options.aggregateChannels && [...(result.aggregations.channelIds || []), ...(result.aggregations.studioIds || [])];
|
||||||
|
|
||||||
const actorCounts = options.aggregateActors && countAggregations(result.aggregations?.actorIds);
|
const actorCounts = options.aggregateActors && countAggregations(result.aggregations?.actorIds);
|
||||||
const tagCounts = options.aggregateTags && countAggregations(result.aggregations?.tagIds);
|
const tagCounts = options.aggregateTags && countAggregations(result.aggregations?.tagIds);
|
||||||
const channelCounts = options.aggregateChannels && countAggregations(result.aggregations?.channelIds);
|
const channelCounts = options.aggregateChannels && countAggregations(entityIds);
|
||||||
|
|
||||||
|
console.log('entity ids', entityIds);
|
||||||
|
|
||||||
console.time('fetch aggregations');
|
console.time('fetch aggregations');
|
||||||
|
|
||||||
const [aggActors, aggTags, aggChannels] = await Promise.all([
|
const [aggActors, aggTags, aggChannels] = await Promise.all([
|
||||||
options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: actorCounts }) : [],
|
options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: actorCounts }) : [],
|
||||||
options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }) : [],
|
options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }) : [],
|
||||||
options.aggregateChannels ? fetchEntitiesById(result.aggregations.channelIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }) : [],
|
options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }) : [],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
console.log('studio ids', aggChannels.filter((studio) => studio.slug === 'wgcz'));
|
||||||
|
|
||||||
console.timeEnd('fetch aggregations');
|
console.timeEnd('fetch aggregations');
|
||||||
|
|
||||||
console.time('fetch full');
|
console.time('fetch full');
|
||||||
|
|
2
static
2
static
|
@ -1 +1 @@
|
||||||
Subproject commit 5e1b2190f0d580321a310c1c1fc95ede8f33473b
|
Subproject commit 333d2604c8987548786434c78162118f50c94bc8
|
Loading…
Reference in New Issue