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

@@ -16,7 +16,6 @@ import {
} from '@heroicons/react/24/solid';
import type { PlexDevice } from '@server/interfaces/api/plexInterfaces';
import type { PlexSettings, TautulliSettings } from '@server/lib/settings';
import axios from 'axios';
import { Field, Formik } from 'formik';
import { orderBy } from 'lodash';
import { useMemo, useState } from 'react';
@@ -241,9 +240,15 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
params.enable = activeLibraries.join(',');
}
await axios.get('/api/v1/settings/plex/library', {
params,
const searchParams = new URLSearchParams({
sync: params.sync ? 'true' : 'false',
...(params.enable ? { enable: params.enable } : {}),
});
const res = await fetch(
`/api/v1/settings/plex/library?${searchParams.toString()}`
);
if (!res.ok) throw new Error();
setIsSyncing(false);
revalidate();
};
@@ -262,11 +267,12 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
toastId = id;
}
);
const response = await axios.get<PlexDevice[]>(
'/api/v1/settings/plex/devices/servers'
);
if (response.data) {
setAvailableServers(response.data);
const res = await fetch('/api/v1/settings/plex/devices/servers');
if (!res.ok) throw new Error();
const data: PlexDevice[] = await res.json();
if (data) {
setAvailableServers(data);
}
if (toastId) {
removeToast(toastId);
@@ -289,16 +295,30 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
};
const startScan = async () => {
await axios.post('/api/v1/settings/plex/sync', {
start: true,
const res = await fetch('/api/v1/settings/plex/sync', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
start: true,
}),
});
if (!res.ok) throw new Error();
revalidateSync();
};
const cancelScan = async () => {
await axios.post('/api/v1/settings/plex/sync', {
cancel: true,
const res = await fetch('/api/v1/settings/plex/sync', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
cancel: true,
}),
});
if (!res.ok) throw new Error();
revalidateSync();
};
@@ -313,15 +333,19 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
.join(',');
}
await axios.get('/api/v1/settings/plex/library', {
params,
});
const searchParams = new URLSearchParams(params.enable ? params : {});
const res = await fetch(
`/api/v1/settings/plex/library?${searchParams.toString()}`
);
if (!res.ok) throw new Error();
} else {
await axios.get('/api/v1/settings/plex/library', {
params: {
enable: [...activeLibraries, libraryId].join(','),
},
const searchParams = new URLSearchParams({
enable: [...activeLibraries, libraryId].join(','),
});
const res = await fetch(
`/api/v1/settings/plex/library?${searchParams.toString()}`
);
if (!res.ok) throw new Error();
}
setIsSyncing(false);
revalidate();
@@ -385,12 +409,19 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
toastId = id;
}
);
await axios.post('/api/v1/settings/plex', {
ip: values.hostname,
port: Number(values.port),
useSsl: values.useSsl,
webAppUrl: values.webAppUrl,
} as PlexSettings);
const res = await fetch('/api/v1/settings/plex', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
ip: values.hostname,
port: Number(values.port),
useSsl: values.useSsl,
webAppUrl: values.webAppUrl,
} as PlexSettings),
});
if (!res.ok) throw new Error();
syncLibraries();
@@ -748,14 +779,27 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
validationSchema={TautulliSettingsSchema}
onSubmit={async (values) => {
try {
await axios.post('/api/v1/settings/tautulli', {
hostname: values.tautulliHostname,
port: Number(values.tautulliPort),
useSsl: values.tautulliUseSsl,
urlBase: values.tautulliUrlBase,
apiKey: values.tautulliApiKey,
externalUrl: values.tautulliExternalUrl,
} as TautulliSettings);
const res = await fetch('/api/v1/settings/tautulli', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
hostname: values.tautulliHostname,
port: Number(values.tautulliPort),
useSsl: values.tautulliUseSsl,
urlBase: values.tautulliUrlBase,
apiKey: values.tautulliApiKey,
externalUrl: values.tautulliExternalUrl,
} as TautulliSettings),
});
if (!res.ok) throw new Error();
if (!res.ok) {
throw new Error('Failed to fetch');
}
// Continue with any necessary processing
addToast(
intl.formatMessage(messages.toastTautulliSettingsSuccess),