Skip to content

Commit

Permalink
fix(rules): Improved the tvdb ID fallback mechanism for Sonarr rule v…
Browse files Browse the repository at this point in the history
…alues in case the tvdb ID is missing from Plex
  • Loading branch information
jorenn92 committed Oct 24, 2023
1 parent ef191b3 commit abd3dc8
Showing 1 changed file with 157 additions and 110 deletions.
267 changes: 157 additions & 110 deletions server/src/modules/rules/getter/sonarr-getter.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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(
Expand Down Expand Up @@ -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;
}
}

0 comments on commit abd3dc8

Please sign in to comment.