import { knexQuery as knex, knexOwner } from './knex.js'; import { curateActor, sortActorsByGender } from './actors.js'; import { curateMedia } from './media.js'; import { curateStash } from './stashes.js'; import promiseProps from '../utils/promise-props.js'; function curateSerie(rawSerie, assets) { if (!rawSerie) { return null; } return { id: rawSerie.id, title: rawSerie.title, slug: rawSerie.slug, url: rawSerie.url, date: rawSerie.date, createdAt: rawSerie.created_at, effectiveDate: rawSerie.effective_date, description: rawSerie.description, duration: rawSerie.duration, channel: { id: assets.channel.id, slug: assets.channel.slug, name: assets.channel.name, type: assets.channel.type, isIndependent: assets.channel.independent, hasLogo: assets.channel.has_logo, }, network: assets.channel.network_id ? { id: assets.channel.network_id, slug: assets.channel.network_slug, name: assets.channel.network_name, type: assets.channel.network_type, hasLogo: assets.channel.has_logo, } : null, actors: sortActorsByGender(assets.actors.map((actor) => curateActor(actor, { sceneDate: rawSerie.effective_date }))), directors: assets.directors.map((director) => ({ id: director.id, slug: director.slug, name: director.name, })), tags: assets.tags.map((tag) => ({ id: tag.id, slug: tag.slug, name: tag.name, })), poster: curateMedia(assets.poster), // covers: assets.covers.map((cover) => curateMedia(cover)), photos: assets.photos.map((photo) => curateMedia(photo)), stashes: assets.stashes?.map((stash) => curateStash(stash)) || [], createdBatchId: rawSerie.created_batch_id, updatedBatchId: rawSerie.updated_batch_id, }; } export async function fetchSeriesById(serieIds, reqUser) { const { series, channels, actors, directors, tags, posters, photos, stashes, } = await promiseProps({ series: knex('series') .select('series.*', knex.raw('sum(releases.duration) as duration')) .leftJoin('series_scenes', 'series_scenes.serie_id', 'series.id') .leftJoin('releases', 'releases.id', 'series_scenes.scene_id') .whereIn('series.id', serieIds) .groupBy('series.id'), channels: knex('series') .select('channels.*', 'networks.id as network_id', 'networks.slug as network_slug', 'networks.name as network_name', 'networks.type as network_type') .whereIn('series.id', serieIds) .leftJoin('entities as channels', 'channels.id', 'series.entity_id') .leftJoin('entities as networks', 'networks.id', 'channels.parent_id') .groupBy('channels.id', 'networks.id'), actors: knex('series') .select( 'actors.*', 'actors_meta.*', 'releases_actors.release_id', 'series.id as serie_id', ) .distinctOn('actors.id', 'series.id') // cannot distinct on JSON column avatar, must specify .whereIn('series.id', serieIds) .whereNotNull('actors.id') .leftJoin('series_scenes', 'series_scenes.serie_id', 'series.id') .leftJoin('releases_actors', 'releases_actors.release_id', 'series_scenes.scene_id') .leftJoin('actors', 'actors.id', 'releases_actors.actor_id') .leftJoin('actors_meta', 'actors_meta.actor_id', 'actors.id'), directors: knex('series') .whereIn('series.id', serieIds) .leftJoin('series_scenes', 'series_scenes.serie_id', 'series.id') .leftJoin('releases_directors', 'releases_directors.release_id', 'series_scenes.scene_id') .leftJoin('actors as directors', 'directors.id', 'releases_directors.director_id'), tags: knex('series') .select('tags.id', 'tags.slug', 'tags.name', 'tags.priority', 'series.id as serie_id') .distinct() .whereIn('series.id', serieIds) .whereNotNull('tags.id') .leftJoin('series_scenes', 'series_scenes.serie_id', 'series.id') .leftJoin('releases_tags', 'releases_tags.release_id', 'series_scenes.scene_id') .leftJoin('tags', 'tags.id', 'releases_tags.tag_id') .orderBy('priority', 'desc'), posters: knex('series_posters') .whereIn('serie_id', serieIds) .leftJoin('media', 'media.id', 'series_posters.media_id') .orderBy('media.index'), photos: knex('series') .whereIn('series.id', serieIds) .leftJoin('series_scenes', 'series_scenes.serie_id', 'series.id') .leftJoin('releases_photos', 'releases_photos.release_id', 'series_scenes.scene_id') .leftJoin('media', 'media.id', 'releases_photos.media_id'), stashes: reqUser ? knexOwner('stashes_series') .leftJoin('stashes', 'stashes.id', 'stashes_series.stash_id') .where('stashes.user_id', reqUser.id) .whereIn('stashes_series.serie_id', serieIds) : [], }); return serieIds.map((serieId) => { const serie = series.find((serieEntry) => serieEntry.id === serieId); if (!serie) { console.warn('Cannot find serie', serieId); return null; } const serieChannel = channels.find((entity) => entity.id === serie.entity_id); const serieActors = actors.filter((actor) => actor.serie_id === serieId); const serieDirectors = directors.filter((director) => director.release_id === serieId); const serieTags = tags.filter((tag) => tag.serie_id === serieId); const seriePosters = posters.filter((poster) => poster.serie_id === serieId); const seriePhotos = photos.filter((photo) => photo.release_id === serieId); const serieStashes = stashes.filter((stash) => stash.serie_id === serieId); return curateSerie(serie, { channel: serieChannel, actors: serieActors, directors: serieDirectors, tags: serieTags, posters: seriePosters, photos: seriePhotos, stashes: serieStashes, }); }).filter(Boolean); }