From 6b6bec4090324981590ba92336bdcdc28068a20e Mon Sep 17 00:00:00 2001 From: Brandon Date: Mon, 30 Jan 2023 21:59:50 -0500 Subject: [PATCH] fix: prevent season deletion in preference of setting season to unknown --- server/lib/availabilitySync.ts | 167 ++++++++++++++++------------- src/components/TitleCard/index.tsx | 2 +- 2 files changed, 94 insertions(+), 75 deletions(-) diff --git a/server/lib/availabilitySync.ts b/server/lib/availabilitySync.ts index d1d32207a4..cfd50ea925 100644 --- a/server/lib/availabilitySync.ts +++ b/server/lib/availabilitySync.ts @@ -60,7 +60,7 @@ class AvailabilitySync { //We can not delete media so if both versions do not exist, we will change both columns to unknown or null if (!mediaExists) { if ( - media.status !== MediaStatus.UNKNOWN && + media.status !== MediaStatus.UNKNOWN || media.status4k !== MediaStatus.UNKNOWN ) { const request = await requestRepository.find({ @@ -71,7 +71,9 @@ class AvailabilitySync { }); logger.debug( - `${media.tmdbId} does not exist in any of your media instances. We will change its status to unknown.`, + `${ + media.mediaType === 'tv' ? media.tvdbId : media.tmdbId + } does not exist in any of your media instances. We will change its status to unknown.`, { label: 'AvailabilitySync' } ); @@ -90,7 +92,6 @@ class AvailabilitySync { await requestRepository.remove(request); } - continue; } if (media.mediaType === 'tv') { @@ -98,67 +99,100 @@ class AvailabilitySync { const seasons = await seasonRepository.find({ where: [ { status: MediaStatus.AVAILABLE, media: { id: media.id } }, + { + status: MediaStatus.PARTIALLY_AVAILABLE, + media: { id: media.id }, + }, { status4k: MediaStatus.AVAILABLE, media: { id: media.id } }, + { + status4k: MediaStatus.PARTIALLY_AVAILABLE, + media: { id: media.id }, + }, ], }); let didDeleteSeasons = false; for (const season of seasons) { - const seasonExists = await this.seasonExists(media, season); - - if (!seasonExists) { - logger.debug( - `Removing season ${season.seasonNumber}, media id: ${media.tmdbId} because it doesn't appear in any library.`, - { label: 'AvailabilitySync' } + if ( + !mediaExists && + (season.status !== MediaStatus.UNKNOWN || + season.status4k !== MediaStatus.UNKNOWN) + ) { + await seasonRepository.update( + { id: season.id }, + { + status: MediaStatus.UNKNOWN, + status4k: MediaStatus.UNKNOWN, + } ); - - const seasonToBeDeleted = - await seasonRequestRepository.findOne({ - relations: { - request: { - media: true, + } else { + const seasonExists = await this.seasonExists(media, season); + + if (!seasonExists) { + logger.debug( + `Removing season ${season.seasonNumber}, media id: ${media.tvdbId} because it does not exist in any of your media instances.`, + { label: 'AvailabilitySync' } + ); + + if ( + season.status !== MediaStatus.UNKNOWN || + season.status4k !== MediaStatus.UNKNOWN + ) { + await seasonRepository.update( + { id: season.id }, + { + status: MediaStatus.UNKNOWN, + status4k: MediaStatus.UNKNOWN, + } + ); + } + + const seasonToBeDeleted = + await seasonRequestRepository.findOne({ + relations: { + request: { + media: true, + }, }, - }, - where: { - request: { - media: { - id: media.id, + where: { + request: { + media: { + id: media.id, + }, }, + seasonNumber: season.seasonNumber, }, - seasonNumber: season.seasonNumber, - }, - }); + }); - await seasonRepository.delete(season.id); + if (seasonToBeDeleted) { + await seasonRequestRepository.remove(seasonToBeDeleted); + } - if (seasonToBeDeleted) { - await seasonRequestRepository.remove(seasonToBeDeleted); + didDeleteSeasons = true; } - - didDeleteSeasons = true; } - } - - if (didDeleteSeasons) { - if ( - media.status === MediaStatus.AVAILABLE || - media.status4k === MediaStatus.AVAILABLE - ) { - logger.debug( - `Marking media id: ${media.tmdbId} as PARTIALLY_AVAILABLE because we deleted some of its seasons.`, - { label: 'AvailabilitySync' } - ); - - if (media.status === MediaStatus.AVAILABLE) { - await mediaRepository.update(media.id, { - status: MediaStatus.PARTIALLY_AVAILABLE, - }); - } - if (media.status4k === MediaStatus.AVAILABLE) { - await mediaRepository.update(media.id, { - status4k: MediaStatus.PARTIALLY_AVAILABLE, - }); + if (didDeleteSeasons) { + if ( + media.status === MediaStatus.AVAILABLE || + media.status4k === MediaStatus.AVAILABLE + ) { + logger.debug( + `Marking media id: ${media.tvdbId} as PARTIALLY_AVAILABLE because we deleted some of its seasons.`, + { label: 'AvailabilitySync' } + ); + + if (media.status === MediaStatus.AVAILABLE) { + await mediaRepository.update(media.id, { + status: MediaStatus.PARTIALLY_AVAILABLE, + }); + } + + if (media.status4k === MediaStatus.AVAILABLE) { + await mediaRepository.update(media.id, { + status4k: MediaStatus.PARTIALLY_AVAILABLE, + }); + } } } } @@ -198,20 +232,15 @@ class AvailabilitySync { { status4k: MediaStatus.PARTIALLY_AVAILABLE }, ]; - let mediaPage = await mediaRepository.find({ - where: whereOptions, - skip: offset, - take: pageSize, - }); + let mediaPage: Media[]; do { - yield mediaPage; - offset += pageSize; - mediaPage = await mediaRepository.find({ + yield (mediaPage = await mediaRepository.find({ where: whereOptions, skip: offset, take: pageSize, - }); + })); + offset += pageSize; } while (mediaPage.length > 0); } @@ -285,7 +314,6 @@ class AvailabilitySync { //check if both exist or if a single non-4k or 4k exists //if both do not exist we will return false - if (!server.is4k && !meta.id) { existsInRadarr = false; } @@ -309,7 +337,6 @@ class AvailabilitySync { //if only a single non-4k or 4k exists, then change entity columns accordingly //related media request will then be deleted - if (!existsInRadarr && existsInRadarr4k && !existsInPlex) { if (media.status !== MediaStatus.UNKNOWN) { this.mediaUpdater(media, false); @@ -353,7 +380,6 @@ class AvailabilitySync { //check if both exist or if a single non-4k or 4k exists //if both do not exist we will return false - if (!server.is4k && !meta.id) { existsInSonarr = false; } @@ -377,7 +403,6 @@ class AvailabilitySync { //if only a single non-4k or 4k exists, then change entity columns accordingly //related media request will then be deleted - if (!existsInSonarr && existsInSonarr4k && !existsInPlex) { if (media.status !== MediaStatus.UNKNOWN) { this.mediaUpdater(media, false); @@ -402,7 +427,7 @@ class AvailabilitySync { season: Season, seasonExistsInPlex: boolean, seasonExistsInPlex4k: boolean - ) { + ): Promise { if (!media.tvdbId) { return false; } @@ -470,7 +495,6 @@ class AvailabilitySync { //if season does not exist, we will change status to unknown and delete related season request //if parent media request is empty(all related seasons have been removed), parent is automatically deleted - if ( !seasonExistsInSonarr && seasonExistsInSonarr4k && @@ -491,7 +515,7 @@ class AvailabilitySync { if (media.status === MediaStatus.AVAILABLE) { logger.debug( - `Marking media id: ${media.tmdbId} as PARTIALLY_AVAILABLE because we deleted one of its seasons.`, + `Marking media id: ${media.tvdbId} as PARTIALLY_AVAILABLE because we deleted one of its seasons.`, { label: 'AvailabilitySync' } ); await mediaRepository.update(media.id, { @@ -521,7 +545,7 @@ class AvailabilitySync { if (media.status4k === MediaStatus.AVAILABLE) { logger.debug( - `Marking media id: ${media.tmdbId} as PARTIALLY_AVAILABLE because we deleted one of its seasons.`, + `Marking media id: ${media.tvdbId} as PARTIALLY_AVAILABLE because we deleted one of its seasons.`, { label: 'AvailabilitySync' } ); await mediaRepository.update(media.id, { @@ -546,7 +570,6 @@ class AvailabilitySync { let existsInPlex4k = false; //check each plex instance to see if media exists - try { if (ratingKey) { const meta = await this.plexClient?.getMetadata(ratingKey); @@ -566,16 +589,13 @@ class AvailabilitySync { throw ex; } } - - //base case for if both exist in plex - + //base case for if both media versions exist in plex if (existsInPlex && existsInPlex4k) { return true; } //we then check radarr or sonarr has that specific media. If not, then we will move to delete //if a non-4k or 4k version exists in at least one of the instances, we will only update that specific version - if (media.mediaType === 'movie') { const existsInRadarr = await this.mediaExistsInRadarr( media, @@ -584,7 +604,6 @@ class AvailabilitySync { ); //if true, media exists in at least one radarr or plex instance. - if (existsInRadarr) { logger.warn( `${media.tmdbId} exists in at least one radarr or plex instance. Media will be updated if set to available.`, @@ -605,10 +624,9 @@ class AvailabilitySync { ); //if true, media exists in at least one sonarr or plex instance. - if (existsInSonarr) { logger.warn( - `${media.tmdbId} exists in at least one sonarr or plex instance. Media will be updated if set to available.`, + `${media.tvdbId} exists in at least one sonarr or plex instance. Media will be updated if set to available.`, { label: 'AvailabilitySync', } @@ -658,6 +676,7 @@ class AvailabilitySync { } } + //base case for if both season versions exist in plex if (seasonExistsInPlex && seasonExistsInPlex4k) { return true; } diff --git a/src/components/TitleCard/index.tsx b/src/components/TitleCard/index.tsx index be5ad5fa84..e7211234d7 100644 --- a/src/components/TitleCard/index.tsx +++ b/src/components/TitleCard/index.tsx @@ -141,7 +141,7 @@ const TitleCard = ({ : intl.formatMessage(globalMessages.tvshow)} - {currentStatus && ( + {currentStatus && currentStatus !== MediaStatus.UNKNOWN && (