multiple asset location

This commit is contained in:
meisnate12 2021-02-21 03:13:07 -05:00
parent b2914546f0
commit 1b0973a8e8
5 changed files with 170 additions and 349 deletions

View file

@ -15,6 +15,8 @@ plex: # Can be individually specified pe
asset_directory: config/assets asset_directory: config/assets
show_unmanaged: true show_unmanaged: true
show_filtered: false show_filtered: false
show_missing: true
save_missing: true
radarr: # Can be individually specified per library as well radarr: # Can be individually specified per library as well
url: http://192.168.1.12:7878 url: http://192.168.1.12:7878
token: ################################ token: ################################

View file

@ -708,51 +708,27 @@ class CollectionBuilder:
if "name_mapping" in self.details: if "name_mapping" in self.details:
if self.details["name_mapping"]: name_mapping = self.details["name_mapping"] if self.details["name_mapping"]: name_mapping = self.details["name_mapping"]
else: logger.error("Collection Error: name_mapping attribute is blank") else: logger.error("Collection Error: name_mapping attribute is blank")
path = os.path.join(self.library.asset_directory, "{}".format(name_mapping), "poster.*") for ad in self.library.asset_directory:
matches = glob.glob(path) path = os.path.join(ad, "{}".format(name_mapping))
if len(matches) > 0: if not os.path.isdir(path):
for match in matches: continue
self.posters.append(("file", os.path.abspath(match), "asset_directory")) matches = glob.glob(os.path.join(ad, "{}".format(name_mapping), "poster.*"))
elif len(self.posters) == 0 and "poster" not in self.details: if len(matches) > 0:
logger.warning("poster not found at: {}".format(os.path.abspath(path))) for match in matches:
path = os.path.join(self.library.asset_directory, "{}".format(name_mapping), "background.*") self.posters.append(("file", os.path.abspath(match), "asset_directory"))
matches = glob.glob(path) matches = glob.glob(os.path.join(ad, "{}".format(name_mapping), "background.*"))
if len(matches) > 0: if len(matches) > 0:
for match in matches: for match in matches:
self.backgrounds.append(("file", os.path.abspath(match), "asset_directory")) self.backgrounds.append(("file", os.path.abspath(match), "asset_directory"))
elif len(self.backgrounds) == 0 and "background" not in self.details:
logger.warning("background not found at: {}".format(os.path.abspath(path)))
poster = util.choose_from_list(self.posters, "poster", list_type="tuple")
if not poster and "poster" in self.details: poster = self.details["poster"]
if poster:
if poster[0] == "url": collection.uploadPoster(url=poster[1])
else: collection.uploadPoster(filepath=poster[1])
logger.info("Detail: {} updated poster to [{}] {}".format(poster[2], poster[0], poster[1]))
background = util.choose_from_list(self.backgrounds, "background", list_type="tuple")
if not background and "background" in self.details: background = self.details["background"]
if background:
if background[0] == "url": collection.uploadArt(url=background[1])
else: collection.uploadArt(filepath=background[1])
logger.info("Detail: {} updated background to [{}] {}".format(background[2], background[0], background[1]))
if self.library.asset_directory:
path = os.path.join(self.library.asset_directory, "{}".format(name_mapping))
if os.path.isdir(path):
dirs = [folder for folder in os.listdir(path) if os.path.isdir(os.path.join(path, folder))] dirs = [folder for folder in os.listdir(path) if os.path.isdir(os.path.join(path, folder))]
if len(dirs) > 0: if len(dirs) > 0:
for item in collection.items(): for item in collection.items():
folder = os.path.basename(os.path.dirname(item.locations[0])) folder = os.path.basename(os.path.dirname(item.locations[0]))
if folder in dirs: if folder in dirs:
files = [file for file in os.listdir(os.path.join(path, folder)) if os.path.isfile(os.path.join(path, folder, file))] matches = glob.glob(os.path.join(path, folder, "poster.*"))
poster_path = None poster_path = os.path.abspath(matches[0]) if len(matches) > 0 else None
background_path = None matches = glob.glob(os.path.join(path, folder, "background.*"))
for file in files: background_path = os.path.abspath(matches[0]) if len(matches) > 0 else None
if poster_path is None and file.startswith("poster."):
poster_path = os.path.join(path, folder, file)
if background_path is None and file.startswith("background."):
background_path = os.path.join(path, folder, file)
if poster_path: if poster_path:
item.uploadPoster(filepath=poster_path) item.uploadPoster(filepath=poster_path)
logger.info("Detail: asset_directory updated {}'s poster to [file] {}".format(item.title, poster_path)) logger.info("Detail: asset_directory updated {}'s poster to [file] {}".format(item.title, poster_path))
@ -763,3 +739,17 @@ class CollectionBuilder:
logger.warning("No Files Found: {}".format(os.path.join(path, folder))) logger.warning("No Files Found: {}".format(os.path.join(path, folder)))
else: else:
logger.warning("No Folder: {}".format(os.path.join(path, folder))) logger.warning("No Folder: {}".format(os.path.join(path, folder)))
poster = util.choose_from_list(self.posters, "poster", list_type="tuple")
if not poster and "poster" in self.details: poster = self.details["poster"]
if poster:
if poster[0] == "url": collection.uploadPoster(url=poster[1])
else: collection.uploadPoster(filepath=poster[1])
logger.info("Detail: {} updated collection poster to [{}] {}".format(poster[2], poster[0], poster[1]))
background = util.choose_from_list(self.backgrounds, "background", list_type="tuple")
if not background and "background" in self.details: background = self.details["background"]
if background:
if background[0] == "url": collection.uploadArt(url=background[1])
else: collection.uploadArt(filepath=background[1])
logger.info("Detail: {} updated collection background to [{}] {}".format(background[2], background[0], background[1]))

View file

@ -4,9 +4,12 @@ from modules.anidb import AniDBAPI
from modules.builder import CollectionBuilder from modules.builder import CollectionBuilder
from modules.cache import Cache from modules.cache import Cache
from modules.imdb import IMDbAPI from modules.imdb import IMDbAPI
from modules.plex import PlexAPI
from modules.mal import MyAnimeListAPI from modules.mal import MyAnimeListAPI
from modules.mal import MyAnimeListIDList from modules.mal import MyAnimeListIDList
from modules.plex import PlexAPI
from modules.radarr import RadarrAPI
from modules.sonarr import SonarrAPI
from modules.tautulli import TautulliAPI
from modules.tmdb import TMDbAPI from modules.tmdb import TMDbAPI
from modules.trakt import TraktAPI from modules.trakt import TraktAPI
from modules.tvdb import TVDbAPI from modules.tvdb import TVDbAPI
@ -29,13 +32,19 @@ class Config:
try: self.data, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path)) try: self.data, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path))
except yaml.scanner.ScannerError as e: raise Failed("YAML Error: {}".format(str(e).replace("\n", "\n|\t "))) except yaml.scanner.ScannerError as e: raise Failed("YAML Error: {}".format(str(e).replace("\n", "\n|\t ")))
def check_for_attribute(data, attribute, parent=None, test_list=None, options="", default=None, do_print=True, default_is_none=False, var_type="str", throw=False, save=True): def check_for_attribute(data, attribute, parent=None, test_list=None, options="", default=None, do_print=True, default_is_none=False, req_default=False, var_type="str", throw=False, save=True):
message = "" message = ""
endline = "" endline = ""
data = data if parent is None else data[parent] if parent is not None:
if parent in data:
data = data[parent]
else:
data = None
do_print = False
save = False
text = "{} attribute".format(attribute) if parent is None else "{} sub-attribute {}".format(parent, attribute) text = "{} attribute".format(attribute) if parent is None else "{} sub-attribute {}".format(parent, attribute)
if data is None or attribute not in data: if data is None or attribute not in data:
message = "Config Error: {} not found".format(text) message = "{} not found".format(text)
if parent and save is True: if parent and save is True:
new_config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path)) new_config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path))
endline = "\n| {} sub-attribute {} added to config".format(parent, attribute) endline = "\n| {} sub-attribute {} added to config".format(parent, attribute)
@ -46,40 +55,47 @@ class Config:
yaml.round_trip_dump(new_config, open(self.config_path, "w"), indent=ind, block_seq_indent=bsi) yaml.round_trip_dump(new_config, open(self.config_path, "w"), indent=ind, block_seq_indent=bsi)
elif not data[attribute] and data[attribute] != False: elif not data[attribute] and data[attribute] != False:
if default_is_none is True: return None if default_is_none is True: return None
else: message = "Config Error: {} is blank".format(text) else: message = "{} is blank".format(text)
elif var_type == "bool": elif var_type == "bool":
if isinstance(data[attribute], bool): return data[attribute] if isinstance(data[attribute], bool): return data[attribute]
else: message = "Config Error: {} must be either true or false".format(text) else: message = "{} must be either true or false".format(text)
elif var_type == "int": elif var_type == "int":
if isinstance(data[attribute], int) and data[attribute] > 0: return data[attribute] if isinstance(data[attribute], int) and data[attribute] > 0: return data[attribute]
else: message = "Config Error: {} must an integer > 0".format(text) else: message = "{} must an integer > 0".format(text)
elif var_type == "path": elif var_type == "path":
if os.path.exists(os.path.abspath(data[attribute])): return data[attribute] if os.path.exists(os.path.abspath(data[attribute])): return data[attribute]
else: message = "Config Error: {} could not be found".format(text) else: message = "Path {} does not exist".format(os.path.abspath(data[attribute]))
if default and os.path.exists(os.path.abspath(default)): elif var_type == "list": return util.get_list(data[attribute])
return default elif var_type == "listpath":
elif default: temp_list = [path for path in util.get_list(data[attribute]) if os.path.exists(os.path.abspath(path))]
default = None if len(temp_list) > 0: return temp_list
default_is_none = True else: message = "No Paths exist"
message = "Config Error: neither {} or the default path {} could be found".format(data[attribute], default) elif var_type == "lowerlist": return util.get_list(data[attribute], lower=True)
elif test_list is None or data[attribute] in test_list: return data[attribute] elif test_list is None or data[attribute] in test_list: return data[attribute]
else: message = "Config Error: {}: {} is an invalid input".format(text, data[attribute]) else: message = "{}: {} is an invalid input".format(text, data[attribute])
if var_type == "path" and default and os.path.exists(os.path.abspath(default)):
return default
elif var_type == "path" and default:
default = None
message = "neither {} or the default path {} could be found".format(data[attribute], default)
if default is not None or default_is_none: if default is not None or default_is_none:
message = message + " using {} as default".format(default) message = message + " using {} as default".format(default)
message = message + endline message = message + endline
if req_default and default is None:
raise Failed("{} attribute must be set under {} globally or under this specific Library".format(attribute, parent))
if (default is None and not default_is_none) or throw: if (default is None and not default_is_none) or throw:
if len(options) > 0: if len(options) > 0:
message = message + "\n" + options message = message + "\n" + options
raise Failed(message) raise Failed(message)
if do_print: if do_print:
util.print_multiline(message) util.print_multiline("Config Warning: {}".format(message))
if attribute in data and data[attribute] and test_list is not None and data[attribute] not in test_list: if attribute in data and data[attribute] and test_list is not None and data[attribute] not in test_list:
util.print_multiline(options) util.print_multiline(options)
return default return default
self.general = {} self.general = {}
self.general["cache"] = check_for_attribute(self.data, "cache", parent="cache", options="| \ttrue (Create a cache to store ids)\n| \tfalse (Do not create a cache to store ids)", var_type="bool", default=True) if "cache" in self.data else True self.general["cache"] = check_for_attribute(self.data, "cache", parent="cache", options=" true (Create a cache to store ids)\n false (Do not create a cache to store ids)", var_type="bool", default=True)
self.general["cache_expiration"] = check_for_attribute(self.data, "cache_expiration", parent="cache", var_type="int", default=60) if "cache" in self.data else 60 self.general["cache_expiration"] = check_for_attribute(self.data, "cache_expiration", parent="cache", var_type="int", default=60)
if self.general["cache"]: if self.general["cache"]:
util.seperator() util.seperator()
self.Cache = Cache(self.config_path, self.general["cache_expiration"]) self.Cache = Cache(self.config_path, self.general["cache_expiration"])
@ -92,7 +108,8 @@ class Config:
if "tmdb" in self.data: if "tmdb" in self.data:
logger.info("Connecting to TMDb...") logger.info("Connecting to TMDb...")
self.tmdb = {} self.tmdb = {}
self.tmdb["apikey"] = check_for_attribute(self.data, "apikey", parent="tmdb", throw=True) try: self.tmdb["apikey"] = check_for_attribute(self.data, "apikey", parent="tmdb", throw=True)
except Failed as e: raise Failed("Config Error: {}".format(e))
self.tmdb["language"] = check_for_attribute(self.data, "language", parent="tmdb", default="en") self.tmdb["language"] = check_for_attribute(self.data, "language", parent="tmdb", default="en")
self.TMDb = TMDbAPI(self.tmdb) self.TMDb = TMDbAPI(self.tmdb)
logger.info("TMDb Connection {}".format("Failed" if self.TMDb is None else "Successful")) logger.info("TMDb Connection {}".format("Failed" if self.TMDb is None else "Successful"))
@ -112,7 +129,7 @@ class Config:
authorization = self.data["trakt"]["authorization"] if "authorization" in self.data["trakt"] and self.data["trakt"]["authorization"] else None authorization = self.data["trakt"]["authorization"] if "authorization" in self.data["trakt"] and self.data["trakt"]["authorization"] else None
self.Trakt = TraktAPI(self.trakt, authorization) self.Trakt = TraktAPI(self.trakt, authorization)
except Failed as e: except Failed as e:
logger.error(e) logger.error("Config Error: {}".format(e))
logger.info("Trakt Connection {}".format("Failed" if self.Trakt is None else "Successful")) logger.info("Trakt Connection {}".format("Failed" if self.Trakt is None else "Successful"))
else: else:
logger.warning("trakt attribute not found") logger.warning("trakt attribute not found")
@ -131,7 +148,7 @@ class Config:
authorization = self.data["mal"]["authorization"] if "authorization" in self.data["mal"] and self.data["mal"]["authorization"] else None authorization = self.data["mal"]["authorization"] if "authorization" in self.data["mal"] and self.data["mal"]["authorization"] else None
self.MyAnimeList = MyAnimeListAPI(self.mal, self.MyAnimeListIDList, authorization) self.MyAnimeList = MyAnimeListAPI(self.mal, self.MyAnimeListIDList, authorization)
except Failed as e: except Failed as e:
logger.error(e) logger.error("Config Error: {}".format(e))
logger.info("My Anime List Connection {}".format("Failed" if self.MyAnimeList is None else "Successful")) logger.info("My Anime List Connection {}".format("Failed" if self.MyAnimeList is None else "Successful"))
else: else:
logger.warning("mal attribute not found") logger.warning("mal attribute not found")
@ -145,42 +162,42 @@ class Config:
logger.info("Connecting to Plex Libraries...") logger.info("Connecting to Plex Libraries...")
self.general["plex"] = {} self.general["plex"] = {}
self.general["plex"]["url"] = check_for_attribute(self.data, "url", parent="plex", default_is_none=True) if "plex" in self.data else None self.general["plex"]["url"] = check_for_attribute(self.data, "url", parent="plex", default_is_none=True)
self.general["plex"]["token"] = check_for_attribute(self.data, "token", parent="plex", default_is_none=True) if "plex" in self.data else None self.general["plex"]["token"] = check_for_attribute(self.data, "token", parent="plex", default_is_none=True)
self.general["plex"]["asset_directory"] = check_for_attribute(self.data, "asset_directory", parent="plex", var_type="path", default=os.path.join(default_dir, "assets")) if "plex" in self.data else os.path.join(default_dir, "assets") self.general["plex"]["asset_directory"] = check_for_attribute(self.data, "asset_directory", parent="plex", var_type="listpath", default=os.path.join(default_dir, "assets"))
self.general["plex"]["sync_mode"] = check_for_attribute(self.data, "sync_mode", parent="plex", default="append", test_list=["append", "sync"], options="| \tappend (Only Add Items to the Collection)\n| \tsync (Add & Remove Items from the Collection)") if "plex" in self.data else "append" self.general["plex"]["sync_mode"] = check_for_attribute(self.data, "sync_mode", parent="plex", default="append", test_list=["append", "sync"], options=" append (Only Add Items to the Collection)\n sync (Add & Remove Items from the Collection)")
self.general["plex"]["show_unmanaged"] = check_for_attribute(self.data, "show_unmanaged", parent="plex", var_type="bool", default=True) if "plex" in self.data else True self.general["plex"]["show_unmanaged"] = check_for_attribute(self.data, "show_unmanaged", parent="plex", var_type="bool", default=True)
self.general["plex"]["show_filtered"] = check_for_attribute(self.data, "show_filtered", parent="plex", var_type="bool", default=False) if "plex" in self.data else False self.general["plex"]["show_filtered"] = check_for_attribute(self.data, "show_filtered", parent="plex", var_type="bool", default=False)
self.general["plex"]["show_missing"] = check_for_attribute(self.data, "show_missing", parent="plex", var_type="bool", default=True) if "plex" in self.data else True self.general["plex"]["show_missing"] = check_for_attribute(self.data, "show_missing", parent="plex", var_type="bool", default=True)
self.general["plex"]["save_missing"] = check_for_attribute(self.data, "save_missing", parent="plex", var_type="bool", default=True) if "plex" in self.data else True self.general["plex"]["save_missing"] = check_for_attribute(self.data, "save_missing", parent="plex", var_type="bool", default=True)
self.general["radarr"] = {} self.general["radarr"] = {}
self.general["radarr"]["url"] = check_for_attribute(self.data, "url", parent="radarr", default_is_none=True) if "radarr" in self.data else None self.general["radarr"]["url"] = check_for_attribute(self.data, "url", parent="radarr", default_is_none=True)
self.general["radarr"]["version"] = check_for_attribute(self.data, "version", parent="radarr", test_list=["v2", "v3"], options="| \tv2 (For Radarr 0.2)\n| \tv3 (For Radarr 3.0)", default="v2") if "radarr" in self.data else "v2" self.general["radarr"]["version"] = check_for_attribute(self.data, "version", parent="radarr", test_list=["v2", "v3"], options=" v2 (For Radarr 0.2)\n v3 (For Radarr 3.0)", default="v2")
self.general["radarr"]["token"] = check_for_attribute(self.data, "token", parent="radarr", default_is_none=True) if "radarr" in self.data else None self.general["radarr"]["token"] = check_for_attribute(self.data, "token", parent="radarr", default_is_none=True)
self.general["radarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="radarr", default_is_none=True) if "radarr" in self.data else None self.general["radarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="radarr", default_is_none=True)
self.general["radarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="radarr", default_is_none=True) if "radarr" in self.data else None self.general["radarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="radarr", default_is_none=True)
self.general["radarr"]["add"] = check_for_attribute(self.data, "add", parent="radarr", var_type="bool", default=False) if "radarr" in self.data else False self.general["radarr"]["add"] = check_for_attribute(self.data, "add", parent="radarr", var_type="bool", default=False)
self.general["radarr"]["search"] = check_for_attribute(self.data, "search", parent="radarr", var_type="bool", default=False) if "radarr" in self.data else False self.general["radarr"]["search"] = check_for_attribute(self.data, "search", parent="radarr", var_type="bool", default=False)
self.general["radarr"]["tag"] = util.get_list(check_for_attribute(self.data, "tag", parent="radarr", default_is_none=True), lower=True) if "radarr" in self.data else None self.general["radarr"]["tag"] = check_for_attribute(self.data, "tag", parent="radarr", var_type="lowerlist", default_is_none=True)
self.general["sonarr"] = {} self.general["sonarr"] = {}
self.general["sonarr"]["url"] = check_for_attribute(self.data, "url", parent="sonarr", default_is_none=True) if "sonarr" in self.data else None self.general["sonarr"]["url"] = check_for_attribute(self.data, "url", parent="sonarr", default_is_none=True)
self.general["sonarr"]["token"] = check_for_attribute(self.data, "token", parent="sonarr", default_is_none=True) if "sonarr" in self.data else None self.general["sonarr"]["token"] = check_for_attribute(self.data, "token", parent="sonarr", default_is_none=True)
self.general["sonarr"]["version"] = check_for_attribute(self.data, "version", parent="sonarr", test_list=["v2", "v3"], options="| \tv2 (For Sonarr 0.2)\n| \tv3 (For Sonarr 3.0)", default="v2") if "sonarr" in self.data else "v2" self.general["sonarr"]["version"] = check_for_attribute(self.data, "version", parent="sonarr", test_list=["v2", "v3"], options=" v2 (For Sonarr 0.2)\n v3 (For Sonarr 3.0)", default="v2")
self.general["sonarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="sonarr", default_is_none=True) if "sonarr" in self.data else None self.general["sonarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="sonarr", default_is_none=True)
self.general["sonarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="sonarr", default_is_none=True) if "sonarr" in self.data else None self.general["sonarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="sonarr", default_is_none=True)
self.general["sonarr"]["add"] = check_for_attribute(self.data, "add", parent="sonarr", var_type="bool", default=False) if "sonarr" in self.data else False self.general["sonarr"]["add"] = check_for_attribute(self.data, "add", parent="sonarr", var_type="bool", default=False)
self.general["sonarr"]["search"] = check_for_attribute(self.data, "search", parent="sonarr", var_type="bool", default=False) if "sonarr" in self.data else False self.general["sonarr"]["search"] = check_for_attribute(self.data, "search", parent="sonarr", var_type="bool", default=False)
self.general["sonarr"]["tag"] = util.get_list(check_for_attribute(self.data, "tag", parent="sonarr", default_is_none=True), lower=True) if "sonarr" in self.data else None self.general["sonarr"]["tag"] = check_for_attribute(self.data, "tag", parent="sonarr", var_type="lowerlist", default_is_none=True)
self.general["tautulli"] = {} self.general["tautulli"] = {}
self.general["tautulli"]["url"] = check_for_attribute(self.data, "url", parent="tautulli", default_is_none=True) if "tautulli" in self.data else None self.general["tautulli"]["url"] = check_for_attribute(self.data, "url", parent="tautulli", default_is_none=True)
self.general["tautulli"]["apikey"] = check_for_attribute(self.data, "apikey", parent="tautulli", default_is_none=True) if "tautulli" in self.data else None self.general["tautulli"]["apikey"] = check_for_attribute(self.data, "apikey", parent="tautulli", default_is_none=True)
self.libraries = [] self.libraries = []
libs = check_for_attribute(self.data, "libraries", throw=True) try: libs = check_for_attribute(self.data, "libraries", throw=True)
except Failed as e: raise Failed("Config Error: {}".format(e))
for lib in libs: for lib in libs:
util.seperator() util.seperator()
params = {} params = {}
@ -192,46 +209,22 @@ class Config:
logger.info("Connecting to {} Library...".format(params["name"])) logger.info("Connecting to {} Library...".format(params["name"]))
default_lib = os.path.join(default_dir, "{}.yml".format(lib)) default_lib = os.path.join(default_dir, "{}.yml".format(lib))
try: try:
if "metadata_path" in libs[lib]: params["metadata_path"] = check_for_attribute(libs[lib], "metadata_path", var_type="path", default=os.path.join(default_dir, "{}.yml".format(lib)), throw=True)
if libs[lib]["metadata_path"]: params["library_type"] = check_for_attribute(libs[lib], "library_type", test_list=["movie", "show"], options=" movie (For Movie Libraries)\n show (For Show Libraries)", throw=True)
if os.path.exists(libs[lib]["metadata_path"]): params["metadata_path"] = libs[lib]["metadata_path"]
else: raise Failed("metadata_path not found at {}".format(libs[lib]["metadata_path"]))
else: raise Failed("metadata_path attribute is blank")
else:
if os.path.exists(default_lib): params["metadata_path"] = os.path.abspath(default_lib)
else: raise Failed("default metadata_path not found at {}".format(os.path.abspath(os.path.join(default_dir, "{}.yml".format(params["name"])))))
if "library_type" in libs[lib]:
if libs[lib]["library_type"]:
if libs[lib]["library_type"] in ["movie", "show"]: params["library_type"] = libs[lib]["library_type"]
else: raise Failed("library_type attribute must be either 'movie' or 'show'")
else: raise Failed("library_type attribute is blank")
else: raise Failed("library_type attribute is required")
params["plex"] = {} params["plex"] = {}
if "plex" in libs[lib] and libs[lib]["plex"] and "url" in libs[lib]["plex"]: params["plex"]["url"] = check_for_attribute(libs[lib], "url", parent="plex", default=self.general["plex"]["url"], req_default=True, save=False)
if libs[lib]["plex"]["url"]: params["plex"]["url"] = libs[lib]["plex"]["url"] params["plex"]["token"] = check_for_attribute(libs[lib], "token", parent="plex", default=self.general["plex"]["token"], req_default=True, save=False)
else: raise Failed("url library attribute is blank")
elif self.general["plex"]["url"]: params["plex"]["url"] = self.general["plex"]["url"]
else: raise Failed("url attribute must be set under plex or under this specific Library")
if "plex" in libs[lib] and libs[lib]["plex"] and "token" in libs[lib]["plex"]:
if libs[lib]["plex"]["token"]: params["plex"]["token"] = libs[lib]["plex"]["token"]
else: raise Failed("token library attribute is blank")
elif self.general["plex"]["token"]: params["plex"]["token"] = self.general["plex"]["token"]
else: raise Failed("token attribute must be set under plex or under this specific Library")
except Failed as e: except Failed as e:
logger.error("Config Error: Skipping {} Library {}".format(str(lib), e)) util.print_multiline("Config Error: Skipping {} Library {}".format(str(lib), e))
continue continue
params["asset_directory"] = None params["asset_directory"] = check_for_attribute(libs[lib], "asset_directory", parent="plex", var_type="listpath", default=os.path.join(default_dir, "assets"))
if "plex" in libs[lib] and "asset_directory" in libs[lib]["plex"]: if "plex" in libs[lib] and "asset_directory" in libs[lib]["plex"]:
if libs[lib]["plex"]["asset_directory"]: if libs[lib]["plex"]["asset_directory"]:
if os.path.exists(libs[lib]["plex"]["asset_directory"]): temp_list = [path for path in util.get_list(libs[lib]["plex"]["asset_directory"]) if os.path.exists(os.path.abspath(path))]
params["asset_directory"] = libs[lib]["plex"]["asset_directory"] if len(temp_list) > 0: params["asset_directory"] = temp_list
else: else: logger.warning("Config Warning: No Paths exist")
logger.warning("Config Warning: Assets will not be used asset_directory not found at {}".format(libs[lib]["plex"]["asset_directory"]))
else: else:
logger.warning("Config Warning: Assets will not be used asset_directory library attribute is blank") logger.warning("Config Warning: Assets will not be used asset_directory library attribute is blank")
elif self.general["plex"]["asset_directory"]: elif self.general["plex"]["asset_directory"]:
@ -239,203 +232,62 @@ class Config:
else: else:
logger.warning("Config Warning: Assets will not be used asset_directory attribute must be set under config or under this specific Library") logger.warning("Config Warning: Assets will not be used asset_directory attribute must be set under config or under this specific Library")
params["sync_mode"] = self.general["plex"]["sync_mode"] params["sync_mode"] = check_for_attribute(libs[lib], "sync_mode", parent="plex", test_list=["append", "sync"], options=" append (Only Add Items to the Collection)\n sync (Add & Remove Items from the Collection)", default=self.general["plex"]["sync_mode"], save=False)
if "plex" in libs[lib] and "sync_mode" in libs[lib]["plex"]: params["show_unmanaged"] = check_for_attribute(libs[lib], "show_unmanaged", parent="plex", var_type="bool", default=self.general["plex"]["show_unmanaged"], save=False)
if libs[lib]["plex"]["sync_mode"]: params["show_filtered"] = check_for_attribute(libs[lib], "show_filtered", parent="plex", var_type="bool", default=self.general["plex"]["show_filtered"], save=False)
if libs[lib]["plex"]["sync_mode"] in ["append", "sync"]: params["show_missing"] = check_for_attribute(libs[lib], "show_missing", parent="plex", var_type="bool", default=self.general["plex"]["show_missing"], save=False)
params["sync_mode"] = libs[lib]["plex"]["sync_mode"] params["save_missing"] = check_for_attribute(libs[lib], "save_missing", parent="plex", var_type="bool", default=self.general["plex"]["save_missing"], save=False)
else:
logger.warning("Config Warning: sync_mode attribute must be either 'append' or 'sync' using general value: {}".format(self.general["plex"]["sync_mode"]))
else:
logger.warning("Config Warning: sync_mode attribute is blank using general value: {}".format(self.general["plex"]["sync_mode"]))
params["show_unmanaged"] = self.general["plex"]["show_unmanaged"] if self.general["radarr"]["url"] or "radarr" in libs[lib]:
if "plex" in libs[lib] and "show_unmanaged" in libs[lib]["plex"]: logger.info("Connecting to {} library's Radarr...".format(params["name"]))
if libs[lib]["plex"]["show_unmanaged"]: radarr_params = {}
if isinstance(libs[lib]["plex"]["show_unmanaged"], bool): try:
params["plex"]["show_unmanaged"] = libs[lib]["plex"]["show_unmanaged"] radarr_params["url"] = check_for_attribute(libs[lib], "url", parent="radarr", default=self.general["radarr"]["url"], req_default=True, save=False)
else: radarr_params["token"] = check_for_attribute(libs[lib], "token", parent="radarr", default=self.general["radarr"]["token"], req_default=True, save=False)
logger.warning("Config Warning: plex sub-attribute show_unmanaged must be either true or false using general value: {}".format(self.general["plex"]["show_unmanaged"])) radarr_params["version"] = check_for_attribute(libs[lib], "version", parent="radarr", test_list=["v2", "v3"], options=" v2 (For Radarr 0.2)\n v3 (For Radarr 3.0)", default=self.general["radarr"]["version"], save=False)
else: radarr_params["quality_profile"] = check_for_attribute(libs[lib], "quality_profile", parent="radarr", default=self.general["radarr"]["quality_profile"], req_default=True, save=False)
logger.warning("Config Warning: plex sub-attribute show_unmanaged is blank using general value: {}".format(self.general["plex"]["show_unmanaged"])) radarr_params["root_folder_path"] = check_for_attribute(libs[lib], "root_folder_path", parent="radarr", default=self.general["radarr"]["root_folder_path"], req_default=True, save=False)
radarr_params["add"] = check_for_attribute(libs[lib], "add", parent="radarr", var_type="bool", default=self.general["radarr"]["add"], save=False)
radarr_params["search"] = check_for_attribute(libs[lib], "search", parent="radarr", var_type="bool", default=self.general["radarr"]["search"], save=False)
radarr_params["tag"] = check_for_attribute(libs[lib], "search", parent="radarr", var_type="lowerlist", default=self.general["radarr"]["tag"], default_is_none=True, save=False)
Radarr = RadarrAPI(self.TMDb, radarr_params)
except Failed as e:
util.print_multiline("Config Error: {}".format(e))
Radarr = None
logger.info("{} library's Radarr Connection {}".format(params["name"], "Failed" if Radarr is None else "Successful"))
params["show_filtered"] = self.general["plex"]["show_filtered"] if self.general["sonarr"]["url"] or "sonarr" in libs[lib]:
if "plex" in libs[lib] and "show_filtered" in libs[lib]["plex"]: logger.info("Connecting to {} library's Sonarr...".format(params["name"]))
if libs[lib]["plex"]["show_filtered"]: sonarr_params = {}
if isinstance(libs[lib]["plex"]["show_filtered"], bool): try:
params["plex"]["show_filtered"] = libs[lib]["plex"]["show_filtered"] sonarr_params["url"] = check_for_attribute(libs[lib], "url", parent="sonarr", default=self.general["sonarr"]["url"], req_default=True, save=False)
else: sonarr_params["token"] = check_for_attribute(libs[lib], "token", parent="sonarr", default=self.general["sonarr"]["token"], req_default=True, save=False)
logger.warning("Config Warning: plex sub-attribute show_filtered must be either true or false using general value: {}".format(self.general["plex"]["show_filtered"])) sonarr_params["version"] = check_for_attribute(libs[lib], "version", parent="sonarr", test_list=["v2", "v3"], options=" v2 (For Sonarr 0.2)\n v3 (For Sonarr 3.0)", default=self.general["sonarr"]["version"], save=False)
else: sonarr_params["quality_profile"] = check_for_attribute(libs[lib], "quality_profile", parent="sonarr", default=self.general["sonarr"]["quality_profile"], req_default=True, save=False)
logger.warning("Config Warning: plex sub-attribute show_filtered is blank using general value: {}".format(self.general["plex"]["show_filtered"])) sonarr_params["root_folder_path"] = check_for_attribute(libs[lib], "root_folder_path", parent="sonarr", default=self.general["sonarr"]["root_folder_path"], req_default=True, save=False)
sonarr_params["add"] = check_for_attribute(libs[lib], "add", parent="sonarr", var_type="bool", default=self.general["sonarr"]["add"], save=False)
sonarr_params["search"] = check_for_attribute(libs[lib], "search", parent="sonarr", var_type="bool", default=self.general["sonarr"]["search"], save=False)
sonarr_params["tag"] = check_for_attribute(libs[lib], "search", parent="sonarr", var_type="lowerlist", default=self.general["sonarr"]["tag"], default_is_none=True, save=False)
Sonarr = SonarrAPI(self.TVDb, sonarr_params, self.tmdb["language"])
except Failed as e:
util.print_multiline("Config Error: {}".format(e))
Sonarr = None
logger.info("{} library's Sonarr Connection {}".format(params["name"], "Failed" if Sonarr is None else "Successful"))
params["show_missing"] = self.general["plex"]["show_missing"] if self.general["tautulli"]["url"] or "tautulli" in libs[lib]:
if "plex" in libs[lib] and "show_missing" in libs[lib]["plex"]: logger.info("Connecting to {} library's Tautulli...".format(params["name"]))
if libs[lib]["plex"]["show_missing"]: tautulli_params = {}
if isinstance(libs[lib]["plex"]["show_missing"], bool): try:
params["plex"]["show_missing"] = libs[lib]["plex"]["show_missing"] tautulli_params["url"] = check_for_attribute(libs[lib], "url", parent="tautulli", default=self.general["tautulli"]["url"], req_default=True, save=False)
else: tautulli_params["apikey"] = check_for_attribute(libs[lib], "apikey", parent="tautulli", default=self.general["tautulli"]["apikey"], req_default=True, save=False)
logger.warning("Config Warning: plex sub-attribute show_missing must be either true or false using general value: {}".format(self.general["plex"]["show_missing"])) Tautulli = TautulliAPI(tautulli_params)
else: except Failed as e:
logger.warning("Config Warning: plex sub-attribute show_missing is blank using general value: {}".format(self.general["plex"]["show_missing"])) util.print_multiline("Config Error: {}".format(e))
Tautulli = None
params["save_missing"] = self.general["plex"]["save_missing"] logger.info("{} library's Tautulli Connection {}".format(params["name"], "Failed" if Tautulli is None else "Successful"))
if "plex" in libs[lib] and "save_missing" in libs[lib]["plex"]:
if libs[lib]["plex"]["save_missing"]:
if isinstance(libs[lib]["plex"]["save_missing"], bool):
params["plex"]["save_missing"] = libs[lib]["plex"]["save_missing"]
else:
logger.warning("Config Warning: plex sub-attribute save_missing must be either true or false using general value: {}".format(self.general["plex"]["save_missing"]))
else:
logger.warning("Config Warning: plex sub-attribute save_missing is blank using general value: {}".format(self.general["plex"]["save_missing"]))
params["tmdb"] = self.TMDb
params["tvdb"] = self.TVDb
params["radarr"] = self.general["radarr"].copy()
if "radarr" in libs[lib] and libs[lib]["radarr"]:
if "url" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["url"]:
params["radarr"]["url"] = libs[lib]["radarr"]["url"]
else:
logger.warning("Config Warning: radarr sub-attribute url is blank using general value: {}".format(self.general["radarr"]["url"]))
if "token" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["token"]:
params["radarr"]["token"] = libs[lib]["radarr"]["token"]
else:
logger.warning("Config Warning: radarr sub-attribute token is blank using general value: {}".format(self.general["radarr"]["token"]))
if "version" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["version"]:
if libs[lib]["radarr"]["version"] in ["v2", "v3"]:
params["radarr"]["version"] = libs[lib]["radarr"]["version"]
else:
logger.warning("Config Warning: radarr sub-attribute version must be either 'v2' or 'v3' using general value: {}".format(self.general["radarr"]["version"]))
else:
logger.warning("Config Warning: radarr sub-attribute version is blank using general value: {}".format(self.general["radarr"]["version"]))
if "quality_profile" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["quality_profile"]:
params["radarr"]["quality_profile"] = libs[lib]["radarr"]["quality_profile"]
else:
logger.warning("Config Warning: radarr sub-attribute quality_profile is blank using general value: {}".format(self.general["radarr"]["quality_profile"]))
if "root_folder_path" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["root_folder_path"]:
params["radarr"]["root_folder_path"] = libs[lib]["radarr"]["root_folder_path"]
else:
logger.warning("Config Warning: radarr sub-attribute root_folder_path is blank using general value: {}".format(self.general["radarr"]["root_folder_path"]))
if "add" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["add"]:
if isinstance(libs[lib]["radarr"]["add"], bool):
params["radarr"]["add"] = libs[lib]["radarr"]["add"]
else:
logger.warning("Config Warning: radarr sub-attribute add must be either true or false using general value: {}".format(self.general["radarr"]["add"]))
else:
logger.warning("Config Warning: radarr sub-attribute add is blank using general value: {}".format(self.general["radarr"]["add"]))
if "search" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["search"]:
if isinstance(libs[lib]["radarr"]["search"], bool):
params["radarr"]["search"] = libs[lib]["radarr"]["search"]
else:
logger.warning("Config Warning: radarr sub-attribute search must be either true or false using general value: {}".format(self.general["radarr"]["search"]))
else:
logger.warning("Config Warning: radarr sub-attribute search is blank using general value: {}".format(self.general["radarr"]["search"]))
if "tag" in libs[lib]["radarr"]:
if libs[lib]["radarr"]["tag"]:
params["radarr"]["tag"] = util.get_list(libs[lib]["radarr"]["tag"], lower=True)
else:
logger.warning("Config Warning: radarr sub-attribute tag is blank using general value: {}".format(self.general["radarr"]["tag"]))
if not params["radarr"]["url"] or not params["radarr"]["token"] or not params["radarr"]["quality_profile"] or not params["radarr"]["root_folder_path"]:
params["radarr"] = None
params["sonarr"] = self.general["sonarr"].copy()
if "sonarr" in libs[lib] and libs[lib]["sonarr"]:
if "url" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["url"]:
params["sonarr"]["url"] = libs[lib]["sonarr"]["url"]
else:
logger.warning("Config Warning: sonarr sub-attribute url is blank using general value: {}".format(self.general["sonarr"]["url"]))
if "token" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["token"]:
params["sonarr"]["token"] = libs[lib]["sonarr"]["token"]
else:
logger.warning("Config Warning: sonarr sub-attribute token is blank using general value: {}".format(self.general["sonarr"]["token"]))
if "version" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["version"]:
if libs[lib]["sonarr"]["version"] in ["v2", "v3"]:
params["sonarr"]["version"] = libs[lib]["sonarr"]["version"]
else:
logger.warning("Config Warning: sonarr sub-attribute version must be either 'v2' or 'v3' using general value: {}".format(self.general["sonarr"]["version"]))
else:
logger.warning("Config Warning: sonarr sub-attribute version is blank using general value: {}".format(self.general["sonarr"]["version"]))
if "quality_profile" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["quality_profile"]:
params["sonarr"]["quality_profile"] = libs[lib]["sonarr"]["quality_profile"]
else:
logger.warning("Config Warning: sonarr sub-attribute quality_profile is blank using general value: {}".format(self.general["sonarr"]["quality_profile"]))
if "root_folder_path" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["root_folder_path"]:
params["sonarr"]["root_folder_path"] = libs[lib]["sonarr"]["root_folder_path"]
else:
logger.warning("Config Warning: sonarr sub-attribute root_folder_path is blank using general value: {}".format(self.general["sonarr"]["root_folder_path"]))
if "add" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["add"]:
if isinstance(libs[lib]["sonarr"]["add"], bool):
params["sonarr"]["add"] = libs[lib]["sonarr"]["add"]
else:
logger.warning("Config Warning: sonarr sub-attribute add must be either true or false using general value: {}".format(self.general["sonarr"]["add"]))
else:
logger.warning("Config Warning: sonarr sub-attribute add is blank using general value: {}".format(self.general["sonarr"]["add"]))
if "search" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["search"]:
if isinstance(libs[lib]["sonarr"]["search"], bool):
params["sonarr"]["search"] = libs[lib]["sonarr"]["search"]
else:
logger.warning("Config Warning: sonarr sub-attribute search must be either true or false using general value: {}".format(self.general["sonarr"]["search"]))
else:
logger.warning("Config Warning: sonarr sub-attribute search is blank using general value: {}".format(self.general["sonarr"]["search"]))
if "tag" in libs[lib]["sonarr"]:
if libs[lib]["sonarr"]["tag"]:
params["sonarr"]["tag"] = util.get_list(libs[lib]["sonarr"]["tag"], lower=True)
else:
logger.warning("Config Warning: sonarr sub-attribute tag is blank using general value: {}".format(self.general["sonarr"]["tag"]))
if not params["sonarr"]["url"] or not params["sonarr"]["token"] or not params["sonarr"]["quality_profile"] or not params["sonarr"]["root_folder_path"] or params["library_type"] == "movie":
params["sonarr"] = None
params["tautulli"] = self.general["tautulli"].copy()
if "tautulli" in libs[lib] and libs[lib]["tautulli"]:
if "url" in libs[lib]["tautulli"]:
if libs[lib]["tautulli"]["url"]:
params["tautulli"]["url"] = libs[lib]["tautulli"]["url"]
else:
logger.warning("Config Warning: tautulli sub-attribute url is blank using general value: {}".format(self.general["tautulli"]["url"]))
if "apikey" in libs[lib]["tautulli"]:
if libs[lib]["tautulli"]["apikey"]:
params["tautulli"]["apikey"] = libs[lib]["tautulli"]["apikey"]
else:
logger.warning("Config Warning: tautulli sub-attribute apikey is blank using general value: {}".format(self.general["tautulli"]["apikey"]))
if not params["tautulli"]["url"] or not params["tautulli"]["apikey"] :
params["tautulli"] = None
try: try:
self.libraries.append(PlexAPI(params)) self.libraries.append(PlexAPI(params, self.TMDb, self.TVDb, Radarr, Sonarr, Tautulli))
logger.info("{} Library Connection Successful".format(params["name"])) logger.info("{} Library Connection Successful".format(params["name"]))
except Failed as e: except Failed as e:
logger.error(e) logger.error(e)

View file

@ -1,9 +1,6 @@
import datetime, logging, os, requests import datetime, logging, os, requests
from lxml import html from lxml import html
from modules import util from modules import util
from modules.radarr import RadarrAPI
from modules.sonarr import SonarrAPI
from modules.tautulli import TautulliAPI
from modules.util import Failed from modules.util import Failed
from plexapi.exceptions import BadRequest, NotFound, Unauthorized from plexapi.exceptions import BadRequest, NotFound, Unauthorized
from plexapi.library import Collections, MovieSection, ShowSection from plexapi.library import Collections, MovieSection, ShowSection
@ -15,7 +12,7 @@ from ruamel import yaml
logger = logging.getLogger("Plex Meta Manager") logger = logging.getLogger("Plex Meta Manager")
class PlexAPI: class PlexAPI:
def __init__(self, params): def __init__(self, params, TMDb, TVDb, Radarr, Sonarr, Tautulli):
try: self.PlexServer = PlexServer(params["plex"]["url"], params["plex"]["token"], timeout=600) try: self.PlexServer = PlexServer(params["plex"]["url"], params["plex"]["token"], timeout=600)
except Unauthorized: raise Failed("Plex Error: Plex token is invalid") except Unauthorized: raise Failed("Plex Error: Plex token is invalid")
except ValueError as e: raise Failed("Plex Error: {}".format(e)) except ValueError as e: raise Failed("Plex Error: {}".format(e))
@ -45,33 +42,15 @@ class PlexAPI:
raise Failed("YAML Error: metadata attributes or collections attribute required") raise Failed("YAML Error: metadata attributes or collections attribute required")
if params["asset_directory"]: if params["asset_directory"]:
logger.info("Using Asset Directory: {}".format(params["asset_directory"])) for ad in params["asset_directory"]:
logger.info("Using Asset Directory: {}".format(ad))
self.Radarr = None self.TMDb = TMDb
if params["tmdb"] and params["radarr"]: self.TVDb = TVDb
logger.info("Connecting to {} library's Radarr...".format(params["name"])) self.Radarr = Radarr
try: self.Radarr = RadarrAPI(params["tmdb"], params["radarr"]) self.Sonarr = Sonarr
except Failed as e: logger.error(e) self.Tautulli = Tautulli
logger.info("{} library's Radarr Connection {}".format(params["name"], "Failed" if self.Radarr is None else "Successful"))
self.Sonarr = None
if params["tvdb"] and params["sonarr"]:
logger.info("Connecting to {} library's Sonarr...".format(params["name"]))
try: self.Sonarr = SonarrAPI(params["tvdb"], params["sonarr"], self.Plex.language)
except Failed as e: logger.error(e)
logger.info("{} library's Sonarr Connection {}".format(params["name"], "Failed" if self.Sonarr is None else "Successful"))
self.Tautulli = None
if params["tautulli"]:
logger.info("Connecting to {} library's Tautulli...".format(params["name"]))
try: self.Tautulli = TautulliAPI(params["tautulli"])
except Failed as e: logger.error(e)
logger.info("{} library's Tautulli Connection {}".format(params["name"], "Failed" if self.Tautulli is None else "Successful"))
self.TMDb = params["tmdb"]
self.TVDb = params["tvdb"]
self.name = params["name"] self.name = params["name"]
self.missing_path = os.path.join(os.path.dirname(os.path.abspath(params["metadata_path"])), "{}_missing.yml".format(os.path.splitext(os.path.basename(params["metadata_path"]))[0])) self.missing_path = os.path.join(os.path.dirname(os.path.abspath(params["metadata_path"])), "{}_missing.yml".format(os.path.splitext(os.path.basename(params["metadata_path"]))[0]))
self.metadata_path = params["metadata_path"] self.metadata_path = params["metadata_path"]
self.asset_directory = params["asset_directory"] self.asset_directory = params["asset_directory"]
@ -81,9 +60,6 @@ class PlexAPI:
self.show_missing = params["show_missing"] self.show_missing = params["show_missing"]
self.save_missing = params["save_missing"] self.save_missing = params["save_missing"]
self.plex = params["plex"] self.plex = params["plex"]
self.radarr = params["radarr"]
self.sonarr = params["sonarr"]
self.tautulli = params["tautulli"]
self.missing = {} self.missing = {}
@retry(stop_max_attempt_number=6, wait_fixed=10000) @retry(stop_max_attempt_number=6, wait_fixed=10000)

View file

@ -4,11 +4,12 @@ from modules.config import Config
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("--mytests", dest="tests", help=argparse.SUPPRESS, action="store_true", default=False) parser.add_argument("--mytests", dest="tests", help=argparse.SUPPRESS, action="store_true", default=False)
parser.add_argument("--debug", dest="debug", help=argparse.SUPPRESS, action="store_true", default=False)
parser.add_argument("-c", "--config", dest="config", help="Run with desired *.yml file", type=str) parser.add_argument("-c", "--config", dest="config", help="Run with desired *.yml file", type=str)
parser.add_argument("-t", "--time", dest="time", help="Time to update each day use format HH:MM (Default: 03:00)", default="03:00", type=str) parser.add_argument("-t", "--time", dest="time", help="Time to update each day use format HH:MM (Default: 03:00)", default="03:00", type=str)
parser.add_argument("-r", "--run", dest="run", help="Run without the scheduler", action="store_true", default=False) parser.add_argument("-r", "--run", dest="run", help="Run without the scheduler", action="store_true", default=False)
parser.add_argument("-rt", "--test", "--tests", "--run-test", "--run-tests", dest="test", help="Run only tests without the scheduler", 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)
parser.add_argument("-cl", "--collections", dest="collections", help="Process only specified collections (comma-separated list)", type=str, default="") parser.add_argument("-cl", "--collection", "--collections", dest="collections", help="Process only specified collections (comma-separated list)", type=str, default="")
parser.add_argument("-d", "--divider", dest="divider", help="Character that divides the sections (Default: '=')", default="=", type=str) 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) parser.add_argument("-w", "--width", dest="width", help="Screen Width (Default: 100)", default=100, type=int)
args = parser.parse_args() args = parser.parse_args()
@ -43,7 +44,7 @@ file_handler.setFormatter(logging.Formatter("[%(asctime)s] %(filename)-27s %(lev
cmd_handler = logging.StreamHandler() cmd_handler = logging.StreamHandler()
cmd_handler.setFormatter(logging.Formatter("| %(message)-100s |")) cmd_handler.setFormatter(logging.Formatter("| %(message)-100s |"))
cmd_handler.setLevel(logging.DEBUG if args.tests or args.test else logging.INFO) cmd_handler.setLevel(logging.DEBUG if args.tests or args.test or args.debug else logging.INFO)
logger.addHandler(cmd_handler) logger.addHandler(cmd_handler)
logger.addHandler(file_handler) logger.addHandler(file_handler)