mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00

* feat: map AniDB IDs from Hama agent to tvdb/tmdb/imdb IDs re #453 * refactor: removes sync job for AnimeList, load mapping on demand * refactor: addressing review comments, using typescript types for xml parsing * refactor: make sure sync job does not update create same tvshow/movie twice Hama agent can have same tvdbid it for different library items - for example when user stores different seasons for same tv show separately. This change adds "AsyncLock" that guarantees code in callback runs for same id fully, before running same callback next time. * refactor: do not use season 0 tvdbid for tvshow from mapping file * refactor: support multiple imdb mappings for same anidb entry * refactor: add debug log for missing tvdb entries in tmdb lookups from anidb/hama agent
144 lines
3.2 KiB
TypeScript
144 lines
3.2 KiB
TypeScript
import NodePlexAPI from 'plex-api';
|
|
import { getSettings } from '../lib/settings';
|
|
|
|
export interface PlexLibraryItem {
|
|
ratingKey: string;
|
|
parentRatingKey?: string;
|
|
grandparentRatingKey?: string;
|
|
title: string;
|
|
guid: string;
|
|
parentGuid?: string;
|
|
grandparentGuid?: string;
|
|
type: 'movie' | 'show' | 'season' | 'episode';
|
|
}
|
|
|
|
interface PlexLibraryResponse {
|
|
MediaContainer: {
|
|
Metadata: PlexLibraryItem[];
|
|
};
|
|
}
|
|
|
|
export interface PlexLibrary {
|
|
type: 'show' | 'movie';
|
|
key: string;
|
|
title: string;
|
|
agent: string;
|
|
}
|
|
|
|
interface PlexLibrariesResponse {
|
|
MediaContainer: {
|
|
Directory: PlexLibrary[];
|
|
};
|
|
}
|
|
|
|
export interface PlexMetadata {
|
|
ratingKey: string;
|
|
parentRatingKey?: string;
|
|
guid: string;
|
|
type: 'movie' | 'show' | 'season';
|
|
title: string;
|
|
Guid: {
|
|
id: string;
|
|
}[];
|
|
Children?: {
|
|
size: 12;
|
|
Metadata: PlexMetadata[];
|
|
};
|
|
index: number;
|
|
parentIndex?: number;
|
|
leafCount: number;
|
|
viewedLeafCount: number;
|
|
}
|
|
|
|
interface PlexMetadataResponse {
|
|
MediaContainer: {
|
|
Metadata: PlexMetadata[];
|
|
};
|
|
}
|
|
|
|
class PlexAPI {
|
|
private plexClient: NodePlexAPI;
|
|
|
|
constructor({ plexToken }: { plexToken?: string }) {
|
|
const settings = getSettings();
|
|
|
|
this.plexClient = new NodePlexAPI({
|
|
hostname: settings.plex.ip,
|
|
port: settings.plex.port,
|
|
https: settings.plex.useSsl,
|
|
token: plexToken,
|
|
authenticator: {
|
|
authenticate: (
|
|
_plexApi,
|
|
cb: (err?: string, token?: string) => void
|
|
) => {
|
|
if (!plexToken) {
|
|
return cb('Plex Token not found!');
|
|
}
|
|
cb(undefined, plexToken);
|
|
},
|
|
},
|
|
// requestOptions: {
|
|
// includeChildren: 1,
|
|
// },
|
|
options: {
|
|
identifier: settings.clientId,
|
|
product: 'Overseerr',
|
|
deviceName: 'Overseerr',
|
|
platform: 'Overseerr',
|
|
},
|
|
});
|
|
}
|
|
|
|
public async getStatus() {
|
|
return await this.plexClient.query('/');
|
|
}
|
|
|
|
public async getLibraries(): Promise<PlexLibrary[]> {
|
|
const response = await this.plexClient.query<PlexLibrariesResponse>(
|
|
'/library/sections'
|
|
);
|
|
|
|
return response.MediaContainer.Directory;
|
|
}
|
|
|
|
public async getLibraryContents(id: string): Promise<PlexLibraryItem[]> {
|
|
const response = await this.plexClient.query<PlexLibraryResponse>(
|
|
`/library/sections/${id}/all`
|
|
);
|
|
|
|
return response.MediaContainer.Metadata;
|
|
}
|
|
|
|
public async getMetadata(
|
|
key: string,
|
|
options: { includeChildren?: boolean } = {}
|
|
): Promise<PlexMetadata> {
|
|
const response = await this.plexClient.query<PlexMetadataResponse>(
|
|
`/library/metadata/${key}${
|
|
options.includeChildren ? '?includeChildren=1' : ''
|
|
}`
|
|
);
|
|
|
|
return response.MediaContainer.Metadata[0];
|
|
}
|
|
|
|
public async getChildrenMetadata(key: string): Promise<PlexMetadata[]> {
|
|
const response = await this.plexClient.query<PlexMetadataResponse>(
|
|
`/library/metadata/${key}/children`
|
|
);
|
|
|
|
return response.MediaContainer.Metadata;
|
|
}
|
|
|
|
public async getRecentlyAdded(id: string): Promise<PlexLibraryItem[]> {
|
|
const response = await this.plexClient.query<PlexLibraryResponse>(
|
|
`/library/sections/${id}/recentlyAdded`
|
|
);
|
|
|
|
return response.MediaContainer.Metadata;
|
|
}
|
|
}
|
|
|
|
export default PlexAPI;
|