refactor: switch from Axios for Fetch API (#840)

* refactor: switch ExternalAPI to Fetch API

* fix: add missing auth token in Plex request

* fix: send proper URL params

* ci: try to fix format checker

* ci: ci: try to fix format checker

* ci: try to fix format checker

* refactor: make tautulli use the ExternalAPI class

* refactor: add rate limit to fetch api

* refactor: add rate limit to fetch api

* refactor: switch server from axios to fetch api

* refactor: switch frontend from axios to fetch api

* fix: switch from URL objects to strings

* fix: use the right search params for ExternalAPI

* fix: better log for ExternalAPI errors

* feat: add retry to external API requests

* fix: try to fix network errors with IPv6

* fix: imageProxy rate limit

* revert: remove retry to external API requests

* feat: set IPv4 first as an option

* fix(jellyfinapi): add missing argument in JellyfinAPI constructor

* refactor: clean the rate limit utility
This commit is contained in:
Gauthier
2024-07-14 19:04:36 +02:00
committed by GitHub
parent ae955e9e7c
commit b36bb3fa58
100 changed files with 5380 additions and 10870 deletions

View File

@@ -112,8 +112,8 @@ class TheMovieDb extends ExternalAPI {
{
nodeCache: cacheManager.getCache('tmdb').data,
rateLimit: {
maxRequests: 20,
maxRPS: 50,
id: 'tmdb',
},
}
);
@@ -129,7 +129,10 @@ class TheMovieDb extends ExternalAPI {
}: SearchOptions): Promise<TmdbSearchMultiResponse> => {
try {
const data = await this.get<TmdbSearchMultiResponse>('/search/multi', {
params: { query, page, include_adult: includeAdult, language },
query,
page: page.toString(),
include_adult: includeAdult ? 'true' : 'false',
language,
});
return data;
@@ -152,13 +155,11 @@ class TheMovieDb extends ExternalAPI {
}: SingleSearchOptions): Promise<TmdbSearchMovieResponse> => {
try {
const data = await this.get<TmdbSearchMovieResponse>('/search/movie', {
params: {
query,
page,
include_adult: includeAdult,
language,
primary_release_year: year,
},
query,
page: page.toString(),
include_adult: includeAdult ? 'true' : 'false',
language,
primary_release_year: year?.toString() || '',
});
return data;
@@ -181,13 +182,11 @@ class TheMovieDb extends ExternalAPI {
}: SingleSearchOptions): Promise<TmdbSearchTvResponse> => {
try {
const data = await this.get<TmdbSearchTvResponse>('/search/tv', {
params: {
query,
page,
include_adult: includeAdult,
language,
first_air_date_year: year,
},
query,
page: page.toString(),
include_adult: includeAdult ? 'true' : 'false',
language,
first_air_date_year: year?.toString() || '',
});
return data;
@@ -210,7 +209,7 @@ class TheMovieDb extends ExternalAPI {
}): Promise<TmdbPersonDetails> => {
try {
const data = await this.get<TmdbPersonDetails>(`/person/${personId}`, {
params: { language },
language,
});
return data;
@@ -230,7 +229,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbPersonCombinedCredits>(
`/person/${personId}/combined_credits`,
{
params: { language },
language,
}
);
@@ -253,11 +252,9 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbMovieDetails>(
`/movie/${movieId}`,
{
params: {
language,
append_to_response:
'credits,external_ids,videos,keywords,release_dates,watch/providers',
},
language,
append_to_response:
'credits,external_ids,videos,keywords,release_dates,watch/providers',
},
43200
);
@@ -279,11 +276,9 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbTvDetails>(
`/tv/${tvId}`,
{
params: {
language,
append_to_response:
'aggregate_credits,credits,external_ids,keywords,videos,content_ratings,watch/providers',
},
language,
append_to_response:
'aggregate_credits,credits,external_ids,keywords,videos,content_ratings,watch/providers',
},
43200
);
@@ -307,10 +302,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSeasonWithEpisodes>(
`/tv/${tvId}/season/${seasonNumber}`,
{
params: {
language,
append_to_response: 'external_ids',
},
language: language || '',
append_to_response: 'external_ids',
}
);
@@ -333,10 +326,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchMovieResponse>(
`/movie/${movieId}/recommendations`,
{
params: {
page,
language,
},
page: page.toString(),
language,
}
);
@@ -359,10 +350,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchMovieResponse>(
`/movie/${movieId}/similar`,
{
params: {
page,
language,
},
page: page.toString(),
language,
}
);
@@ -385,10 +374,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchMovieResponse>(
`/keyword/${keywordId}/movies`,
{
params: {
page,
language,
},
page: page.toString(),
language,
}
);
@@ -411,10 +398,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchTvResponse>(
`/tv/${tvId}/recommendations`,
{
params: {
page,
language,
},
page: page.toString(),
language,
}
);
@@ -437,10 +422,8 @@ class TheMovieDb extends ExternalAPI {
}): Promise<TmdbSearchTvResponse> {
try {
const data = await this.get<TmdbSearchTvResponse>(`/tv/${tvId}/similar`, {
params: {
page,
language,
},
page: page.toString(),
language,
});
return data;
@@ -481,40 +464,38 @@ class TheMovieDb extends ExternalAPI {
.split('T')[0];
const data = await this.get<TmdbSearchMovieResponse>('/discover/movie', {
params: {
sort_by: sortBy,
page,
include_adult: includeAdult,
language,
region: this.region,
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? undefined
: this.originalLanguage,
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'primary_release_date.gte':
!primaryReleaseDateGte && primaryReleaseDateLte
? defaultPastDate
: primaryReleaseDateGte,
'primary_release_date.lte':
!primaryReleaseDateLte && primaryReleaseDateGte
? defaultFutureDate
: primaryReleaseDateLte,
with_genres: genre,
with_companies: studio,
with_keywords: keywords,
'with_runtime.gte': withRuntimeGte,
'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
watch_region: watchRegion,
with_watch_providers: watchProviders,
},
sort_by: sortBy,
page: page.toString(),
include_adult: includeAdult ? 'true' : 'false',
language,
region: this.region || '',
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? ''
: this.originalLanguage || '',
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'primary_release_date.gte':
!primaryReleaseDateGte && primaryReleaseDateLte
? defaultPastDate
: primaryReleaseDateGte || '',
'primary_release_date.lte':
!primaryReleaseDateLte && primaryReleaseDateGte
? defaultFutureDate
: primaryReleaseDateLte || '',
with_genres: genre || '',
with_companies: studio || '',
with_keywords: keywords || '',
'with_runtime.gte': withRuntimeGte || '',
'with_runtime.lte': withRuntimeLte || '',
'vote_average.gte': voteAverageGte || '',
'vote_average.lte': voteAverageLte || '',
'vote_count.gte': voteCountGte || '',
'vote_count.lte': voteCountLte || '',
watch_region: watchRegion || '',
with_watch_providers: watchProviders || '',
});
return data;
@@ -555,40 +536,40 @@ class TheMovieDb extends ExternalAPI {
.split('T')[0];
const data = await this.get<TmdbSearchTvResponse>('/discover/tv', {
params: {
sort_by: sortBy,
page,
language,
region: this.region,
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'first_air_date.gte':
!firstAirDateGte && firstAirDateLte
? defaultPastDate
: firstAirDateGte,
'first_air_date.lte':
!firstAirDateLte && firstAirDateGte
? defaultFutureDate
: firstAirDateLte,
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? undefined
: this.originalLanguage,
include_null_first_air_dates: includeEmptyReleaseDate,
with_genres: genre,
with_networks: network,
with_keywords: keywords,
'with_runtime.gte': withRuntimeGte,
'with_runtime.lte': withRuntimeLte,
'vote_average.gte': voteAverageGte,
'vote_average.lte': voteAverageLte,
'vote_count.gte': voteCountGte,
'vote_count.lte': voteCountLte,
with_watch_providers: watchProviders,
watch_region: watchRegion,
},
sort_by: sortBy,
page: page.toString(),
language,
region: this.region || '',
// Set our release date values, but check if one is set and not the other,
// so we can force a past date or a future date. TMDB Requires both values if one is set!
'first_air_date.gte':
!firstAirDateGte && firstAirDateLte
? defaultPastDate
: firstAirDateGte || '',
'first_air_date.lte':
!firstAirDateLte && firstAirDateGte
? defaultFutureDate
: firstAirDateLte || '',
with_original_language:
originalLanguage && originalLanguage !== 'all'
? originalLanguage
: originalLanguage === 'all'
? ''
: this.originalLanguage || '',
include_null_first_air_dates: includeEmptyReleaseDate
? 'true'
: 'false',
with_genres: genre || '',
with_networks: network?.toString() || '',
with_keywords: keywords || '',
'with_runtime.gte': withRuntimeGte || '',
'with_runtime.lte': withRuntimeLte || '',
'vote_average.gte': voteAverageGte || '',
'vote_average.lte': voteAverageLte || '',
'vote_count.gte': voteCountGte || '',
'vote_count.lte': voteCountLte || '',
with_watch_providers: watchProviders || '',
watch_region: watchRegion || '',
});
return data;
@@ -608,12 +589,10 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbUpcomingMoviesResponse>(
'/movie/upcoming',
{
params: {
page,
language,
region: this.region,
originalLanguage: this.originalLanguage,
},
page: page.toString(),
language,
region: this.region || '',
originalLanguage: this.originalLanguage || '',
}
);
@@ -636,11 +615,9 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchMultiResponse>(
`/trending/all/${timeWindow}`,
{
params: {
page,
language,
region: this.region,
},
page: page.toString(),
language,
region: this.region || '',
}
);
@@ -661,9 +638,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchMovieResponse>(
`/trending/movie/${timeWindow}`,
{
params: {
page,
},
page: page.toString(),
}
);
@@ -684,9 +659,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbSearchTvResponse>(
`/trending/tv/${timeWindow}`,
{
params: {
page,
},
page: page.toString(),
}
);
@@ -715,10 +688,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbExternalIdResponse>(
`/find/${externalId}`,
{
params: {
external_source: type === 'imdb' ? 'imdb_id' : 'tvdb_id',
language,
},
external_source: type === 'imdb' ? 'imdb_id' : 'tvdb_id',
language,
}
);
@@ -808,9 +779,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbCollection>(
`/collection/${collectionId}`,
{
params: {
language,
},
language,
}
);
@@ -883,9 +852,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbGenresResult>(
'/genre/movie/list',
{
params: {
language,
},
language,
},
86400 // 24 hours
);
@@ -897,9 +864,7 @@ class TheMovieDb extends ExternalAPI {
const englishData = await this.get<TmdbGenresResult>(
'/genre/movie/list',
{
params: {
language: 'en',
},
language: 'en',
},
86400 // 24 hours
);
@@ -934,9 +899,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbGenresResult>(
'/genre/tv/list',
{
params: {
language,
},
language,
},
86400 // 24 hours
);
@@ -948,9 +911,7 @@ class TheMovieDb extends ExternalAPI {
const englishData = await this.get<TmdbGenresResult>(
'/genre/tv/list',
{
params: {
language: 'en',
},
language: 'en',
},
86400 // 24 hours
);
@@ -1005,10 +966,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbKeywordSearchResponse>(
'/search/keyword',
{
params: {
query,
page,
},
query,
page: page.toString(),
},
86400 // 24 hours
);
@@ -1030,10 +989,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<TmdbCompanySearchResponse>(
'/search/company',
{
params: {
query,
page,
},
query,
page: page.toString(),
},
86400 // 24 hours
);
@@ -1053,9 +1010,7 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<{ results: TmdbWatchProviderRegion[] }>(
'/watch/providers/regions',
{
params: {
language: language ?? this.originalLanguage,
},
language: language ? this.originalLanguage || '' : '',
},
86400 // 24 hours
);
@@ -1079,10 +1034,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<{ results: TmdbWatchProviderDetails[] }>(
'/watch/providers/movie',
{
params: {
language: language ?? this.originalLanguage,
watch_region: watchRegion,
},
language: language ? this.originalLanguage || '' : '',
watch_region: watchRegion,
},
86400 // 24 hours
);
@@ -1106,10 +1059,8 @@ class TheMovieDb extends ExternalAPI {
const data = await this.get<{ results: TmdbWatchProviderDetails[] }>(
'/watch/providers/tv',
{
params: {
language: language ?? this.originalLanguage,
watch_region: watchRegion,
},
language: language ? this.originalLanguage || '' : '',
watch_region: watchRegion,
},
86400 // 24 hours
);