diff --git a/src/backend/metadata/getmeta.ts b/src/backend/metadata/getmeta.ts index c4771451..e428199e 100644 --- a/src/backend/metadata/getmeta.ts +++ b/src/backend/metadata/getmeta.ts @@ -1,12 +1,17 @@ import { FetchError } from "ofetch"; import { formatJWMeta, mediaTypeToJW } from "./justwatch"; +import { Tmdb } from "./tmdb"; +import { Trakt, formatTTVMeta } from "./trakttv"; import { JWMediaResult, JWSeasonMetaResult, JW_API_BASE, MWMediaMeta, MWMediaType, + TMDBMovieData, + TMDBShowData, + TTVSeasonMetaResult, } from "./types"; import { makeUrl, proxiedFetch } from "../helpers/fetch"; @@ -37,6 +42,56 @@ export async function getMetaFromId( type: MWMediaType, id: string, seasonId?: string +): Promise { + const result = await Trakt.searchById(id, mediaTypeToJW(type)); + if (!result) return null; + const details = await Tmdb.getMediaDetails(id, type); + + if (!details) return null; + + let imdbId; + if (type === MWMediaType.MOVIE) { + imdbId = (details as TMDBMovieData).imdb_id ?? undefined; + } + + let seasonData: TTVSeasonMetaResult | undefined; + + if (type === MWMediaType.SERIES) { + const seasons = (details as TMDBShowData).seasons; + const season = + seasons?.find((v) => v.id.toString() === seasonId) ?? seasons?.[0]; + + const episodes = await Trakt.getEpisodes( + result.ttv_entity_id, + season?.season_number ?? 1 + ); + + if (season && episodes) { + seasonData = { + id: season.id.toString(), + season_number: season.season_number, + title: season.name, + episodes, + }; + } + } + + const meta = formatTTVMeta(result, seasonData); + if (!meta) return null; + + console.log(meta); + + return { + meta, + imdbId, + tmdbId: id, + }; +} + +export async function getLegacyMetaFromId( + type: MWMediaType, + id: string, + seasonId?: string ): Promise { const queryType = mediaTypeToJW(type); diff --git a/src/backend/metadata/search.ts b/src/backend/metadata/search.ts index 4506514a..8eb246b7 100644 --- a/src/backend/metadata/search.ts +++ b/src/backend/metadata/search.ts @@ -16,6 +16,7 @@ export async function searchForMedia(query: MWQuery): Promise { const contentType = mediaTypeToTTV(type); const results = await Trakt.search(searchQuery, contentType); + console.log(results[0]); cache.set(query, results, 3600); return results; } diff --git a/src/backend/metadata/tmdb.ts b/src/backend/metadata/tmdb.ts index 460e13b4..3aa1821f 100644 --- a/src/backend/metadata/tmdb.ts +++ b/src/backend/metadata/tmdb.ts @@ -47,31 +47,4 @@ export abstract class Tmdb { public static getMediaPoster(posterPath: string | null): string | undefined { if (posterPath) return `https://image.tmdb.org/t/p/w185/${posterPath}`; } - - /* public static async getMetaFromId( - type: MWMediaType, - id: string, - seasonId?: string - ): Promise { - console.log("getMetaFromId", type, id, seasonId); - - const details = await Tmdb.getMediaDetails(id, type); - - if (!details) return null; - - let imdbId; - if (type === MWMediaType.MOVIE) { - imdbId = (details as TMDBMovieData).imdb_id ?? undefined; - } - - if (!meta.length) return null; - - console.log(meta); - - return { - meta, - imdbId, - tmdbId: id, - }; - } */ } diff --git a/src/backend/metadata/trakttv.ts b/src/backend/metadata/trakttv.ts index 5fb67a17..ae50aefe 100644 --- a/src/backend/metadata/trakttv.ts +++ b/src/backend/metadata/trakttv.ts @@ -2,12 +2,13 @@ import { conf } from "@/setup/config"; import { Tmdb } from "./tmdb"; import { - DetailedMeta, MWMediaMeta, MWMediaType, MWSeasonMeta, TMDBShowData, TTVContentTypes, + TTVEpisodeResult, + TTVEpisodeShort, TTVMediaResult, TTVSearchResult, TTVSeasonMetaResult, @@ -69,14 +70,14 @@ export function formatTTVMeta( } export function TTVMediaToId(media: MWMediaMeta): string { - return ["TTV", mediaTypeToTTV(media.type), media.id].join("-"); + return ["MW", mediaTypeToTTV(media.type), media.id].join("-"); } export function decodeTTVId( paramId: string ): { id: string; type: MWMediaType } | null { const [prefix, type, id] = paramId.split("-", 3); - if (prefix !== "TTV") return null; + if (prefix !== "MW") return null; let mediaType; try { mediaType = TTVMediaToMediaType(type); @@ -101,7 +102,6 @@ export async function formatTTVSearchResult( media.ids.tmdb.toString(), TTVMediaToMediaType(result.type) ); - console.log(details); const seasons = type === MWMediaType.SERIES @@ -115,7 +115,7 @@ export async function formatTTVSearchResult( return { title: media.title, poster: Tmdb.getMediaPoster(details.poster_path), - id: media.ids.trakt, + id: media.ids.tmdb, original_release_year: media.year, ttv_entity_id: media.ids.slug, object_type: mediaTypeToTTV(type), @@ -155,12 +155,33 @@ export abstract class Trakt { return formatted.map((v) => formatTTVMeta(v)); } - public static async getMetaFromId( - type: MWMediaType, - id: string, - seasonId?: string - ): Promise { - console.log("getMetaFromId", type, id, seasonId); - return null; + public static async searchById( + tmdbId: string, + type: "movie" | "show" + ): Promise { + const data = await Trakt.get( + `/search/tmdb/${tmdbId}?type=${type}` + ); + + const formatted = await Promise.all( + // eslint-disable-next-line no-return-await + data.map(async (v) => await formatTTVSearchResult(v)) + ); + return formatted[0]; + } + + public static async getEpisodes( + slug: string, + season: number + ): Promise { + const data = await Trakt.get( + `/shows/${slug}/seasons/${season}` + ); + + return data.map((e) => ({ + id: e.ids.tmdb, + episode_number: e.number, + title: e.title, + })); } } diff --git a/src/backend/metadata/types.ts b/src/backend/metadata/types.ts index 9e87d49d..07671e39 100644 --- a/src/backend/metadata/types.ts +++ b/src/backend/metadata/types.ts @@ -311,3 +311,15 @@ export type JWSeasonMetaResult = { season_number: number; episodes: JWEpisodeShort[]; }; + +export interface TTVEpisodeResult { + season: number; + number: number; + title: string; + ids: { + trakt: number; + tvdb: number; + imdb: string; + tmdb: number; + }; +}