fix: disambiguate tmdb ids by media type across lookups (#2577)
This commit is contained in:
@@ -89,18 +89,29 @@ blocklistRoutes.get(
|
||||
type: 'or',
|
||||
}),
|
||||
async (req, res, next) => {
|
||||
const mediaType = req.query.mediaType;
|
||||
if (mediaType !== MediaType.MOVIE && mediaType !== MediaType.TV) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Invalid or missing mediaType query parameter.',
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const blocklisteRepository = getRepository(Blocklist);
|
||||
|
||||
const blocklistItem = await blocklisteRepository.findOneOrFail({
|
||||
where: { tmdbId: Number(req.params.id) },
|
||||
where: {
|
||||
tmdbId: Number(req.params.id),
|
||||
mediaType,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).send(blocklistItem);
|
||||
} catch (e) {
|
||||
if (e instanceof EntityNotFoundError) {
|
||||
return next({
|
||||
status: 401,
|
||||
status: 404,
|
||||
message: e.message,
|
||||
});
|
||||
}
|
||||
@@ -153,11 +164,22 @@ blocklistRoutes.delete(
|
||||
type: 'or',
|
||||
}),
|
||||
async (req, res, next) => {
|
||||
const mediaType = req.query.mediaType;
|
||||
if (mediaType !== MediaType.MOVIE && mediaType !== MediaType.TV) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Invalid or missing mediaType query parameter.',
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const blocklisteRepository = getRepository(Blocklist);
|
||||
|
||||
const blocklistItem = await blocklisteRepository.findOneOrFail({
|
||||
where: { tmdbId: Number(req.params.id) },
|
||||
where: {
|
||||
tmdbId: Number(req.params.id),
|
||||
mediaType,
|
||||
},
|
||||
});
|
||||
|
||||
await blocklisteRepository.remove(blocklistItem);
|
||||
@@ -165,7 +187,10 @@ blocklistRoutes.delete(
|
||||
const mediaRepository = getRepository(Media);
|
||||
|
||||
const mediaItem = await mediaRepository.findOneOrFail({
|
||||
where: { tmdbId: Number(req.params.id) },
|
||||
where: {
|
||||
tmdbId: Number(req.params.id),
|
||||
mediaType: req.query.mediaType as MediaType,
|
||||
},
|
||||
});
|
||||
|
||||
await mediaRepository.remove(mediaItem);
|
||||
@@ -174,7 +199,7 @@ blocklistRoutes.delete(
|
||||
} catch (e) {
|
||||
if (e instanceof EntityNotFoundError) {
|
||||
return next({
|
||||
status: 401,
|
||||
status: 404,
|
||||
message: e.message,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import TheMovieDb from '@server/api/themoviedb';
|
||||
import { MediaType } from '@server/constants/media';
|
||||
import Media from '@server/entity/Media';
|
||||
import logger from '@server/logger';
|
||||
import { mapCollection } from '@server/models/Collection';
|
||||
@@ -17,7 +18,10 @@ collectionRoutes.get<{ id: string }>('/:id', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
collection.parts.map((part) => part.id)
|
||||
collection.parts.map((part) => ({
|
||||
tmdbId: part.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json(mapCollection(collection, media));
|
||||
|
||||
@@ -124,7 +124,10 @@ discoverRoutes.get('/movies', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
let keywordData: TmdbKeyword[] = [];
|
||||
@@ -193,7 +196,10 @@ discoverRoutes.get<{ language: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -251,7 +257,10 @@ discoverRoutes.get<{ genreId: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -299,7 +308,10 @@ discoverRoutes.get<{ studioId: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -349,7 +361,10 @@ discoverRoutes.get('/movies/upcoming', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -417,7 +432,10 @@ discoverRoutes.get('/tv', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
let keywordData: TmdbKeyword[] = [];
|
||||
@@ -485,7 +503,10 @@ discoverRoutes.get<{ language: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -543,7 +564,10 @@ discoverRoutes.get<{ genreId: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -591,7 +615,10 @@ discoverRoutes.get<{ networkId: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -641,7 +668,10 @@ discoverRoutes.get('/tv/upcoming', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -711,7 +741,10 @@ discoverRoutes.get('/trending', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: isMovie(result) ? MediaType.MOVIE : MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -755,7 +788,10 @@ discoverRoutes.get<{ keywordId: string }>(
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
data.results.map((result) => result.id)
|
||||
data.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -27,6 +27,7 @@ movieRoutes.get('/:id', async (req, res, next) => {
|
||||
const onUserWatchlist = await getRepository(Watchlist).exist({
|
||||
where: {
|
||||
tmdbId: Number(req.params.id),
|
||||
mediaType: MediaType.MOVIE,
|
||||
requestedBy: {
|
||||
id: req.user?.id,
|
||||
},
|
||||
@@ -67,7 +68,10 @@ movieRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
results.results.map((result) => result.id)
|
||||
results.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -109,7 +113,10 @@ movieRoutes.get('/:id/similar', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
results.results.map((result) => result.id)
|
||||
results.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.MOVIE,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -43,12 +43,22 @@ personRoutes.get('/:id/combined_credits', async (req, res, next) => {
|
||||
|
||||
const castMedia = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
combinedCredits.cast.map((result) => result.id)
|
||||
combinedCredits.cast
|
||||
.filter((result) => result.media_type)
|
||||
.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: result.media_type!,
|
||||
}))
|
||||
);
|
||||
|
||||
const crewMedia = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
combinedCredits.crew.map((result) => result.id)
|
||||
combinedCredits.crew
|
||||
.filter((result) => result.media_type)
|
||||
.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: result.media_type!,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -35,7 +35,10 @@ searchRoutes.get('/', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
results.results.map((result) => result.id)
|
||||
results.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: result.media_type,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -35,6 +35,7 @@ tvRoutes.get('/:id', async (req, res, next) => {
|
||||
const onUserWatchlist = await getRepository(Watchlist).exist({
|
||||
where: {
|
||||
tmdbId: Number(req.params.id),
|
||||
mediaType: MediaType.TV,
|
||||
requestedBy: {
|
||||
id: req.user?.id,
|
||||
},
|
||||
@@ -110,7 +111,10 @@ tvRoutes.get('/:id/recommendations', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
results.results.map((result) => result.id)
|
||||
results.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
@@ -151,7 +155,10 @@ tvRoutes.get('/:id/similar', async (req, res, next) => {
|
||||
|
||||
const media = await Media.getRelatedMedia(
|
||||
req.user,
|
||||
results.results.map((result) => result.id)
|
||||
results.results.map((result) => ({
|
||||
tmdbId: result.id,
|
||||
mediaType: MediaType.TV,
|
||||
}))
|
||||
);
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -7,6 +7,7 @@ import logger from '@server/logger';
|
||||
import { Router } from 'express';
|
||||
import { QueryFailedError } from 'typeorm';
|
||||
|
||||
import { MediaType } from '@server/constants/media';
|
||||
import { watchlistCreate } from '@server/interfaces/api/watchlistCreate';
|
||||
|
||||
const watchlistRoutes = Router();
|
||||
@@ -57,12 +58,24 @@ watchlistRoutes.delete('/:tmdbId', async (req, res, next) => {
|
||||
});
|
||||
}
|
||||
try {
|
||||
await Watchlist.deleteWatchlist(Number(req.params.tmdbId), req.user);
|
||||
const mediaType = req.query.mediaType;
|
||||
if (mediaType !== MediaType.MOVIE && mediaType !== MediaType.TV) {
|
||||
return next({
|
||||
status: 400,
|
||||
message: 'Invalid mediaType query parameter.',
|
||||
});
|
||||
}
|
||||
|
||||
await Watchlist.deleteWatchlist(
|
||||
Number(req.params.tmdbId),
|
||||
mediaType,
|
||||
req.user
|
||||
);
|
||||
return res.status(204).send();
|
||||
} catch (e) {
|
||||
if (e instanceof NotFoundError) {
|
||||
return next({
|
||||
status: 401,
|
||||
status: 404,
|
||||
message: e.message,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user