diff --git a/server/src/modules/rules/getter/sonarr-getter.service.ts b/server/src/modules/rules/getter/sonarr-getter.service.ts index cdbb3562..a9417c06 100644 --- a/server/src/modules/rules/getter/sonarr-getter.service.ts +++ b/server/src/modules/rules/getter/sonarr-getter.service.ts @@ -9,6 +9,9 @@ import { import { EPlexDataType } from '../../api/plex-api/enums/plex-data-type-enum'; import { PlexApiService } from '../../api/plex-api/plex-api.service'; import _ from 'lodash'; +import { TmdbApiService } from 'src/modules/api/tmdb-api/tmdb.service'; +import { TmdbIdService } from 'src/modules/api/tmdb-api/tmdb-id.service'; +import { PlexMetadata } from 'src/modules/api/plex-api/interfaces/media.interface'; @Injectable() export class SonarrGetterService { @@ -18,6 +21,8 @@ export class SonarrGetterService { constructor( private readonly servarrService: ServarrService, private readonly plexApi: PlexApiService, + private readonly tmdbApi: TmdbApiService, + private readonly tmdbIdHelper: TmdbIdService, ) { const ruleConstanst = new RuleConstants(); this.plexProperties = ruleConstanst.applications.find( @@ -47,141 +52,183 @@ export class SonarrGetterService { )) as unknown as PlexLibraryItem; } - const tvdbId = libItem.Guid - ? +libItem.Guid.find((el) => el.id.includes('tvdb')).id.split('://')[1] - : libItem.guid.includes('tvdb') - ? +libItem.guid.split('://')[1].split('?')[0] - : null; + const tvdbId = await this.findTvdbidFromPlexLibItem(libItem); - const showResponse = - await this.servarrService.SonarrApi.getSeriesByTvdbId(tvdbId); + if (tvdbId) { + const showResponse = + await this.servarrService.SonarrApi.getSeriesByTvdbId(tvdbId); - season = season - ? showResponse.seasons.find((el) => el.seasonNumber === season) - : season; + season = season + ? showResponse.seasons.find((el) => el.seasonNumber === season) + : season; - // fetch episode or first episode of the season - episode = - [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes(dataType) && - showResponse.added !== '0001-01-01T00:00:00Z' - ? ( - await this.servarrService.SonarrApi.getEpisodes( - showResponse.id, - origLibItem.grandparentRatingKey - ? origLibItem.parentIndex - : origLibItem.index, - [origLibItem.grandparentRatingKey ? origLibItem.index : 1], - ) - )[0] - : undefined; + // fetch episode or first episode of the season + episode = + [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes(dataType) && + showResponse.added !== '0001-01-01T00:00:00Z' + ? ( + await this.servarrService.SonarrApi.getEpisodes( + showResponse.id, + origLibItem.grandparentRatingKey + ? origLibItem.parentIndex + : origLibItem.index, + [origLibItem.grandparentRatingKey ? origLibItem.index : 1], + ) + )[0] + : undefined; - const episodeFile = - episode && dataType === EPlexDataType.EPISODES - ? await this.servarrService.SonarrApi.getEpisodeFile( - episode.episodeFileId, - ) - : undefined; + const episodeFile = + episode && dataType === EPlexDataType.EPISODES + ? await this.servarrService.SonarrApi.getEpisodeFile( + episode.episodeFileId, + ) + : undefined; - if (tvdbId && showResponse) { - switch (prop.name) { - case 'addDate': { - return showResponse.added && - showResponse.added !== '0001-01-01T00:00:00Z' - ? new Date(showResponse.added) - : null; - } - case 'diskSizeEntireShow': { - if ( - [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes(dataType) - ) { - if (dataType === EPlexDataType.EPISODES) { - return episodeFile?.size ? +episodeFile.size / 1048576 : null; + if (tvdbId && showResponse) { + switch (prop.name) { + case 'addDate': { + return showResponse.added && + showResponse.added !== '0001-01-01T00:00:00Z' + ? new Date(showResponse.added) + : null; + } + case 'diskSizeEntireShow': { + if ( + [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes( + dataType, + ) + ) { + if (dataType === EPlexDataType.EPISODES) { + return episodeFile?.size ? +episodeFile.size / 1048576 : null; + } else { + return season?.statistics?.sizeOnDisk + ? +season.statistics.sizeOnDisk / 1048576 + : null; + } } else { - return season?.statistics?.sizeOnDisk - ? +season.statistics.sizeOnDisk / 1048576 + return showResponse.statistics.sizeOnDisk + ? +showResponse.statistics.sizeOnDisk / 1048576 : null; } - } else { - return showResponse.statistics.sizeOnDisk - ? +showResponse.statistics.sizeOnDisk / 1048576 - : null; } - } - case 'tags': { - const tagIds = showResponse.tags; - return (await this.servarrService.SonarrApi.getTags()) - .filter((el) => tagIds.includes(el.id)) - .map((el) => el.label); - } - case 'qualityProfileId': { - if ([EPlexDataType.EPISODES].includes(dataType) && episodeFile) { - return episodeFile.quality.quality.id; - } else { - return showResponse.qualityProfileId; + case 'tags': { + const tagIds = showResponse.tags; + return (await this.servarrService.SonarrApi.getTags()) + .filter((el) => tagIds.includes(el.id)) + .map((el) => el.label); } - } - case 'firstAirDate': { - if ( - [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes(dataType) - ) { - return episode?.airDate ? new Date(episode.airDate) : null; - } else { - return showResponse.firstAired - ? new Date(showResponse.firstAired) - : null; + case 'qualityProfileId': { + if ([EPlexDataType.EPISODES].includes(dataType) && episodeFile) { + return episodeFile.quality.quality.id; + } else { + return showResponse.qualityProfileId; + } } - } - case 'seasons': { - if ( - [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes(dataType) - ) { - return season?.statistics?.episodeCount - ? +season.statistics.episodeCount - : null; - } else { - return showResponse.statistics.seasonCount - ? +showResponse.statistics.seasonCount - : null; + case 'firstAirDate': { + if ( + [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes( + dataType, + ) + ) { + return episode?.airDate ? new Date(episode.airDate) : null; + } else { + return showResponse.firstAired + ? new Date(showResponse.firstAired) + : null; + } } - } - case 'status': { - return showResponse.status ? showResponse.status : null; - } - case 'ended': { - return showResponse.ended !== undefined - ? showResponse.ended - ? 1 - : 0 - : null; - } - case 'monitored': { - if (dataType === EPlexDataType.SEASONS) { - return showResponse.added !== '0001-01-01T00:00:00Z' && season - ? season.monitored + case 'seasons': { + if ( + [EPlexDataType.SEASONS, EPlexDataType.EPISODES].includes( + dataType, + ) + ) { + return season?.statistics?.episodeCount + ? +season.statistics.episodeCount + : null; + } else { + return showResponse.statistics.seasonCount + ? +showResponse.statistics.seasonCount + : null; + } + } + case 'status': { + return showResponse.status ? showResponse.status : null; + } + case 'ended': { + return showResponse.ended !== undefined + ? showResponse.ended ? 1 : 0 : null; } + case 'monitored': { + if (dataType === EPlexDataType.SEASONS) { + return showResponse.added !== '0001-01-01T00:00:00Z' && season + ? season.monitored + ? 1 + : 0 + : null; + } - if (dataType === EPlexDataType.EPISODES) { - return showResponse.added !== '0001-01-01T00:00:00Z' && episode - ? episode.monitored + if (dataType === EPlexDataType.EPISODES) { + return showResponse.added !== '0001-01-01T00:00:00Z' && episode + ? episode.monitored + ? 1 + : 0 + : null; + } + + return showResponse.added !== '0001-01-01T00:00:00Z' + ? showResponse.monitored ? 1 : 0 : null; } - - return showResponse.added !== '0001-01-01T00:00:00Z' - ? showResponse.monitored - ? 1 - : 0 - : null; } - } - } else return null; + } else return null; + } else { + return undefined; + } } catch (e) { this.logger.warn(`Sonarr-Getter - Action failed : ${e.message}`); return undefined; } } + + public async findTvdbidFromPlexLibItem(libItem: PlexLibraryItem) { + let tvdbid = this.getGuidFromPlexLibItem(libItem, 'tvdb'); + if (!tvdbid) { + const plexMetaData = await this.plexApi.getMetadata(libItem.ratingKey); + tvdbid = this.getGuidFromPlexLibItem(plexMetaData, 'tvdb'); + if (!tvdbid) { + const resp = await this.tmdbIdHelper.getTmdbIdFromPlexData(libItem); + const tmdb = resp?.id ? resp.id : undefined; + if (tmdb) { + const tmdbShow = await this.tmdbApi.getTvShow({ tvId: tmdb }); + if (tmdbShow?.external_ids?.tvdb_id) { + tvdbid = tmdbShow.external_ids.tvdb_id; + } + } + } + } + + if (!tvdbid) { + console.warn( + `Couldn't find tvdb id for '${libItem.title}', can not run Sonarr rules against this item`, + ); + } + return tvdbid; + } + + private getGuidFromPlexLibItem( + libItem: PlexLibraryItem | PlexMetadata, + guiID: 'tvdb' | 'imdb' | 'tmdb', + ) { + return libItem.Guid + ? +libItem.Guid.find((el) => el.id.includes(guiID))?.id?.split('://')[1] + : libItem.guid.includes(guiID) + ? +libItem.guid.split('://')[1].split('?')[0] + : undefined; + } }