mirror of
https://github.com/sct/overseerr.git
synced 2025-09-30 23:43:33 +02:00
feat: add genre/studio/network view to Discover results (#1067)
* feat: add genres view to movie/series Discover results * feat: add studio/network view to movie/series Discover results * fix: remove with_release_type filter, since it is removing valid/desired results
This commit is contained in:
@@ -3,9 +3,13 @@ import cacheManager from '../../lib/cache';
|
||||
import ExternalAPI from '../externalapi';
|
||||
import {
|
||||
TmdbCollection,
|
||||
TmdbStudio,
|
||||
TmdbExternalIdResponse,
|
||||
TmdbGenre,
|
||||
TmdbGenresResult,
|
||||
TmdbLanguage,
|
||||
TmdbMovieDetails,
|
||||
TmdbNetwork,
|
||||
TmdbPersonCombinedCredits,
|
||||
TmdbPersonDetail,
|
||||
TmdbRegion,
|
||||
@@ -30,6 +34,8 @@ interface DiscoverMovieOptions {
|
||||
language?: string;
|
||||
primaryReleaseDateGte?: string;
|
||||
primaryReleaseDateLte?: string;
|
||||
genre?: number;
|
||||
studio?: number;
|
||||
sortBy?:
|
||||
| 'popularity.asc'
|
||||
| 'popularity.desc'
|
||||
@@ -53,6 +59,8 @@ interface DiscoverTvOptions {
|
||||
firstAirDateGte?: string;
|
||||
firstAirDateLte?: string;
|
||||
includeEmptyReleaseDate?: boolean;
|
||||
genre?: number;
|
||||
network?: number;
|
||||
sortBy?:
|
||||
| 'popularity.asc'
|
||||
| 'popularity.desc'
|
||||
@@ -120,7 +128,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch person details: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch person details: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -142,7 +150,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`[TMDB] Failed to fetch person combined credits: ${e.message}`
|
||||
`[TMDb] Failed to fetch person combined credits: ${e.message}`
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -168,7 +176,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch movie details: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch movie details: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -194,7 +202,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch tv show details: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch TV show details: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -220,7 +228,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch tv show details: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch TV show details: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -246,7 +254,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +280,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +306,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch movies by keyword: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch movies by keyword: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +333,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`[TMDB] Failed to fetch tv recommendations: ${e.message}`
|
||||
`[TMDb] Failed to fetch TV recommendations: ${e.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -349,7 +357,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch tv similar: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch TV similar: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,6 +368,8 @@ class TheMovieDb extends ExternalAPI {
|
||||
language = 'en',
|
||||
primaryReleaseDateGte,
|
||||
primaryReleaseDateLte,
|
||||
genre,
|
||||
studio,
|
||||
}: DiscoverMovieOptions = {}): Promise<TmdbSearchMovieResponse> => {
|
||||
try {
|
||||
const data = await this.get<TmdbSearchMovieResponse>('/discover/movie', {
|
||||
@@ -368,17 +378,18 @@ class TheMovieDb extends ExternalAPI {
|
||||
page,
|
||||
include_adult: includeAdult,
|
||||
language,
|
||||
with_release_type: '3|2',
|
||||
region: this.region,
|
||||
with_original_language: this.originalLanguage,
|
||||
'primary_release_date.gte': primaryReleaseDateGte,
|
||||
'primary_release_date.lte': primaryReleaseDateLte,
|
||||
with_genres: genre,
|
||||
with_companies: studio,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch discover movies: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch discover movies: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -389,6 +400,8 @@ class TheMovieDb extends ExternalAPI {
|
||||
firstAirDateGte,
|
||||
firstAirDateLte,
|
||||
includeEmptyReleaseDate = false,
|
||||
genre,
|
||||
network,
|
||||
}: DiscoverTvOptions = {}): Promise<TmdbSearchTvResponse> => {
|
||||
try {
|
||||
const data = await this.get<TmdbSearchTvResponse>('/discover/tv', {
|
||||
@@ -401,12 +414,14 @@ class TheMovieDb extends ExternalAPI {
|
||||
'first_air_date.lte': firstAirDateLte,
|
||||
with_original_language: this.originalLanguage,
|
||||
include_null_first_air_dates: includeEmptyReleaseDate,
|
||||
with_genres: genre,
|
||||
with_networks: network,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch discover tv: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch discover TV: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -432,7 +447,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch upcoming movies: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch upcoming movies: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -459,7 +474,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -482,7 +497,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -505,7 +520,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch all trending: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch all trending: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -537,7 +552,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to find by external ID: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to find by external ID: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,11 +579,11 @@ class TheMovieDb extends ExternalAPI {
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
'[TMDB] Failed to find a title with the provided IMDB id'
|
||||
'[TMDb] Failed to find a title with the provided IMDB id'
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`[TMDB] Failed to get movie by external imdb ID: ${e.message}`
|
||||
`[TMDb] Failed to get movie by external imdb ID: ${e.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -596,11 +611,11 @@ class TheMovieDb extends ExternalAPI {
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`[TMDB] Failed to find a TV show with the provided TVDB ID: ${tvdbId}`
|
||||
`[TMDb] Failed to find a TV show with the provided TVDB ID: ${tvdbId}`
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`[TMDB] Failed to get TV show using the external TVDB ID: ${e.message}`
|
||||
`[TMDb] Failed to get TV show using the external TVDB ID: ${e.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -624,7 +639,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch collection: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch collection: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,7 +655,7 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return regions;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch countries: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch countries: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +671,59 @@ class TheMovieDb extends ExternalAPI {
|
||||
|
||||
return languages;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDB] Failed to fetch langauges: ${e.message}`);
|
||||
throw new Error(`[TMDb] Failed to fetch langauges: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async getStudio(studioId: number): Promise<TmdbStudio> {
|
||||
try {
|
||||
const data = await this.get<TmdbStudio>(`/company/${studioId}`);
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDb] Failed to fetch movie studio: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async getNetwork(networkId: number): Promise<TmdbNetwork> {
|
||||
try {
|
||||
const data = await this.get<TmdbNetwork>(`/network/${networkId}`);
|
||||
|
||||
return data;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDb] Failed to fetch TV network: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async getMovieGenres(): Promise<TmdbGenre[]> {
|
||||
try {
|
||||
const data = await this.get<TmdbGenresResult>(
|
||||
'/genre/movie/list',
|
||||
{},
|
||||
86400 // 24 hours
|
||||
);
|
||||
|
||||
const movieGenres = sortBy(data.genres, 'name');
|
||||
|
||||
return movieGenres;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDb] Failed to fetch movie genres: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async getTvGenres(): Promise<TmdbGenre[]> {
|
||||
try {
|
||||
const data = await this.get<TmdbGenresResult>(
|
||||
'/genre/tv/list',
|
||||
{},
|
||||
86400 // 24 hours
|
||||
);
|
||||
|
||||
const tvGenres = sortBy(data.genres, 'name');
|
||||
|
||||
return tvGenres;
|
||||
} catch (e) {
|
||||
throw new Error(`[TMDb] Failed to fetch TV genres: ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -381,3 +381,32 @@ export interface TmdbLanguage {
|
||||
english_name: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TmdbGenresResult {
|
||||
genres: TmdbGenre[];
|
||||
}
|
||||
|
||||
export interface TmdbGenre {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TmdbStudio {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
headquarters?: string;
|
||||
homepage?: string;
|
||||
logo_path?: string;
|
||||
origin_country?: string;
|
||||
parent_company?: TmdbStudio;
|
||||
}
|
||||
|
||||
export interface TmdbNetwork {
|
||||
id: number;
|
||||
name: string;
|
||||
headquarters?: string;
|
||||
homepage?: string;
|
||||
logo_path?: string;
|
||||
origin_country?: string;
|
||||
}
|
||||
|
Reference in New Issue
Block a user