fix: properly fetch Plex music library with correct release-group mapping

This commit is contained in:
Pierre
2025-01-15 21:08:39 +01:00
committed by HiItsStolas
parent a0a8dfc496
commit f9259cfcdf
3 changed files with 143 additions and 5 deletions

View File

@@ -103,6 +103,73 @@ class MusicBrainz extends ExternalAPI {
}
}
private static requestQueue: Promise<void> = Promise.resolve();
private lastRequestTime = 0;
private readonly RATE_LIMIT_DELAY = 1100;
public async getReleaseGroup({
releaseId,
}: {
releaseId: string;
}): Promise<string | null> {
try {
await MusicBrainz.requestQueue;
MusicBrainz.requestQueue = (async () => {
const now = Date.now();
const timeSinceLastRequest = now - this.lastRequestTime;
if (timeSinceLastRequest < this.RATE_LIMIT_DELAY) {
await new Promise((resolve) =>
setTimeout(resolve, this.RATE_LIMIT_DELAY - timeSinceLastRequest)
);
}
this.lastRequestTime = Date.now();
})();
await MusicBrainz.requestQueue;
const data = await this.getRolling<any>(
`/release/${releaseId}`,
{
inc: 'release-groups',
fmt: 'json',
},
43200,
{
headers: {
'User-Agent':
'Jellyseerr/1.0.0 (https://github.com/Fallenbagel/jellyseerr; hello@jellyseerr.com)',
Accept: 'application/json',
},
},
'https://musicbrainz.org/ws/2'
);
return data['release-group']?.id || null;
} catch (e) {
if (e.message.includes('503')) {
await new Promise((resolve) =>
setTimeout(resolve, this.RATE_LIMIT_DELAY * 2)
);
await MusicBrainz.requestQueue;
MusicBrainz.requestQueue = Promise.resolve();
this.lastRequestTime = Date.now();
try {
return await this.getReleaseGroup({ releaseId });
} catch (retryError) {
throw new Error(
`[MusicBrainz] Failed to fetch release group after retry: ${retryError.message}`
);
}
}
throw new Error(
`[MusicBrainz] Failed to fetch release group: ${e.message}`
);
}
}
public async getWikipediaExtract(
id: string,
language = 'en',

View File

@@ -28,7 +28,7 @@ interface PlexLibraryResponse {
}
export interface PlexLibrary {
type: 'show' | 'movie' | 'music';
type: 'show' | 'movie' | 'artist';
key: string;
title: string;
agent: string;
@@ -155,7 +155,7 @@ class PlexAPI {
(library) =>
library.type === 'movie' ||
library.type === 'show' ||
library.type === 'music'
library.type === 'artist'
)
// Remove libraries that do not have a metadata agent set (usually personal video libraries)
.filter((library) => library.agent !== 'com.plexapp.agents.none')
@@ -168,7 +168,7 @@ class PlexAPI {
id: library.key,
name: library.title,
enabled: existing?.enabled ?? false,
type: library.type,
type: library.type === 'artist' ? 'music' : library.type,
lastScan: existing?.lastScan,
};
});
@@ -230,7 +230,7 @@ class PlexAPI {
options: { addedAt: number } = {
addedAt: Date.now() - 1000 * 60 * 60,
},
mediaType: 'movie' | 'show' | 'music'
mediaType: 'movie' | 'show' | 'artist'
): Promise<PlexLibraryItem[]> {
const response = await this.plexClient.query<PlexLibraryResponse>({
uri: `/library/sections/${id}/all?type=${