import RottenTomatoes from '@server/api/rating/rottentomatoes'; import TheMovieDb from '@server/api/themoviedb'; import { MediaType } from '@server/constants/media'; import Media from '@server/entity/Media'; import logger from '@server/logger'; import { mapTvResult } from '@server/models/Search'; import { mapSeasonWithEpisodes, mapTvDetails } from '@server/models/Tv'; import { Router } from 'express'; const tvRoutes = Router(); tvRoutes.get('/:id', async (req, res, next) => { const tmdb = new TheMovieDb(); try { const tv = await tmdb.getTvShow({ tvId: Number(req.params.id), language: req.locale ?? (req.query.language as string), }); const media = await Media.getMedia(tv.id, MediaType.TV); return res.status(200).json(mapTvDetails(tv, media)); } catch (e) { logger.debug('Something went wrong retrieving series', { label: 'API', errorMessage: e.message, tvId: req.params.id, }); return next({ status: 500, message: 'Unable to retrieve series.', }); } }); tvRoutes.get('/:id/season/:seasonNumber', async (req, res, next) => { const tmdb = new TheMovieDb(); try { const season = await tmdb.getTvSeason({ tvId: Number(req.params.id), seasonNumber: Number(req.params.seasonNumber), language: req.locale ?? (req.query.language as string), }); return res.status(200).json(mapSeasonWithEpisodes(season)); } catch (e) { logger.debug('Something went wrong retrieving season', { label: 'API', errorMessage: e.message, tvId: req.params.id, seasonNumber: req.params.seasonNumber, }); return next({ status: 500, message: 'Unable to retrieve season.', }); } }); tvRoutes.get('/:id/recommendations', async (req, res, next) => { const tmdb = new TheMovieDb(); try { const results = await tmdb.getTvRecommendations({ tvId: Number(req.params.id), page: Number(req.query.page), language: req.locale ?? (req.query.language as string), }); const media = await Media.getRelatedMedia( results.results.map((result) => result.id) ); return res.status(200).json({ page: results.page, totalPages: results.total_pages, totalResults: results.total_results, results: results.results.map((result) => mapTvResult( result, media.find( (req) => req.tmdbId === result.id && req.mediaType === MediaType.TV ) ) ), }); } catch (e) { logger.debug('Something went wrong retrieving series recommendations', { label: 'API', errorMessage: e.message, tvId: req.params.id, }); return next({ status: 500, message: 'Unable to retrieve series recommendations.', }); } }); tvRoutes.get('/:id/similar', async (req, res, next) => { const tmdb = new TheMovieDb(); try { const results = await tmdb.getTvSimilar({ tvId: Number(req.params.id), page: Number(req.query.page), language: req.locale ?? (req.query.language as string), }); const media = await Media.getRelatedMedia( results.results.map((result) => result.id) ); return res.status(200).json({ page: results.page, totalPages: results.total_pages, totalResults: results.total_results, results: results.results.map((result) => mapTvResult( result, media.find( (req) => req.tmdbId === result.id && req.mediaType === MediaType.TV ) ) ), }); } catch (e) { logger.debug('Something went wrong retrieving similar series', { label: 'API', errorMessage: e.message, tvId: req.params.id, }); return next({ status: 500, message: 'Unable to retrieve similar series.', }); } }); tvRoutes.get('/:id/ratings', async (req, res, next) => { const tmdb = new TheMovieDb(); const rtapi = new RottenTomatoes(); try { const tv = await tmdb.getTvShow({ tvId: Number(req.params.id), }); const rtratings = await rtapi.getTVRatings( tv.name, tv.first_air_date ? Number(tv.first_air_date.slice(0, 4)) : undefined ); if (!rtratings) { return next({ status: 404, message: 'Rotten Tomatoes ratings not found.', }); } return res.status(200).json(rtratings); } catch (e) { logger.debug('Something went wrong retrieving series ratings', { label: 'API', errorMessage: e.message, tvId: req.params.id, }); return next({ status: 500, message: 'Unable to retrieve series ratings.', }); } }); export default tvRoutes;