@@ -30,23 +30,24 @@ class AvailabilitySync {
3030 this . sonarrSeasonsCache = { } ;
3131 this . radarrServers = settings . radarr . filter ( ( server ) => server . syncEnabled ) ;
3232 this . sonarrServers = settings . sonarr . filter ( ( server ) => server . syncEnabled ) ;
33- await this . initPlexClient ( ) ;
3433
35- if ( ! this . plexClient ) {
36- return ;
37- }
34+ try {
35+ await this . initPlexClient ( ) ;
3836
39- logger . info ( `Starting availability sync...` , {
40- label : 'AvailabilitySync' ,
41- } ) ;
42- const mediaRepository = getRepository ( Media ) ;
43- const requestRepository = getRepository ( MediaRequest ) ;
44- const seasonRepository = getRepository ( Season ) ;
45- const seasonRequestRepository = getRepository ( SeasonRequest ) ;
37+ if ( ! this . plexClient ) {
38+ return ;
39+ }
4640
47- const pageSize = 50 ;
41+ logger . info ( `Starting availability sync...` , {
42+ label : 'AvailabilitySync' ,
43+ } ) ;
44+ const mediaRepository = getRepository ( Media ) ;
45+ const requestRepository = getRepository ( MediaRequest ) ;
46+ const seasonRepository = getRepository ( Season ) ;
47+ const seasonRequestRepository = getRepository ( SeasonRequest ) ;
48+
49+ const pageSize = 50 ;
4850
49- try {
5051 for await ( const media of this . loadAvailableMediaPaginated ( pageSize ) ) {
5152 if ( ! this . running ) {
5253 throw new Error ( 'Job aborted' ) ;
@@ -239,51 +240,60 @@ class AvailabilitySync {
239240
240241 const isTVType = media . mediaType === 'tv' ;
241242
242- const request = await requestRepository . findOne ( {
243- relations : {
244- media : true ,
245- } ,
246- where : { media : { id : media . id } , is4k : is4k ? true : false } ,
247- } ) ;
248-
249- logger . info (
250- `Media ID ${ media . id } does not exist in your ${ is4k ? '4k' : 'non-4k' } ${
251- isTVType ? 'Sonarr' : 'Radarr'
252- } and Plex instance. Status will be changed to unknown.`,
253- { label : 'AvailabilitySync' }
254- ) ;
255-
256- await mediaRepository . update (
257- media . id ,
258- is4k
259- ? {
260- status4k : MediaStatus . UNKNOWN ,
261- serviceId4k : null ,
262- externalServiceId4k : null ,
263- externalServiceSlug4k : null ,
264- ratingKey4k : null ,
265- }
266- : {
267- status : MediaStatus . UNKNOWN ,
268- serviceId : null ,
269- externalServiceId : null ,
270- externalServiceSlug : null ,
271- ratingKey : null ,
272- }
273- ) ;
243+ try {
244+ const request = await requestRepository . findOne ( {
245+ relations : {
246+ media : true ,
247+ } ,
248+ where : { media : { id : media . id } , is4k : is4k ? true : false } ,
249+ } ) ;
274250
275- if ( isTVType ) {
276- const seasonRepository = getRepository ( Season ) ;
251+ logger . info (
252+ `Media ID ${ media . id } does not exist in your ${
253+ is4k ? '4k' : 'non-4k'
254+ } ${
255+ isTVType ? 'Sonarr' : 'Radarr'
256+ } and Plex instance. Status will be changed to unknown.`,
257+ { label : 'AvailabilitySync' }
258+ ) ;
277259
278- await seasonRepository ? .update (
279- { media : { id : media . id } } ,
260+ await mediaRepository . update (
261+ media . id ,
280262 is4k
281- ? { status4k : MediaStatus . UNKNOWN }
282- : { status : MediaStatus . UNKNOWN }
263+ ? {
264+ status4k : MediaStatus . UNKNOWN ,
265+ serviceId4k : null ,
266+ externalServiceId4k : null ,
267+ externalServiceSlug4k : null ,
268+ ratingKey4k : null ,
269+ }
270+ : {
271+ status : MediaStatus . UNKNOWN ,
272+ serviceId : null ,
273+ externalServiceId : null ,
274+ externalServiceSlug : null ,
275+ ratingKey : null ,
276+ }
283277 ) ;
284- }
285278
286- await requestRepository . delete ( { id : request ?. id } ) ;
279+ if ( isTVType ) {
280+ const seasonRepository = getRepository ( Season ) ;
281+
282+ await seasonRepository ?. update (
283+ { media : { id : media . id } } ,
284+ is4k
285+ ? { status4k : MediaStatus . UNKNOWN }
286+ : { status : MediaStatus . UNKNOWN }
287+ ) ;
288+ }
289+
290+ await requestRepository . delete ( { id : request ?. id } ) ;
291+ } catch ( ex ) {
292+ logger . debug ( `Failure updating media ID ${ media . id } ` , {
293+ errorMessage : ex . message ,
294+ label : 'AvailabilitySync' ,
295+ } ) ;
296+ }
287297 }
288298
289299 private async mediaExistsInRadarr (
@@ -539,83 +549,90 @@ class AvailabilitySync {
539549 }
540550 }
541551
542- const seasonToBeDeleted = await seasonRequestRepository . findOne ( {
543- relations : {
544- request : {
545- media : true ,
552+ try {
553+ const seasonToBeDeleted = await seasonRequestRepository . findOne ( {
554+ relations : {
555+ request : {
556+ media : true ,
557+ } ,
546558 } ,
547- } ,
548- where : {
549- request : {
550- is4k : seasonExistsInSonarr ? true : false ,
551- media : {
552- id : media . id ,
559+ where : {
560+ request : {
561+ is4k : seasonExistsInSonarr ? true : false ,
562+ media : {
563+ id : media . id ,
564+ } ,
553565 } ,
566+ seasonNumber : season . seasonNumber ,
554567 } ,
555- seasonNumber : season . seasonNumber ,
556- } ,
557- } ) ;
558-
559- // If season does not exist, we will change status to unknown and delete related season request
560- // If parent media request is empty(all related seasons have been removed), parent is automatically deleted
561- if (
562- ! seasonExistsInSonarr &&
563- ( seasonExistsInSonarr4k || seasonExistsInPlex4k ) &&
564- ! seasonExistsInPlex
565- ) {
566- if ( season . status !== MediaStatus . UNKNOWN ) {
567- logger . info (
568- `Season ${ season . seasonNumber } , media ID ${ media . id } does not exist in your non-4k Sonarr and Plex instance. Status will be changed to unknown.` ,
569- { label : 'AvailabilitySync' }
570- ) ;
571- await seasonRepository . update ( season . id , {
572- status : MediaStatus . UNKNOWN ,
573- } ) ;
574-
575- if ( seasonToBeDeleted ) {
576- await seasonRequestRepository . remove ( seasonToBeDeleted ) ;
577- }
568+ } ) ;
578569
579- if ( media . status === MediaStatus . AVAILABLE ) {
570+ // If season does not exist, we will change status to unknown and delete related season request
571+ // If parent media request is empty(all related seasons have been removed), parent is automatically deleted
572+ if (
573+ ! seasonExistsInSonarr &&
574+ ( seasonExistsInSonarr4k || seasonExistsInPlex4k ) &&
575+ ! seasonExistsInPlex
576+ ) {
577+ if ( season . status !== MediaStatus . UNKNOWN ) {
580578 logger . info (
581- `Marking media ID ${ media . id } as PARTIALLY_AVAILABLE because season removal has occurred .` ,
579+ `Season ${ season . seasonNumber } , media ID ${ media . id } does not exist in your non-4k Sonarr and Plex instance. Status will be changed to unknown .` ,
582580 { label : 'AvailabilitySync' }
583581 ) ;
584- await mediaRepository . update ( media . id , {
585- status : MediaStatus . PARTIALLY_AVAILABLE ,
582+ await seasonRepository . update ( season . id , {
583+ status : MediaStatus . UNKNOWN ,
586584 } ) ;
587- }
588- }
589- }
590585
591- if (
592- ( seasonExistsInSonarr || seasonExistsInPlex ) &&
593- ! seasonExistsInSonarr4k &&
594- ! seasonExistsInPlex4k
595- ) {
596- if ( season . status4k !== MediaStatus . UNKNOWN ) {
597- logger . info (
598- `Season ${ season . seasonNumber } , media ID ${ media . id } does not exist in your 4k Sonarr and Plex instance. Status will be changed to unknown.` ,
599- { label : 'AvailabilitySync' }
600- ) ;
601- await seasonRepository . update ( season . id , {
602- status4k : MediaStatus . UNKNOWN ,
603- } ) ;
586+ if ( seasonToBeDeleted ) {
587+ await seasonRequestRepository . remove ( seasonToBeDeleted ) ;
588+ }
604589
605- if ( seasonToBeDeleted ) {
606- await seasonRequestRepository . remove ( seasonToBeDeleted ) ;
590+ if ( media . status === MediaStatus . AVAILABLE ) {
591+ logger . info (
592+ `Marking media ID ${ media . id } as PARTIALLY_AVAILABLE because season removal has occurred.` ,
593+ { label : 'AvailabilitySync' }
594+ ) ;
595+ await mediaRepository . update ( media . id , {
596+ status : MediaStatus . PARTIALLY_AVAILABLE ,
597+ } ) ;
598+ }
607599 }
600+ }
608601
609- if ( media . status4k === MediaStatus . AVAILABLE ) {
602+ if (
603+ ( seasonExistsInSonarr || seasonExistsInPlex ) &&
604+ ! seasonExistsInSonarr4k &&
605+ ! seasonExistsInPlex4k
606+ ) {
607+ if ( season . status4k !== MediaStatus . UNKNOWN ) {
610608 logger . info (
611- `Marking media ID ${ media . id } as PARTIALLY_AVAILABLE because season removal has occurred .` ,
609+ `Season ${ season . seasonNumber } , media ID ${ media . id } does not exist in your 4k Sonarr and Plex instance. Status will be changed to unknown .` ,
612610 { label : 'AvailabilitySync' }
613611 ) ;
614- await mediaRepository . update ( media . id , {
615- status4k : MediaStatus . PARTIALLY_AVAILABLE ,
612+ await seasonRepository . update ( season . id , {
613+ status4k : MediaStatus . UNKNOWN ,
616614 } ) ;
615+
616+ if ( seasonToBeDeleted ) {
617+ await seasonRequestRepository . remove ( seasonToBeDeleted ) ;
618+ }
619+
620+ if ( media . status4k === MediaStatus . AVAILABLE ) {
621+ logger . info (
622+ `Marking media ID ${ media . id } as PARTIALLY_AVAILABLE because season removal has occurred.` ,
623+ { label : 'AvailabilitySync' }
624+ ) ;
625+ await mediaRepository . update ( media . id , {
626+ status4k : MediaStatus . PARTIALLY_AVAILABLE ,
627+ } ) ;
628+ }
617629 }
618630 }
631+ } catch ( ex ) {
632+ logger . debug ( `Failure updating media ID ${ media . id } ` , {
633+ errorMessage : ex . message ,
634+ label : 'AvailabilitySync' ,
635+ } ) ;
619636 }
620637
621638 if (
@@ -654,7 +671,10 @@ class AvailabilitySync {
654671 }
655672 } catch ( ex ) {
656673 if ( ! ex . message . includes ( 'response code: 404' ) ) {
657- throw ex ;
674+ logger . debug ( `Failed to retrieve plex metadata` , {
675+ errorMessage : ex . message ,
676+ label : 'AvailabilitySync' ,
677+ } ) ;
658678 }
659679 }
660680 // Base case if both media versions exist in plex
@@ -714,36 +734,43 @@ class AvailabilitySync {
714734 let seasonExistsInPlex = false ;
715735 let seasonExistsInPlex4k = false ;
716736
717- if ( ratingKey ) {
718- const children =
719- this . plexSeasonsCache [ ratingKey ] ??
720- ( await this . plexClient ?. getChildrenMetadata ( ratingKey ) ) ??
721- [ ] ;
722- this . plexSeasonsCache [ ratingKey ] = children ;
723- const seasonMeta = children ?. find (
724- ( child ) => child . index === season . seasonNumber
725- ) ;
737+ try {
738+ if ( ratingKey ) {
739+ const children =
740+ this . plexSeasonsCache [ ratingKey ] ??
741+ ( await this . plexClient ?. getChildrenMetadata ( ratingKey ) ) ??
742+ [ ] ;
743+ this . plexSeasonsCache [ ratingKey ] = children ;
744+ const seasonMeta = children ?. find (
745+ ( child ) => child . index === season . seasonNumber
746+ ) ;
726747
727- if ( seasonMeta ) {
728- seasonExistsInPlex = true ;
748+ if ( seasonMeta ) {
749+ seasonExistsInPlex = true ;
750+ }
729751 }
730- }
731-
732- if ( ratingKey4k ) {
733- const children4k =
734- this . plexSeasonsCache [ ratingKey4k ] ??
735- ( await this . plexClient ?. getChildrenMetadata ( ratingKey4k ) ) ??
736- [ ] ;
737- this . plexSeasonsCache [ ratingKey4k ] = children4k ;
738- const seasonMeta4k = children4k ?. find (
739- ( child ) => child . index === season . seasonNumber
740- ) ;
752+ if ( ratingKey4k ) {
753+ const children4k =
754+ this . plexSeasonsCache [ ratingKey4k ] ??
755+ ( await this . plexClient ?. getChildrenMetadata ( ratingKey4k ) ) ??
756+ [ ] ;
757+ this . plexSeasonsCache [ ratingKey4k ] = children4k ;
758+ const seasonMeta4k = children4k ?. find (
759+ ( child ) => child . index === season . seasonNumber
760+ ) ;
741761
742- if ( seasonMeta4k ) {
743- seasonExistsInPlex4k = true ;
762+ if ( seasonMeta4k ) {
763+ seasonExistsInPlex4k = true ;
764+ }
765+ }
766+ } catch ( ex ) {
767+ if ( ! ex . message . includes ( 'response code: 404' ) ) {
768+ logger . debug ( `Failed to retrieve plex's children metadata` , {
769+ errorMessage : ex . message ,
770+ label : 'AvailabilitySync' ,
771+ } ) ;
744772 }
745773 }
746-
747774 // Base case if both season versions exist in plex
748775 if ( seasonExistsInPlex && seasonExistsInPlex4k ) {
749776 return true ;
0 commit comments