@ -19,51 +19,65 @@ except (ModuleNotFoundError, ImportError):
print ( " Requirements Error: Requirements are not installed " )
print ( " Requirements Error: Requirements are not installed " )
sys . exit ( 0 )
sys . exit ( 0 )
default_dir = os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , " config " )
load_dotenv ( os . path . join ( default_dir , " .env " ) )
arguments = {
" config " : { " args " : " c " , " type " : " str " , " help " : " Run with desired *.yml file " } ,
" times " : { " args " : [ " t " , " time " ] , " type " : " str " , " default " : " 05:00 " , " help " : " Times to update each day use format HH:MM (Default: 05:00) (comma-separated list) " } ,
" run " : { " args " : " r " , " type " : " bool " , " help " : " Run without the scheduler " } ,
" tests " : { " args " : [ " rt " , " test " , " run-test " , " run-tests " ] , " type " : " bool " , " help " : " Run in debug mode with only collections that have test: true " } ,
" debug " : { " args " : " db " , " type " : " bool " , " help " : " Run with Debug Logs Reporting to the Command Window " } ,
" trace " : { " args " : " tr " , " type " : " bool " , " help " : " Run with extra Trace Debug Logs " } ,
" log-requests " : { " args " : [ " lr " , " log-request " ] , " type " : " bool " , " help " : " Run with all Requests printed " } ,
" timeout " : { " args " : " ti " , " type " : " int " , " default " : 180 , " help " : " PMM Global Timeout (Default: 180) " } ,
" collections-only " : { " args " : [ " co " , " collection-only " ] , " type " : " bool " , " help " : " Run only collection operations " } ,
" playlists-only " : { " args " : [ " po " , " playlist-only " ] , " type " : " bool " , " help " : " Run only playlist operations " } ,
" operations-only " : { " args " : [ " op " , " operation " , " operations " , " lo " , " library-only " , " libraries-only " , " operation-only " ] , " type " : " bool " , " help " : " Run only operations " } ,
" overlays-only " : { " args " : [ " ov " , " overlay " , " overlays " , " overlay-only " ] , " type " : " bool " , " help " : " Run only overlays " } ,
" run-collections " : { " args " : [ " rc " , " cl " , " collection " , " collections " , " run-collection " ] , " type " : " str " , " help " : " Process only specified collections (pipe-separated list ' | ' ) " } ,
" run-libraries " : { " args " : [ " rl " , " l " , " library " , " libraries " , " run-library " ] , " type " : " str " , " help " : " Process only specified libraries (pipe-separated list ' | ' ) " } ,
" run-metadata-files " : { " args " : [ " rm " , " m " , " metadata " , " metadata-files " ] , " type " : " str " , " help " : " Process only specified Metadata files (pipe-separated list ' | ' ) " } ,
" libraries-first " : { " args " : [ " lf " , " library-first " ] , " type " : " bool " , " help " : " Run library operations before collections " } ,
" ignore-schedules " : { " args " : " is " , " type " : " bool " , " help " : " Run ignoring collection schedules " } ,
" ignore-ghost " : { " args " : " ig " , " type " : " bool " , " help " : " Run ignoring ghost logging " } ,
" cache-libraries " : { " args " : [ " ca " , " cache-library " ] , " type " : " bool " , " help " : " Cache Library load for 1 day " } ,
" delete-collections " : { " args " : [ " dc " , " delete " , " delete-collection " ] , " type " : " bool " , " help " : " Deletes all Collections in the Plex Library before running " } ,
" delete-labels " : { " args " : [ " dl " , " delete-label " ] , " type " : " bool " , " help " : " Deletes all Labels in the Plex Library before running " } ,
" resume " : { " args " : " re " , " type " : " str " , " help " : " Resume collection run from a specific collection " } ,
" no-countdown " : { " args " : " nc " , " type " : " bool " , " help " : " Run without displaying the countdown " } ,
" no-missing " : { " args " : " nm " , " type " : " bool " , " help " : " Run without running the missing section " } ,
" no-report " : { " args " : " nr " , " type " : " bool " , " help " : " Run without saving a report " } ,
" read-only-config " : { " args " : " ro " , " type " : " bool " , " help " : " Run without writing to the config " } ,
" divider " : { " args " : " d " , " type " : " str " , " default " : " = " , " help " : " Character that divides the sections (Default: ' = ' ) " } ,
" width " : { " args " : " w " , " type " : " int " , " default " : 100 , " help " : " Screen Width (Default: 100) " } ,
}
parser = argparse . ArgumentParser ( )
parser = argparse . ArgumentParser ( )
parser . add_argument ( " -db " , " --debug " , dest = " debug " , help = " Run with Debug Logs Reporting to the Command Window " , action = " store_true " , default = False )
for arg_key , arg_data in arguments . items ( ) :
parser . add_argument ( " -tr " , " --trace " , dest = " trace " , help = " Run with extra Trace Debug Logs " , action = " store_true " , default = False )
temp_args = arg_data [ " args " ] if isinstance ( arg_data [ " args " ] , list ) else [ arg_data [ " args " ] ]
parser . add_argument ( " -lr " , " --log-request " , " --log-requests " , dest = " log_requests " , help = " Run with all Requests printed " , action = " store_true " , default = False )
args = [ f " -- { arg_key } " ] + [ f " -- { a } " if len ( a ) > 2 else f " - { a } " for a in temp_args ]
parser . add_argument ( " -c " , " --config " , dest = " config " , help = " Run with desired *.yml file " , type = str )
kwargs = { " dest " : arg_key . replace ( " - " , " _ " ) , " help " : arg_data [ " help " ] }
parser . add_argument ( " -t " , " --time " , " --times " , dest = " times " , help = " Times to update each day use format HH:MM (Default: 05:00) (comma-separated list) " , default = " 05:00 " , type = str )
if arg_data [ " type " ] == " bool " :
parser . add_argument ( " -ti " , " --timeout " , dest = " timeout " , help = " PMM Global Timeout (Default: 180) " , default = 180 , type = int )
kwargs [ " action " ] = " store_true "
parser . add_argument ( " -re " , " --resume " , dest = " resume " , help = " Resume collection run from a specific collection " , type = str )
kwargs [ " default " ] = False
parser . add_argument ( " -r " , " --run " , dest = " run " , help = " Run without the scheduler " , action = " store_true " , default = False )
else :
parser . add_argument ( " -is " , " --ignore-schedules " , dest = " ignore_schedules " , help = " Run ignoring collection schedules " , action = " store_true " , default = False )
kwargs [ " type " ] = int if arg_data [ " type " ] == " int " else str
parser . add_argument ( " -ig " , " --ignore-ghost " , dest = " ignore_ghost " , help = " Run ignoring ghost logging " , action = " store_true " , default = False )
parser . add_argument ( " -rt " , " --test " , " --tests " , " --run-test " , " --run-tests " , dest = " test " , help = " Run in debug mode with only collections that have test: true " , action = " store_true " , default = False )
if " default " in arg_data :
parser . add_argument ( " -co " , " --collection-only " , " --collections-only " , dest = " collection_only " , help = " Run only collection operations " , action = " store_true " , default = False )
kwargs [ " default " ] = arg_data [ " default " ]
parser . add_argument ( " -po " , " --playlist-only " , " --playlists-only " , dest = " playlist_only " , help = " Run only playlist operations " , action = " store_true " , default = False )
parser . add_argument ( " -op " , " --operation " , " --operations " , " -lo " , " --library-only " , " --libraries-only " , " --operation-only " , " --operations-only " , dest = " operations " , help = " Run only operations " , action = " store_true " , default = False )
parser . add_argument ( * args , * * kwargs )
parser . add_argument ( " -ov " , " --overlay " , " --overlays " , " --overlay-only " , " --overlays-only " , dest = " overlays " , help = " Run only overlays " , action = " store_true " , default = False )
parser . add_argument ( " -lf " , " --library-first " , " --libraries-first " , dest = " library_first " , help = " Run library operations before collections " , action = " store_true " , default = False )
parser . add_argument ( " -rc " , " -cl " , " --collection " , " --collections " , " --run-collection " , " --run-collections " , dest = " collections " , help = " Process only specified collections (pipe-separated list ' | ' ) " , type = str )
parser . add_argument ( " -rl " , " -l " , " --library " , " --libraries " , " --run-library " , " --run-libraries " , dest = " libraries " , help = " Process only specified libraries (pipe-separated list ' | ' ) " , type = str )
parser . add_argument ( " -rm " , " -m " , " --metadata " , " --metadata-files " , " --run-metadata-files " , dest = " metadata " , help = " Process only specified Metadata files (pipe-separated list ' | ' ) " , type = str )
parser . add_argument ( " -ca " , " --cache-library " , " --cache-libraries " , dest = " cache_libraries " , help = " Cache Library load for 1 day " , action = " store_true " , default = False )
parser . add_argument ( " -dc " , " --delete " , " --delete-collections " , dest = " delete_collections " , help = " Deletes all Collections in the Plex Library before running " , action = " store_true " , default = False )
parser . add_argument ( " -dl " , " --delete-label " , " --delete-labels " , dest = " delete_labels " , help = " Deletes all Labels in the Plex Library before running " , action = " store_true " , default = False )
parser . add_argument ( " -nc " , " --no-countdown " , dest = " no_countdown " , help = " Run without displaying the countdown " , action = " store_true " , default = False )
parser . add_argument ( " -nm " , " --no-missing " , dest = " no_missing " , help = " Run without running the missing section " , action = " store_true " , default = False )
parser . add_argument ( " -nr " , " --no-report " , dest = " no_report " , help = " Run without saving a report " , action = " store_true " , default = False )
parser . add_argument ( " -ro " , " --read-only-config " , dest = " read_only_config " , help = " Run without writing to the config " , action = " store_true " , default = False )
parser . add_argument ( " -d " , " --divider " , dest = " divider " , help = " Character that divides the sections (Default: ' = ' ) " , default = " = " , type = str )
parser . add_argument ( " -w " , " --width " , dest = " width " , help = " Screen Width (Default: 100) " , default = 100 , type = int )
args , unknown = parser . parse_known_args ( )
args , unknown = parser . parse_known_args ( )
default_dir = os . path . join ( os . path . dirname ( os . path . abspath ( __file__ ) ) , " config " )
load_dotenv ( os . path . join ( default_dir , " .env " ) )
static_envs = [ ]
def get_env ( env_str , default , arg_bool = False , arg_int = False ) :
test_value = None
def get_arg ( env_str , default , arg_bool = False , arg_int = False ) :
global test_value
env_vars = [ env_str ] if not isinstance ( env_str , list ) else env_str
env_vars = [ env_str ] if not isinstance ( env_str , list ) else env_str
final_value = None
final_value = None
static_envs . extend ( env_vars )
static_envs . extend ( env_vars )
for env_var in env_vars :
for env_var in env_vars :
env_value = os . environ . get ( env_var )
env_value = os . environ . get ( env_var )
if env_var == " BRANCH_NAME " :
test_value = env_value
if env_value is not None :
if env_value is not None :
final_value = env_value
final_value = env_value
break
break
@ -84,45 +98,18 @@ def get_arg(env_str, default, arg_bool=False, arg_int=False):
return str ( final_value )
return str ( final_value )
else :
else :
return default
return default
try :
from git import Repo , InvalidGitRepositoryError
try :
static_envs = [ ]
git_branch = Repo ( path = " . " ) . head . ref . name # noqa
run_args = { }
except InvalidGitRepositoryError :
for arg_key , arg_data in arguments . items ( ) :
git_branch = None
temp_args = arg_data [ " args " ] if isinstance ( arg_data [ " args " ] , list ) else [ arg_data [ " args " ] ]
except ImportError :
final_vars = [ f " PMM_ { arg_key . replace ( ' - ' , ' _ ' ) . upper ( ) } " ] + [ f " PMM_ { a . replace ( ' - ' , ' _ ' ) . upper ( ) } " for a in temp_args if len ( a ) > 2 ]
git_branch = None
run_args [ arg_key ] = get_env ( final_vars , getattr ( args , arg_key . replace ( " - " , " _ " ) ) , arg_bool = arg_data [ " type " ] == " bool " , arg_int = arg_data [ " type " ] == " int " )
env_version = get_arg ( " BRANCH_NAME " , " master " )
is_docker = get_arg ( " PMM_DOCKER " , False , arg_bool = True )
env_version = get_env ( " BRANCH_NAME " , " master " )
is_linuxserver = get_arg ( " PMM_LINUXSERVER " , False , arg_bool = True )
is_docker = get_env ( " PMM_DOCKER " , False , arg_bool = True )
config_file = get_arg ( " PMM_CONFIG " , args . config )
is_linuxserver = get_env ( " PMM_LINUXSERVER " , False , arg_bool = True )
times = get_arg ( " PMM_TIME " , args . times )
run = get_arg ( " PMM_RUN " , args . run , arg_bool = True )
test = get_arg ( " PMM_TEST " , args . test , arg_bool = True )
ignore_schedules = get_arg ( " PMM_IGNORE_SCHEDULES " , args . ignore_schedules , arg_bool = True )
ignore_ghost = get_arg ( " PMM_IGNORE_GHOST " , args . ignore_ghost , arg_bool = True )
collection_only = get_arg ( " PMM_COLLECTIONS_ONLY " , args . collection_only , arg_bool = True )
playlist_only = get_arg ( " PMM_PLAYLISTS_ONLY " , args . playlist_only , arg_bool = True )
operations_only = get_arg ( [ " PMM_OPERATIONS " , " PMM_OPERATIONS_ONLY " , " PMM_LIBRARIES_ONLY " ] , args . operations , arg_bool = True )
overlays_only = get_arg ( [ " PMM_OVERLAYS " , " PMM_OVERLAYS_ONLY " ] , args . overlays , arg_bool = True )
library_first = get_arg ( " PMM_LIBRARIES_FIRST " , args . library_first , arg_bool = True )
collections = get_arg ( " PMM_COLLECTIONS " , args . collections )
libraries = get_arg ( " PMM_LIBRARIES " , args . libraries )
metadata_files = get_arg ( " PMM_METADATA_FILES " , args . metadata )
cache_libraries = get_arg ( " PMM_CACHE_LIBRARIES " , args . cache_libraries , arg_bool = True )
delete_collections = get_arg ( " PMM_DELETE_COLLECTIONS " , args . delete_collections , arg_bool = True )
delete_labels = get_arg ( " PMM_DELETE_LABELS " , args . delete_labels , arg_bool = True )
resume = get_arg ( " PMM_RESUME " , args . resume )
no_countdown = get_arg ( " PMM_NO_COUNTDOWN " , args . no_countdown , arg_bool = True )
no_missing = get_arg ( " PMM_NO_MISSING " , args . no_missing , arg_bool = True )
no_report = get_arg ( " PMM_NO_REPORT " , args . no_report , arg_bool = True )
read_only_config = get_arg ( " PMM_READ_ONLY_CONFIG " , args . read_only_config , arg_bool = True )
divider = get_arg ( " PMM_DIVIDER " , args . divider )
screen_width = get_arg ( " PMM_WIDTH " , args . width , arg_int = True )
timeout = get_arg ( " PMM_TIMEOUT " , args . timeout , arg_int = True )
debug = get_arg ( " PMM_DEBUG " , args . debug , arg_bool = True )
trace = get_arg ( " PMM_TRACE " , args . trace , arg_bool = True )
log_requests = get_arg ( " PMM_LOG_REQUESTS " , args . log_requests , arg_bool = True )
secret_args = { }
secret_args = { }
plex_url = None
plex_url = None
@ -140,8 +127,8 @@ while i < len(unknown):
i + = 1
i + = 1
i + = 1
i + = 1
plex_url = get_ arg ( " PMM_PLEX_URL " , plex_url )
plex_url = get_ env ( " PMM_PLEX_URL " , plex_url )
plex_token = get_ arg ( " PMM_PLEX_TOKEN " , plex_token )
plex_token = get_ env ( " PMM_PLEX_TOKEN " , plex_token )
env_secrets = [ ]
env_secrets = [ ]
for env_name , env_data in os . environ . items ( ) :
for env_name , env_data in os . environ . items ( ) :
@ -153,23 +140,33 @@ for _, v in secret_args.items():
if v in run_arg :
if v in run_arg :
run_arg = run_arg . replace ( v , " (redacted) " )
run_arg = run_arg . replace ( v , " (redacted) " )
if collections :
try :
collection_only = True
from git import Repo , InvalidGitRepositoryError
try :
git_branch = Repo ( path = " . " ) . head . ref . name # noqa
except InvalidGitRepositoryError :
git_branch = None
except ImportError :
git_branch = None
if screen_width < 90 or screen_width > 300 :
if run_args [ " run-collections " ] :
print ( f " Argument Error: width argument invalid: { screen_width } must be an integer between 90 and 300 using the default 100 " )
run_args [ " collections-only " ] = True
screen_width = 100
if config_file and os . path . exists ( config_file ) :
if run_args [ " width " ] < 90 or run_args [ " width " ] > 300 :
default_dir = os . path . join ( os . path . dirname ( os . path . abspath ( config_file ) ) )
print ( f " Argument Error: width argument invalid: { run_args [ ' width ' ] } must be an integer between 90 and 300 using the default 100 " )
elif config_file and not os . path . exists ( config_file ) :
run_args [ " width " ] = 100
print ( f " Config Error: config not found at { os . path . abspath ( config_file ) } " )
if run_args [ " config " ] and os . path . exists ( run_args [ " config " ] ) :
default_dir = os . path . join ( os . path . dirname ( os . path . abspath ( run_args [ " config " ] ) ) )
elif run_args [ " config " ] and not os . path . exists ( run_args [ " config " ] ) :
print ( f " Config Error: config not found at { os . path . abspath ( run_args [ ' config ' ] ) } " )
sys . exit ( 0 )
sys . exit ( 0 )
elif not os . path . exists ( os . path . join ( default_dir , " config.yml " ) ) :
elif not os . path . exists ( os . path . join ( default_dir , " config.yml " ) ) :
print ( f " Config Error: config not found at { os . path . abspath ( default_dir ) } " )
print ( f " Config Error: config not found at { os . path . abspath ( default_dir ) } " )
sys . exit ( 0 )
sys . exit ( 0 )
logger = MyLogger ( " Plex Meta Manager " , default_dir , screen_width , divider [ 0 ] , ignore_ghost , test or debug , trace , log_requests )
logger = MyLogger ( " Plex Meta Manager " , default_dir , run_args [ " width " ] , run_args [ " divider " ] [ 0 ] , run_args [ " ignore-ghost " ] ,
run_args [ " tests " ] or run_args [ " debug " ] , run_args [ " trace " ] , run_args [ " log-requests " ] )
from modules import util
from modules import util
util . logger = logger
util . logger = logger
@ -189,7 +186,7 @@ old_send = requests.Session.send
def new_send ( * send_args , * * kwargs ) :
def new_send ( * send_args , * * kwargs ) :
if kwargs . get ( " timeout " , None ) is None :
if kwargs . get ( " timeout " , None ) is None :
kwargs [ " timeout " ] = timeout
kwargs [ " timeout " ] = run_args[ " timeout" ]
return old_send ( * send_args , * * kwargs )
return old_send ( * send_args , * * kwargs )
requests . Session . send = new_send
requests . Session . send = new_send
@ -244,7 +241,7 @@ def start(attrs):
logger . info ( f " Platform: { platform . platform ( ) } " )
logger . info ( f " Platform: { platform . platform ( ) } " )
logger . info ( f " Memory: { round ( psutil . virtual_memory ( ) . total / ( 1024.0 * * 3 ) ) } GB " )
logger . info ( f " Memory: { round ( psutil . virtual_memory ( ) . total / ( 1024.0 * * 3 ) ) } GB " )
if " time " in attrs and attrs [ " time " ] : start_type = f " { attrs [ ' time ' ] } "
if " time " in attrs and attrs [ " time " ] : start_type = f " { attrs [ ' time ' ] } "
elif " test " in attrs and attrs [ " test " ] : start_type = " Test "
elif run_args [ " tests " ] : start_type = " Test "
elif " collections " in attrs and attrs [ " collections " ] : start_type = " Collections "
elif " collections " in attrs and attrs [ " collections " ] : start_type = " Collections "
elif " libraries " in attrs and attrs [ " libraries " ] : start_type = " Libraries "
elif " libraries " in attrs and attrs [ " libraries " ] : start_type = " Libraries "
else : start_type = " "
else : start_type = " "
@ -252,45 +249,24 @@ def start(attrs):
if " time " not in attrs :
if " time " not in attrs :
attrs [ " time " ] = start_time . strftime ( " % H: % M " )
attrs [ " time " ] = start_time . strftime ( " % H: % M " )
attrs [ " time_obj " ] = start_time
attrs [ " time_obj " ] = start_time
attrs [ " read_only " ] = read_only_config
attrs [ " version " ] = version
attrs [ " version " ] = version
attrs [ " branch " ] = branch
attrs [ " branch " ] = branch
attrs [ " no_missing " ] = no_missing
attrs [ " config_file " ] = run_args [ " config " ]
attrs [ " no_report " ] = no_report
attrs [ " ignore_schedules " ] = run_args [ " ignore-schedules " ]
attrs [ " collection_only " ] = collection_only
attrs [ " read_only " ] = run_args [ " read-only-config " ]
attrs [ " playlist_only " ] = playlist_only
attrs [ " no_missing " ] = run_args [ " no-missing " ]
attrs [ " operations_only " ] = operations_only
attrs [ " no_report " ] = run_args [ " no-report " ]
attrs [ " overlays_only " ] = overlays_only
attrs [ " collection_only " ] = run_args [ " collections-only " ]
attrs [ " playlist_only " ] = run_args [ " playlists-only " ]
attrs [ " operations_only " ] = run_args [ " operations-only " ]
attrs [ " overlays_only " ] = run_args [ " overlays-only " ]
attrs [ " plex_url " ] = plex_url
attrs [ " plex_url " ] = plex_url
attrs [ " plex_token " ] = plex_token
attrs [ " plex_token " ] = plex_token
logger . separator ( debug = True )
logger . separator ( debug = True )
logger . debug ( f " Run Command: { run_arg } " )
logger . debug ( f " Run Command: { run_arg } " )
logger . debug ( f " --config (PMM_CONFIG): { config_file } " )
for akey , adata in arguments . items ( ) :
logger . debug ( f " --time (PMM_TIME): { times } " )
ext = ' " ' if adata [ " type " ] == " str " and run_args [ akey ] not in [ None , " None " ] else " "
logger . debug ( f " --run (PMM_RUN): { run } " )
logger . debug ( f " -- { akey } (PMM_ { akey . upper ( ) } ): { ext } { run_args [ akey ] } { ext } " )
logger . debug ( f " --run-tests (PMM_TEST): { test } " )
logger . debug ( f " --collections-only (PMM_COLLECTIONS_ONLY): { collection_only } " )
logger . debug ( f " --playlists-only (PMM_PLAYLISTS_ONLY): { playlist_only } " )
logger . debug ( f " --operations (PMM_OPERATIONS): { operations_only } " )
logger . debug ( f " --overlays (PMM_OVERLAYS): { overlays_only } " )
logger . debug ( f " --libraries-first (PMM_LIBRARIES_FIRST): { library_first } " )
logger . debug ( f " --run-collections (PMM_COLLECTIONS): { collections } " )
logger . debug ( f " --run-libraries (PMM_LIBRARIES): { libraries } " )
logger . debug ( f " --run-metadata-files (PMM_METADATA_FILES): { metadata_files } " )
logger . debug ( f " --ignore-schedules (PMM_IGNORE_SCHEDULES): { ignore_schedules } " )
logger . debug ( f " --ignore-ghost (PMM_IGNORE_GHOST): { ignore_ghost } " )
logger . debug ( f " --cache-libraries (PMM_CACHE_LIBRARIES): { cache_libraries } " )
logger . debug ( f " --delete-collections (PMM_DELETE_COLLECTIONS): { delete_collections } " )
logger . debug ( f " --delete-labels (PMM_DELETE_LABELS): { delete_labels } " )
logger . debug ( f " --resume (PMM_RESUME): { resume } " )
logger . debug ( f " --no-countdown (PMM_NO_COUNTDOWN): { no_countdown } " )
logger . debug ( f " --no-missing (PMM_NO_MISSING): { no_missing } " )
logger . debug ( f " --no-report (PMM_NO_REPORT): { no_report } " )
logger . debug ( f " --read-only-config (PMM_READ_ONLY_CONFIG): { read_only_config } " )
logger . debug ( f " --divider (PMM_DIVIDER): { divider } " )
logger . debug ( f " --width (PMM_WIDTH): { screen_width } " )
logger . debug ( f " --debug (PMM_DEBUG): { debug } " )
logger . debug ( f " --trace (PMM_TRACE): { trace } " )
logger . debug ( " " )
logger . debug ( " " )
if secret_args :
if secret_args :
logger . debug ( " PMM Secrets Read: " )
logger . debug ( " PMM Secrets Read: " )
@ -358,7 +334,7 @@ def run_config(config, stats):
playlist_status = { }
playlist_status = { }
playlist_stats = { }
playlist_stats = { }
if ( config . playlist_files or config . general [ " playlist_report " ] ) and not overlays_only and not operations_only and not collection_only and not config . requested_metadata_files :
if ( config . playlist_files or config . general [ " playlist_report " ] ) and not run_args[ " overlays-only " ] and not run_args [ " operations-only " ] and not run_args [ " collections-only " ] and not config . requested_metadata_files :
logger . add_playlists_handler ( )
logger . add_playlists_handler ( )
if config . playlist_files :
if config . playlist_files :
playlist_status , playlist_stats = run_playlists ( config )
playlist_status , playlist_stats = run_playlists ( config )
@ -383,7 +359,7 @@ def run_config(config, stats):
logger . remove_playlists_handler ( )
logger . remove_playlists_handler ( )
amount_added = 0
amount_added = 0
if not operations_only and not overlays_only and not playlist_only :
if not run_args[ " operations-only " ] and not run_args [ " overlays-only " ] and not run_args [ " playlists-only " ] :
has_run_again = False
has_run_again = False
for library in config . libraries :
for library in config . libraries :
if library . run_again :
if library . run_again :
@ -424,7 +400,7 @@ def run_config(config, stats):
logger . stacktrace ( )
logger . stacktrace ( )
logger . critical ( e )
logger . critical ( e )
if not collection_only and not overlays_only and not playlist_only :
if not run_args[ " collections-only " ] and not run_args [ " overlays-only " ] and not run_args [ " playlists-only " ] :
used_url = [ ]
used_url = [ ]
for library in config . libraries :
for library in config . libraries :
if library . url not in used_url :
if library . url not in used_url :
@ -540,7 +516,7 @@ def run_libraries(config):
logger . debug ( f " Optimize: { library . optimize } " )
logger . debug ( f " Optimize: { library . optimize } " )
logger . debug ( f " Timeout: { library . timeout } " )
logger . debug ( f " Timeout: { library . timeout } " )
if delete_collections and not playlist_only :
if run_args[ " delete-collections " ] and not run_args [ " playlists-only " ] :
time_start = datetime . now ( )
time_start = datetime . now ( )
logger . info ( " " )
logger . info ( " " )
logger . separator ( f " Deleting all Collections from the { library . name } Library " , space = False , border = False )
logger . separator ( f " Deleting all Collections from the { library . name } Library " , space = False , border = False )
@ -553,7 +529,7 @@ def run_libraries(config):
logger . error ( e )
logger . error ( e )
library_status [ library . name ] [ " All Collections Deleted " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
library_status [ library . name ] [ " All Collections Deleted " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
if delete_labels and not playlist_only :
if run_args[ " delete-labels " ] and not run_args [ " playlists-only " ] :
time_start = datetime . now ( )
time_start = datetime . now ( )
logger . info ( " " )
logger . info ( " " )
logger . separator ( f " Deleting all Labels from All items in the { library . name } Library " , space = False , border = False )
logger . separator ( f " Deleting all Labels from All items in the { library . name } Library " , space = False , border = False )
@ -579,7 +555,7 @@ def run_libraries(config):
expired = None
expired = None
if config . Cache :
if config . Cache :
list_key , expired = config . Cache . query_list_cache ( " library " , library . mapping_name , 1 )
list_key , expired = config . Cache . query_list_cache ( " library " , library . mapping_name , 1 )
if cache_libraries and list_key and expired is False :
if run_args[ " cache-libraries " ] and list_key and expired is False :
logger . info ( f " Library: { library . mapping_name } loaded from Cache " )
logger . info ( f " Library: { library . mapping_name } loaded from Cache " )
temp_items = config . Cache . query_list_ids ( list_key )
temp_items = config . Cache . query_list_ids ( list_key )
@ -587,7 +563,7 @@ def run_libraries(config):
temp_items = library . cache_items ( )
temp_items = library . cache_items ( )
if config . Cache and list_key :
if config . Cache and list_key :
config . Cache . delete_list_ids ( list_key )
config . Cache . delete_list_ids ( list_key )
if config . Cache and cache_libraries :
if config . Cache and run_args[ " cache-libraries " ] :
list_key = config . Cache . update_list_cache ( " library " , library . mapping_name , expired , 1 )
list_key = config . Cache . update_list_cache ( " library " , library . mapping_name , expired , 1 )
config . Cache . update_list_ids ( list_key , [ ( i . ratingKey , i . guid ) for i in temp_items ] )
config . Cache . update_list_ids ( list_key , [ ( i . ratingKey , i . guid ) for i in temp_items ] )
if not library . is_music :
if not library . is_music :
@ -598,16 +574,16 @@ def run_libraries(config):
library_status [ library . name ] [ " Library Loading and Mapping " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
library_status [ library . name ] [ " Library Loading and Mapping " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
def run_operations_and_overlays ( ) :
def run_operations_and_overlays ( ) :
if not test and not collection_only and not playlist_only and not config . requested_metadata_files :
if not run_args[ " tests " ] and not run_args [ " collections-only " ] and not run_args [ " playlists-only " ] and not config . requested_metadata_files :
if not overlays_only and library . library_operation :
if not run_args[ " overlays-only " ] and library . library_operation :
library_status [ library . name ] [ " Library Operations " ] = library . Operations . run_operations ( )
library_status [ library . name ] [ " Library Operations " ] = library . Operations . run_operations ( )
if not operations_only and ( library . overlay_files or library . remove_overlays ) :
if not run_args[ " operations-only " ] and ( library . overlay_files or library . remove_overlays ) :
library_status [ library . name ] [ " Library Overlays " ] = library . Overlays . run_overlays ( )
library_status [ library . name ] [ " Library Overlays " ] = library . Overlays . run_overlays ( )
if library_first :
if run_args[ " libraries-first " ] :
run_operations_and_overlays ( )
run_operations_and_overlays ( )
if not operations_only and not overlays_only and not playlist_only :
if not run_args[ " operations-only " ] and not run_args [ " overlays-only " ] and not run_args [ " playlists-only " ] :
time_start = datetime . now ( )
time_start = datetime . now ( )
for images in library . images_files :
for images in library . images_files :
images_name = images . get_file_name ( )
images_name = images . get_file_name ( )
@ -617,7 +593,7 @@ def run_libraries(config):
continue
continue
logger . info ( " " )
logger . info ( " " )
logger . separator ( f " Running { images_name } Images File \n { images . path } " )
logger . separator ( f " Running { images_name } Images File \n { images . path } " )
if not test and not resume and not collection_only :
if not run_args[ " tests" ] and not resume and not run_args[ " collections-only " ] :
try :
try :
images . update_metadata ( )
images . update_metadata ( )
except Failed as e :
except Failed as e :
@ -634,7 +610,7 @@ def run_libraries(config):
continue
continue
logger . info ( " " )
logger . info ( " " )
logger . separator ( f " Running { metadata_name } Metadata File \n { metadata . path } " )
logger . separator ( f " Running { metadata_name } Metadata File \n { metadata . path } " )
if not test and not resume and not collection_only :
if not run_args[ " tests" ] and not resume and not run_args[ " collections-only " ] :
try :
try :
metadata . update_metadata ( )
metadata . update_metadata ( )
except Failed as e :
except Failed as e :
@ -647,13 +623,13 @@ def run_libraries(config):
continue
continue
if collections_to_run :
if collections_to_run :
logger . info ( " " )
logger . info ( " " )
logger . separator ( f " { ' Test ' if test else ' ' } Collections " )
logger . separator ( f " { ' Test ' if run_args[ ' test' ] else ' ' } Collections " )
logger . remove_library_handler ( library . mapping_name )
logger . remove_library_handler ( library . mapping_name )
run_collection ( config , library , metadata , collections_to_run )
run_collection ( config , library , metadata , collections_to_run )
logger . re_add_library_handler ( library . mapping_name )
logger . re_add_library_handler ( library . mapping_name )
library_status [ library . name ] [ " Library Metadata Files " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
library_status [ library . name ] [ " Library Metadata Files " ] = str ( datetime . now ( ) - time_start ) . split ( ' . ' ) [ 0 ]
if not library_first :
if not run_args[ " libraries-first " ] :
run_operations_and_overlays ( )
run_operations_and_overlays ( )
logger . remove_library_handler ( library . mapping_name )
logger . remove_library_handler ( library . mapping_name )
@ -668,7 +644,7 @@ def run_collection(config, library, metadata, requested_collections):
logger . info ( " " )
logger . info ( " " )
for mapping_name , collection_attrs in requested_collections . items ( ) :
for mapping_name , collection_attrs in requested_collections . items ( ) :
collection_start = datetime . now ( )
collection_start = datetime . now ( )
if test and ( " test " not in collection_attrs or collection_attrs [ " test " ] is not True ) :
if run_args[ " tests" ] and ( " test " not in collection_attrs or collection_attrs [ " test " ] is not True ) :
no_template_test = True
no_template_test = True
if " template " in collection_attrs and collection_attrs [ " template " ] :
if " template " in collection_attrs and collection_attrs [ " template " ] :
for data_template in util . get_list ( collection_attrs [ " template " ] , split = False ) :
for data_template in util . get_list ( collection_attrs [ " template " ] , split = False ) :
@ -859,7 +835,7 @@ def run_playlists(config):
for playlist_file in config . playlist_files :
for playlist_file in config . playlist_files :
for mapping_name , playlist_attrs in playlist_file . playlists . items ( ) :
for mapping_name , playlist_attrs in playlist_file . playlists . items ( ) :
playlist_start = datetime . now ( )
playlist_start = datetime . now ( )
if test and ( " test " not in playlist_attrs or playlist_attrs [ " test " ] is not True ) :
if run_args[ " tests" ] and ( " test " not in playlist_attrs or playlist_attrs [ " test " ] is not True ) :
no_template_test = True
no_template_test = True
if " template " in playlist_attrs and playlist_attrs [ " template " ] :
if " template " in playlist_attrs and playlist_attrs [ " template " ] :
for data_template in util . get_list ( playlist_attrs [ " template " ] , split = False ) :
for data_template in util . get_list ( playlist_attrs [ " template " ] , split = False ) :
@ -1034,17 +1010,10 @@ def run_playlists(config):
if __name__ == " __main__ " :
if __name__ == " __main__ " :
try :
try :
if run or test or collections or libraries or metadata_files or resume :
if run_args [ " run " ] or run_args [ " tests " ] or run_args [ " run-collections " ] or run_args [ " run-libraries " ] or run_args [ " run-metadata-files " ] or run_args [ " resume " ] :
params = {
process ( { " collections " : run_args [ " run-collections " ] , " libraries " : run_args [ " run-libraries " ] , " metadata_files " : run_args [ " run-metadata-files " ] } )
" config_file " : config_file ,
" ignore_schedules " : ignore_schedules ,
" collections " : collections ,
" libraries " : libraries ,
" metadata_files " : metadata_files
}
process ( params )
else :
else :
times_to_run = util . get_list ( times)
times_to_run = util . get_list ( run_args [ " times " ] )
valid_times = [ ]
valid_times = [ ]
for time_to_run in times_to_run :
for time_to_run in times_to_run :
try :
try :
@ -1057,11 +1026,10 @@ if __name__ == "__main__":
else :
else :
raise Failed ( f " Argument Error: blank time argument " )
raise Failed ( f " Argument Error: blank time argument " )
for time_to_run in valid_times :
for time_to_run in valid_times :
params = { " config_file " : config_file , " ignore_schedules " : ignore_schedules , " time " : time_to_run }
schedule . every ( ) . day . at ( time_to_run ) . do ( process , { " time " : time_to_run } )
schedule . every ( ) . day . at ( time_to_run ) . do ( process , params )
while True :
while True :
schedule . run_pending ( )
schedule . run_pending ( )
if not no _countdown:
if not ru n_args[ " no- countdown" ] :
current_time = datetime . now ( ) . strftime ( " % H: % M " )
current_time = datetime . now ( ) . strftime ( " % H: % M " )
seconds = None
seconds = None
og_time_str = " "
og_time_str = " "