2021-02-24 06:42:58 +00:00
import logging , os , re , requests
from datetime import datetime , timedelta
2021-01-20 21:37:59 +00:00
from modules import util
from modules . util import Failed
from plexapi . exceptions import BadRequest , NotFound , Unauthorized
from plexapi . library import Collections , MovieSection , ShowSection
from plexapi . server import PlexServer
from plexapi . video import Movie , Show
from retrying import retry
from ruamel import yaml
logger = logging . getLogger ( " Plex Meta Manager " )
class PlexAPI :
2021-02-21 17:01:10 +00:00
def __init__ ( self , params , TMDb , TVDb ) :
2021-02-22 01:56:31 +00:00
try : self . PlexServer = PlexServer ( params [ " plex " ] [ " url " ] , params [ " plex " ] [ " token " ] , timeout = params [ " plex " ] [ " timeout " ] )
2021-01-20 21:37:59 +00:00
except Unauthorized : raise Failed ( " Plex Error: Plex token is invalid " )
2021-02-24 06:44:06 +00:00
except ValueError as e : raise Failed ( f " Plex Error: { e } " )
2021-02-24 06:42:58 +00:00
except requests . exceptions . ConnectionError :
2021-01-20 21:37:59 +00:00
util . print_stacktrace ( )
raise Failed ( " Plex Error: Plex url is invalid " )
self . is_movie = params [ " library_type " ] == " movie "
self . is_show = params [ " library_type " ] == " show "
self . Plex = next ( ( s for s in self . PlexServer . library . sections ( ) if s . title == params [ " name " ] and ( ( self . is_movie and isinstance ( s , MovieSection ) ) or ( self . is_show and isinstance ( s , ShowSection ) ) ) ) , None )
2021-02-24 06:44:06 +00:00
if not self . Plex : raise Failed ( f " Plex Error: Plex Library { params [ ' name ' ] } not found " )
2021-01-20 21:37:59 +00:00
try : self . data , ind , bsi = yaml . util . load_yaml_guess_indent ( open ( params [ " metadata_path " ] , encoding = " utf-8 " ) )
2021-02-24 06:44:06 +00:00
except yaml . scanner . ScannerError as e : raise Failed ( f " YAML Error: { util . tab_new_lines ( e ) } " )
2021-01-20 21:37:59 +00:00
2021-02-20 05:41:45 +00:00
def get_dict ( attribute ) :
if attribute in self . data :
if self . data [ attribute ] :
if isinstance ( self . data [ attribute ] , dict ) : return self . data [ attribute ]
2021-02-24 06:44:06 +00:00
else : logger . warning ( f " Config Warning: { attribute } must be a dictionary " )
else : logger . warning ( f " Config Warning: { attribute } attribute is blank " )
2021-02-20 05:41:45 +00:00
return None
self . metadata = get_dict ( " metadata " )
self . templates = get_dict ( " templates " )
self . collections = get_dict ( " collections " )
2021-01-20 21:37:59 +00:00
if self . metadata is None and self . collections is None :
raise Failed ( " YAML Error: metadata attributes or collections attribute required " )
if params [ " asset_directory " ] :
2021-02-21 08:13:07 +00:00
for ad in params [ " asset_directory " ] :
2021-02-24 06:44:06 +00:00
logger . info ( f " Using Asset Directory: { ad } " )
2021-01-20 21:37:59 +00:00
2021-02-21 08:13:07 +00:00
self . TMDb = TMDb
self . TVDb = TVDb
2021-02-21 17:01:10 +00:00
self . Radarr = None
self . Sonarr = None
self . Tautulli = None
2021-01-20 21:37:59 +00:00
self . name = params [ " name " ]
2021-02-24 06:44:06 +00:00
self . missing_path = os . path . join ( os . path . dirname ( os . path . abspath ( params [ " metadata_path " ] ) ) , f " { os . path . splitext ( os . path . basename ( params [ ' metadata_path ' ] ) ) [ 0 ] } _missing.yml " )
2021-01-20 21:37:59 +00:00
self . metadata_path = params [ " metadata_path " ]
self . asset_directory = params [ " asset_directory " ]
self . sync_mode = params [ " sync_mode " ]
2021-02-13 05:26:40 +00:00
self . show_unmanaged = params [ " show_unmanaged " ]
self . show_filtered = params [ " show_filtered " ]
2021-02-20 06:41:40 +00:00
self . show_missing = params [ " show_missing " ]
self . save_missing = params [ " save_missing " ]
2021-01-20 21:37:59 +00:00
self . plex = params [ " plex " ]
2021-02-22 01:56:31 +00:00
self . timeout = params [ " plex " ] [ " timeout " ]
2021-02-16 21:51:38 +00:00
self . missing = { }
2021-01-20 21:37:59 +00:00
2021-02-21 17:01:10 +00:00
def add_Radarr ( self , Radarr ) :
self . Radarr = Radarr
def add_Sonarr ( self , Sonarr ) :
self . Sonarr = Sonarr
def add_Tautulli ( self , Tautulli ) :
self . Tautulli = Tautulli
2021-01-20 21:37:59 +00:00
@retry ( stop_max_attempt_number = 6 , wait_fixed = 10000 )
def search ( self , title , libtype = None , year = None ) :
if libtype is not None and year is not None : return self . Plex . search ( title = title , year = year , libtype = libtype )
elif libtype is not None : return self . Plex . search ( title = title , libtype = libtype )
elif year is not None : return self . Plex . search ( title = title , year = year )
else : return self . Plex . search ( title = title )
@retry ( stop_max_attempt_number = 6 , wait_fixed = 10000 )
def fetchItem ( self , data ) :
return self . PlexServer . fetchItem ( data )
@retry ( stop_max_attempt_number = 6 , wait_fixed = 10000 )
def server_search ( self , data ) :
return self . PlexServer . search ( data )
def get_all_collections ( self ) :
return self . Plex . search ( libtype = " collection " )
def get_collection ( self , data ) :
collection = util . choose_from_list ( self . search ( str ( data ) , libtype = " collection " ) , " collection " , str ( data ) , exact = True )
if collection : return collection
2021-02-24 06:44:06 +00:00
else : raise Failed ( f " Plex Error: Collection { data } not found " )
2021-01-20 21:37:59 +00:00
def validate_collections ( self , collections ) :
valid_collections = [ ]
for collection in collections :
try : valid_collections . append ( self . get_collection ( collection ) )
except Failed as e : logger . error ( e )
if len ( valid_collections ) == 0 :
2021-02-24 06:44:06 +00:00
raise Failed ( f " Collection Error: No valid Plex Collections in { collections } " )
2021-01-20 21:37:59 +00:00
return valid_collections
2021-02-16 21:51:38 +00:00
def add_missing ( self , collection , items , is_movie ) :
col_name = collection . encode ( " ascii " , " replace " ) . decode ( )
if col_name not in self . missing :
self . missing [ col_name ] = { }
section = " Movies Missing (TMDb IDs) " if is_movie else " Shows Missing (TVDb IDs) "
if section not in self . missing [ col_name ] :
self . missing [ col_name ] [ section ] = { }
for title , item_id in items :
self . missing [ col_name ] [ section ] [ int ( item_id ) ] = str ( title ) . encode ( " ascii " , " replace " ) . decode ( )
with open ( self . missing_path , " w " ) : pass
2021-01-20 21:37:59 +00:00
try :
2021-02-16 21:51:38 +00:00
yaml . round_trip_dump ( self . missing , open ( self . missing_path , " w " ) )
2021-01-20 21:37:59 +00:00
except yaml . scanner . ScannerError as e :
2021-02-24 06:44:06 +00:00
logger . error ( f " YAML Error: { util . tab_new_lines ( e ) } " )
2021-01-20 21:37:59 +00:00
2021-02-24 06:42:58 +00:00
def add_to_collection ( self , collection , items , filters , show_filtered , rating_key_map , movie_map , show_map ) :
2021-01-20 21:37:59 +00:00
name = collection . title if isinstance ( collection , Collections ) else collection
2021-01-26 06:25:05 +00:00
collection_items = collection . items ( ) if isinstance ( collection , Collections ) else [ ]
2021-01-20 21:37:59 +00:00
total = len ( items )
max_length = len ( str ( total ) )
length = 0
for i , item in enumerate ( items , 1 ) :
2021-02-20 05:41:45 +00:00
try :
current = self . fetchItem ( item . ratingKey if isinstance ( item , ( Movie , Show ) ) else int ( item ) )
2021-02-15 06:51:15 +00:00
except ( BadRequest , NotFound ) :
2021-02-24 06:44:06 +00:00
logger . error ( f " Plex Error: Item { item } not found " )
2021-02-15 06:51:15 +00:00
continue
2021-01-20 21:37:59 +00:00
match = True
if filters :
2021-02-24 06:44:06 +00:00
length = util . print_return ( length , f " Filtering { ( ' ' * ( max_length - len ( str ( i ) ) ) ) + str ( i ) } / { total } { current . title } " )
2021-01-20 21:37:59 +00:00
for f in filters :
modifier = f [ 0 ] [ - 4 : ]
method = util . filter_alias [ f [ 0 ] [ : - 4 ] ] if modifier in [ " .not " , " .lte " , " .gte " ] else util . filter_alias [ f [ 0 ] ]
if method == " max_age " :
threshold_date = datetime . now ( ) - timedelta ( days = f [ 1 ] )
attr = getattr ( current , " originallyAvailableAt " )
if attr is None or attr < threshold_date :
match = False
break
2021-02-12 15:37:04 +00:00
elif method == " original_language " :
2021-02-16 04:54:47 +00:00
terms = util . get_list ( f [ 1 ] , lower = True )
2021-02-12 15:37:04 +00:00
movie = None
for key , value in movie_map . items ( ) :
if current . ratingKey == value :
try :
movie = self . TMDb . get_movie ( key )
break
except Failed :
pass
if movie is None :
2021-02-24 06:44:06 +00:00
logger . warning ( f " Filter Error: No TMDb ID found for { current . title } " )
2021-02-12 15:37:04 +00:00
continue
if ( modifier == " .not " and movie . original_language in terms ) or ( modifier != " .not " and movie . original_language not in terms ) :
match = False
break
2021-01-20 21:37:59 +00:00
elif modifier in [ " .gte " , " .lte " ] :
if method == " originallyAvailableAt " :
threshold_date = datetime . strptime ( f [ 1 ] , " % m/ %d / % y " )
attr = getattr ( current , " originallyAvailableAt " )
if ( modifier == " .lte " and attr > threshold_date ) or ( modifier == " .gte " and attr < threshold_date ) :
match = False
break
elif method in [ " year " , " rating " ] :
attr = getattr ( current , method )
if ( modifier == " .lte " and attr > f [ 1 ] ) or ( modifier == " .gte " and attr < f [ 1 ] ) :
match = False
break
else :
2021-02-16 04:54:47 +00:00
terms = util . get_list ( f [ 1 ] )
2021-02-24 06:42:58 +00:00
attrs = [ ]
2021-01-20 21:37:59 +00:00
if method in [ " video_resolution " , " audio_language " , " subtitle_language " ] :
for media in current . media :
if method == " video_resolution " : attrs = [ media . videoResolution ]
for part in media . parts :
if method == " audio_language " : attrs = ( [ a . language for a in part . audioStreams ( ) ] )
if method == " subtitle_language " : attrs = ( [ s . language for s in part . subtitleStreams ( ) ] )
elif method in [ " contentRating " , " studio " , " year " , " rating " , " originallyAvailableAt " ] : attrs = [ str ( getattr ( current , method ) ) ]
elif method in [ " actors " , " countries " , " directors " , " genres " , " writers " , " collections " ] : attrs = [ getattr ( x , " tag " ) for x in getattr ( current , method ) ]
if ( not list ( set ( terms ) & set ( attrs ) ) and modifier != " .not " ) or ( list ( set ( terms ) & set ( attrs ) ) and modifier == " .not " ) :
match = False
break
2021-02-24 06:44:06 +00:00
length = util . print_return ( length , f " Filtering { ( ' ' * ( max_length - len ( str ( i ) ) ) ) + str ( i ) } / { total } { current . title } " )
2021-01-20 21:37:59 +00:00
if match :
2021-02-24 06:44:06 +00:00
util . print_end ( length , f " { name } Collection | { ' = ' if current in collection_items else ' + ' } | { current . title } " )
2021-02-24 06:42:58 +00:00
if current in collection_items : rating_key_map [ current . ratingKey ] = None
2021-01-20 21:37:59 +00:00
else : current . addCollection ( name )
2021-02-13 04:28:46 +00:00
elif show_filtered is True :
2021-02-24 06:44:06 +00:00
logger . info ( f " { name } Collection | X | { current . title } " )
media_type = f " { ' Movie ' if self . is_movie else ' Show ' } { ' s ' if total > 1 else ' ' } "
util . print_end ( length , f " { total } { media_type } Processed " )
2021-02-24 06:42:58 +00:00
return rating_key_map
2021-01-20 21:37:59 +00:00
2021-02-05 14:56:05 +00:00
def search_item ( self , data , year = None ) :
return util . choose_from_list ( self . search ( data , year = year ) , " movie " if self . is_movie else " show " , str ( data ) , exact = True )
2021-02-15 06:51:15 +00:00
def update_metadata ( self , TMDb , test ) :
2021-01-20 21:37:59 +00:00
logger . info ( " " )
2021-02-24 06:44:06 +00:00
util . separator ( f " { self . name } Library Metadata " )
2021-01-20 21:37:59 +00:00
logger . info ( " " )
if not self . metadata :
raise Failed ( " No metadata to edit " )
for m in self . metadata :
2021-02-15 06:51:15 +00:00
if test and ( " test " not in self . metadata [ m ] or self . metadata [ m ] [ " test " ] is not True ) :
continue
2021-01-20 21:37:59 +00:00
logger . info ( " " )
2021-02-24 06:42:58 +00:00
util . separator ( )
2021-01-20 21:37:59 +00:00
logger . info ( " " )
year = None
if " year " in self . metadata [ m ] :
2021-02-24 06:42:58 +00:00
now = datetime . now ( )
2021-01-20 21:37:59 +00:00
if self . metadata [ m ] [ " year " ] is None : logger . error ( " Metadata Error: year attribute is blank " )
elif not isinstance ( self . metadata [ m ] [ " year " ] , int ) : logger . error ( " Metadata Error: year attribute must be an integer " )
2021-02-24 06:44:06 +00:00
elif self . metadata [ m ] [ " year " ] not in range ( 1800 , now . year + 2 ) : logger . error ( f " Metadata Error: year attribute must be between 1800- { now . year + 1 } " )
2021-01-20 21:37:59 +00:00
else : year = self . metadata [ m ] [ " year " ]
2021-02-05 14:56:05 +00:00
title = m
if " title " in self . metadata [ m ] :
if self . metadata [ m ] [ " title " ] is None : logger . error ( " Metadata Error: title attribute is blank " )
else : title = self . metadata [ m ] [ " title " ]
item = self . search_item ( title , year = year )
if item is None :
2021-02-24 06:44:06 +00:00
item = self . search_item ( f " { title } (SUB) " , year = year )
2021-02-05 14:56:05 +00:00
if item is None and " alt_title " in self . metadata [ m ] :
if self . metadata [ m ] [ " alt_title " ] is None :
logger . error ( " Metadata Error: alt_title attribute is blank " )
else :
alt_title = self . metadata [ m ] [ " alt_title " ]
item = self . search_item ( alt_title , year = year )
if item is None :
2021-02-24 06:44:06 +00:00
logger . error ( f " Plex Error: Item { m } not found " )
logger . error ( f " Skipping { m } " )
2021-02-05 14:56:05 +00:00
continue
2021-02-24 06:44:06 +00:00
item_type = " Movie " if self . is_movie else " Show "
logger . info ( f " Updating { item_type } : { title } ... " )
2021-01-20 21:37:59 +00:00
2021-02-05 14:56:05 +00:00
tmdb_item = None
2021-01-20 21:37:59 +00:00
try :
2021-02-05 14:56:05 +00:00
if " tmdb_id " in self . metadata [ m ] :
if self . metadata [ m ] [ " tmdb_id " ] is None : logger . error ( " Metadata Error: tmdb_id attribute is blank " )
elif self . is_show : logger . error ( " Metadata Error: tmdb_id attribute only works with movie libraries " )
else : tmdb_item = TMDb . get_show ( util . regex_first_int ( self . metadata [ m ] [ " tmdb_id " ] , " Show " ) )
2021-01-20 21:37:59 +00:00
except Failed as e :
2021-02-05 14:56:05 +00:00
logger . error ( e )
originally_available = tmdb_item . first_air_date if tmdb_item else None
rating = tmdb_item . vote_average if tmdb_item else None
original_title = tmdb_item . original_name if tmdb_item and tmdb_item . original_name != tmdb_item . name else None
studio = tmdb_item . networks [ 0 ] . name if tmdb_item else None
tagline = tmdb_item . tagline if tmdb_item and len ( tmdb_item . tagline ) > 0 else None
summary = tmdb_item . overview if tmdb_item else None
2021-01-20 21:37:59 +00:00
edits = { }
2021-02-05 14:56:05 +00:00
def add_edit ( name , current , group , key = None , value = None ) :
2021-01-20 21:37:59 +00:00
if value or name in group :
if value or group [ name ] :
if key is None : key = name
if value is None : value = group [ name ]
2021-02-05 14:56:05 +00:00
if str ( current ) != str ( value ) :
2021-02-24 06:44:06 +00:00
edits [ f " { key } .value " ] = value
edits [ f " { key } .locked " ] = 1
2021-01-20 21:37:59 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . error ( f " Metadata Error: { name } attribute is blank " )
2021-02-05 14:56:05 +00:00
add_edit ( " title " , item . title , self . metadata [ m ] , value = title )
add_edit ( " sort_title " , item . titleSort , self . metadata [ m ] , key = " titleSort " )
add_edit ( " originally_available " , str ( item . originallyAvailableAt ) [ : - 9 ] , self . metadata [ m ] , key = " originallyAvailableAt " , value = originally_available )
add_edit ( " rating " , item . rating , self . metadata [ m ] , value = rating )
add_edit ( " content_rating " , item . contentRating , self . metadata [ m ] , key = " contentRating " )
2021-02-15 04:16:23 +00:00
item_original_title = item . originalTitle if self . is_movie else item . _data . attrib . get ( " originalTitle " )
add_edit ( " original_title " , item_original_title , self . metadata [ m ] , key = " originalTitle " , value = original_title )
2021-02-05 14:56:05 +00:00
add_edit ( " studio " , item . studio , self . metadata [ m ] , value = studio )
2021-02-15 04:16:23 +00:00
item_tagline = item . tagline if self . is_movie else item . _data . attrib . get ( " tagline " )
add_edit ( " tagline " , item_tagline , self . metadata [ m ] , value = tagline )
2021-02-05 14:56:05 +00:00
add_edit ( " summary " , item . summary , self . metadata [ m ] , value = summary )
if len ( edits ) > 0 :
2021-02-24 06:44:06 +00:00
logger . debug ( f " Details Update: { edits } " )
2021-02-05 14:56:05 +00:00
try :
item . edit ( * * edits )
item . reload ( )
2021-02-24 06:44:06 +00:00
logger . info ( f " { item_type } : { m } Details Update Successful " )
2021-02-05 14:56:05 +00:00
except BadRequest :
util . print_stacktrace ( )
2021-02-24 06:44:06 +00:00
logger . error ( f " { item_type } : { m } Details Update Failed " )
2021-02-05 14:56:05 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . info ( f " { item_type } : { m } Details Update Not Needed " )
2021-02-05 14:56:05 +00:00
genres = [ ]
if tmdb_item :
genres . extend ( [ genre . name for genre in tmdb_item . genres ] )
2021-01-20 21:37:59 +00:00
if " genre " in self . metadata [ m ] :
2021-02-05 14:56:05 +00:00
if self . metadata [ m ] [ " genre " ] : genres . extend ( util . get_list ( self . metadata [ m ] [ " genre " ] ) )
else : logger . error ( " Metadata Error: genre attribute is blank " )
if len ( genres ) > 0 :
item_genres = [ genre . tag for genre in item . genres ]
if " genre_sync_mode " in self . metadata [ m ] :
if self . metadata [ m ] [ " genre_sync_mode " ] is None : logger . error ( " Metadata Error: genre_sync_mode attribute is blank defaulting to append " )
elif self . metadata [ m ] [ " genre_sync_mode " ] not in [ " append " , " sync " ] : logger . error ( " Metadata Error: genre_sync_mode attribute must be either ' append ' or ' sync ' defaulting to append " )
elif self . metadata [ m ] [ " genre_sync_mode " ] == " sync " :
for genre in ( g for g in item_genres if g not in genres ) :
2021-01-20 21:37:59 +00:00
item . removeGenre ( genre )
2021-02-24 06:44:06 +00:00
logger . info ( f " Detail: Genre { genre } removed " )
2021-02-05 14:56:05 +00:00
for genre in ( g for g in genres if g not in item_genres ) :
item . addGenre ( genre )
2021-02-24 06:44:06 +00:00
logger . info ( f " Detail: Genre { genre } added " )
2021-01-20 21:37:59 +00:00
if " label " in self . metadata [ m ] :
if self . metadata [ m ] [ " label " ] :
2021-02-05 14:56:05 +00:00
item_labels = [ label . tag for label in item . labels ]
labels = util . get_list ( self . metadata [ m ] [ " label " ] )
2021-01-20 21:37:59 +00:00
if " label_sync_mode " in self . metadata [ m ] :
if self . metadata [ m ] [ " label_sync_mode " ] is None : logger . error ( " Metadata Error: label_sync_mode attribute is blank defaulting to append " )
elif self . metadata [ m ] [ " label_sync_mode " ] not in [ " append " , " sync " ] : logger . error ( " Metadata Error: label_sync_mode attribute must be either ' append ' or ' sync ' defaulting to append " )
2021-02-05 14:56:05 +00:00
elif self . metadata [ m ] [ " label_sync_mode " ] == " sync " :
2021-02-24 06:42:58 +00:00
for label in ( la for la in item_labels if la not in labels ) :
2021-02-05 14:56:05 +00:00
item . removeLabel ( label )
2021-02-24 06:44:06 +00:00
logger . info ( f " Detail: Label { label } removed " )
2021-02-24 06:42:58 +00:00
for label in ( la for la in labels if la not in item_labels ) :
2021-02-05 14:56:05 +00:00
item . addLabel ( label )
2021-02-24 06:44:06 +00:00
logger . info ( f " Detail: Label { label } added " )
2021-01-20 21:37:59 +00:00
else :
logger . error ( " Metadata Error: label attribute is blank " )
if " seasons " in self . metadata [ m ] and self . is_show :
if self . metadata [ m ] [ " seasons " ] :
for season_id in self . metadata [ m ] [ " seasons " ] :
logger . info ( " " )
2021-02-24 06:44:06 +00:00
logger . info ( f " Updating season { season_id } of { m } ... " )
2021-01-20 21:37:59 +00:00
if isinstance ( season_id , int ) :
try : season = item . season ( season_id )
2021-02-24 06:44:06 +00:00
except NotFound : logger . error ( f " Metadata Error: Season: { season_id } not found " )
2021-01-20 21:37:59 +00:00
else :
2021-02-05 14:56:05 +00:00
if " title " in self . metadata [ m ] [ " seasons " ] [ season_id ] and self . metadata [ m ] [ " seasons " ] [ season_id ] [ " title " ] :
title = self . metadata [ m ] [ " seasons " ] [ season_id ] [ " title " ]
else :
title = season . title
if " sub " in self . metadata [ m ] [ " seasons " ] [ season_id ] :
if self . metadata [ m ] [ " seasons " ] [ season_id ] [ " sub " ] is None :
logger . error ( " Metadata Error: sub attribute is blank " )
elif self . metadata [ m ] [ " seasons " ] [ season_id ] [ " sub " ] is True and " (SUB) " not in title :
2021-02-24 06:44:06 +00:00
title = f " { title } (SUB) "
2021-02-05 14:56:05 +00:00
elif self . metadata [ m ] [ " seasons " ] [ season_id ] [ " sub " ] is False and title . endswith ( " (SUB) " ) :
title = title [ : - 6 ]
else :
logger . error ( " Metadata Error: sub attribute must be True or False " )
2021-01-20 21:37:59 +00:00
edits = { }
2021-02-05 14:56:05 +00:00
add_edit ( " title " , season . title , self . metadata [ m ] [ " seasons " ] [ season_id ] , value = title )
add_edit ( " summary " , season . summary , self . metadata [ m ] [ " seasons " ] [ season_id ] )
if len ( edits ) > 0 :
2021-02-24 06:44:06 +00:00
logger . debug ( f " Season: { season_id } Details Update: { edits } " )
2021-02-05 14:56:05 +00:00
try :
season . edit ( * * edits )
season . reload ( )
2021-02-24 06:44:06 +00:00
logger . info ( f " Season: { season_id } Details Update Successful " )
2021-02-05 14:56:05 +00:00
except BadRequest :
util . print_stacktrace ( )
2021-02-24 06:44:06 +00:00
logger . error ( f " Season: { season_id } Details Update Failed " )
2021-02-05 14:56:05 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . info ( f " Season: { season_id } Details Update Not Needed " )
2021-01-20 21:37:59 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . error ( f " Metadata Error: Season: { season_id } invalid, it must be an integer " )
2021-01-20 21:37:59 +00:00
else :
logger . error ( " Metadata Error: seasons attribute is blank " )
if " episodes " in self . metadata [ m ] and self . is_show :
if self . metadata [ m ] [ " episodes " ] :
for episode_str in self . metadata [ m ] [ " episodes " ] :
logger . info ( " " )
2021-02-24 06:42:58 +00:00
match = re . search ( " [Ss] \\ d+[Ee] \\ d+ " , episode_str )
2021-01-20 21:37:59 +00:00
if match :
output = match . group ( 0 ) [ 1 : ] . split ( " E " if " E " in m . group ( 0 ) else " e " )
episode_id = int ( output [ 0 ] )
season_id = int ( output [ 1 ] )
2021-02-24 06:44:06 +00:00
logger . info ( f " Updating episode S { episode_id } E { season_id } of { m } ... " )
2021-01-20 21:37:59 +00:00
try : episode = item . episode ( season = season_id , episode = episode_id )
2021-02-24 06:44:06 +00:00
except NotFound : logger . error ( f " Metadata Error: episode { episode_id } of season { season_id } not found " )
2021-01-20 21:37:59 +00:00
else :
2021-02-05 14:56:05 +00:00
if " title " in self . metadata [ m ] [ " episodes " ] [ episode_str ] and self . metadata [ m ] [ " episodes " ] [ episode_str ] [ " title " ] :
title = self . metadata [ m ] [ " episodes " ] [ episode_str ] [ " title " ]
else :
title = episode . title
if " sub " in self . metadata [ m ] [ " episodes " ] [ episode_str ] :
if self . metadata [ m ] [ " episodes " ] [ episode_str ] [ " sub " ] is None :
logger . error ( " Metadata Error: sub attribute is blank " )
elif self . metadata [ m ] [ " episodes " ] [ episode_str ] [ " sub " ] is True and " (SUB) " not in title :
2021-02-24 06:44:06 +00:00
title = f " { title } (SUB) "
2021-02-05 14:56:05 +00:00
elif self . metadata [ m ] [ " episodes " ] [ episode_str ] [ " sub " ] is False and title . endswith ( " (SUB) " ) :
title = title [ : - 6 ]
else :
logger . error ( " Metadata Error: sub attribute must be True or False " )
2021-01-20 21:37:59 +00:00
edits = { }
2021-02-05 14:56:05 +00:00
add_edit ( " title " , episode . title , self . metadata [ m ] [ " episodes " ] [ episode_str ] , value = title )
add_edit ( " sort_title " , episode . titleSort , self . metadata [ m ] [ " episodes " ] [ episode_str ] , key = " titleSort " )
add_edit ( " rating " , episode . rating , self . metadata [ m ] [ " episodes " ] [ episode_str ] )
add_edit ( " originally_available " , str ( episode . originallyAvailableAt ) [ : - 9 ] , self . metadata [ m ] [ " episodes " ] [ episode_str ] , key = " originallyAvailableAt " )
add_edit ( " summary " , episode . summary , self . metadata [ m ] [ " episodes " ] [ episode_str ] )
if len ( edits ) > 0 :
2021-02-24 06:44:06 +00:00
logger . debug ( f " Season: { season_id } Episode: { episode_id } Details Update: { edits } " )
2021-02-05 14:56:05 +00:00
try :
episode . edit ( * * edits )
episode . reload ( )
2021-02-24 06:44:06 +00:00
logger . info (
f " Season: { season_id } Episode: { episode_id } Details Update Successful " )
2021-02-05 14:56:05 +00:00
except BadRequest :
util . print_stacktrace ( )
2021-02-24 06:44:06 +00:00
logger . error ( f " Season: { season_id } Episode: { episode_id } Details Update Failed " )
2021-02-05 14:56:05 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . info ( f " Season: { season_id } Episode: { episode_id } Details Update Not Needed " )
2021-01-20 21:37:59 +00:00
else :
2021-02-24 06:44:06 +00:00
logger . error ( f " Metadata Error: episode { episode_str } invalid must have S##E## format " )
2021-01-20 21:37:59 +00:00
else :
logger . error ( " Metadata Error: episodes attribute is blank " )