[92] add metadata image sets

pull/1328/head
meisnate12 2 years ago
parent bbe13d7c5b
commit 0328b359ac

@ -1 +1 @@
1.18.3-develop91 1.18.3-develop92

@ -398,6 +398,7 @@ class ConfigFile:
"check_nightly": check_for_attribute(self.data, "check_nightly", parent="settings", var_type="bool", default=False), "check_nightly": check_for_attribute(self.data, "check_nightly", parent="settings", var_type="bool", default=False),
"assets_for_all": check_for_attribute(self.data, "assets_for_all", parent="settings", var_type="bool", default=False, save=False, do_print=False) "assets_for_all": check_for_attribute(self.data, "assets_for_all", parent="settings", var_type="bool", default=False, save=False, do_print=False)
} }
self.image_sets = {}
self.custom_repo = None self.custom_repo = None
if self.general["custom_repo"]: if self.general["custom_repo"]:
repo = self.general["custom_repo"] repo = self.general["custom_repo"]

@ -126,18 +126,16 @@ class DataFile:
defaults_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "defaults") defaults_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "defaults")
if overlay: if overlay:
defaults_path = os.path.join(defaults_path, "overlays") defaults_path = os.path.join(defaults_path, "overlays")
if os.path.exists(os.path.abspath(os.path.join(defaults_path, file_path))): if os.path.exists(os.path.join(defaults_path, file_path)):
file_path = os.path.abspath(os.path.join(defaults_path, file_path)) file_path = os.path.join(defaults_path, file_path)
elif self.library: elif self.library:
for default_folder in [self.library.type.lower(), "both", "chart", "award"]: for default_folder in [self.library.type.lower(), "both", "chart", "award"]:
if os.path.exists(os.path.abspath(os.path.join(defaults_path, default_folder, file_path))): if os.path.exists(os.path.join(defaults_path, default_folder, file_path)):
file_path = os.path.abspath(os.path.join(defaults_path, default_folder, file_path)) file_path = os.path.join(defaults_path, default_folder, file_path)
break break
content_path = os.path.abspath(os.path.join(file_path, "default.yml") if translation else file_path) content_path = os.path.abspath(os.path.join(file_path, "default.yml") if translation else file_path)
dir_path = file_path dir_path = file_path
if not os.path.exists(content_path): if not os.path.exists(content_path):
if os.path.exists(os.path.join("config", content_path)):
content_path = os.path.join("config", content_path)
if file_type == "PMM Default": if file_type == "PMM Default":
raise Failed(f"File Error: Default does not exist {file_path}") raise Failed(f"File Error: Default does not exist {file_path}")
else: else:
@ -1436,7 +1434,45 @@ class MetadataFile(DataFile):
else: else:
logger.error(f"{mapping_name} Advanced Details Update Failed") logger.error(f"{mapping_name} Advanced Details Update Failed")
asset_location, folder_name, ups = self.library.item_images(item, meta, methods, initial=True, asset_directory=self.asset_directory + self.library.asset_directory if self.asset_directory else None) image_set_data = None
if "image_set" in methods:
logger.debug("")
logger.debug("Validating Method: image_set")
set_files = meta[methods["image_set"]]
if not set_files:
raise Failed("Metadata Error: image_set attribute is blank")
logger.debug(f"Value: {set_files}")
set_dict = set_files[0] if isinstance(set_files, list) else set_files
if not isinstance(set_dict, dict):
raise Failed("Metadata Error: No image_set path dictionary found")
elif not set_dict:
raise Failed("Metadata Error: image_set path dictionary is empty")
set_name = ""
for k, v in set_dict.items():
set_name = f"{k}: {v}"
break
if set_name not in self.config.image_sets:
files = util.load_files(meta[methods["image_set"]], "image_set", err_type="Metadata", single=True)
if not files:
raise Failed("Metadata Error: No Path Found for image_set")
file_type, set_file, _, _ = files[0]
temp_data = self.load_file(file_type, set_file)
if "set" not in temp_data:
raise Failed('Image Set Error: Image sets must use the base attribute "set"')
if not isinstance(temp_data, dict):
raise Failed("Image Set Error: Image set must be a dictionary")
if not temp_data["set"]:
raise Failed("Image Set Error: Image set attribute is empty")
if not isinstance(temp_data["set"], dict):
raise Failed("Image Set Error: Image set set attribute must be a dictionary")
self.config.image_sets[set_name] = temp_data["set"]
image_set_data = self.config.image_sets[set_name]
main_set_data = None
if image_set_data and mapping_name in image_set_data:
main_set_data = image_set_data[mapping_name]
asset_location, folder_name, ups = self.library.item_images(item, meta, methods, initial=True, asset_directory=self.asset_directory + self.library.asset_directory if self.asset_directory else None, image_set=main_set_data)
if ups: if ups:
updated = True updated = True
logger.info(f"{self.library.type}: {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}") logger.info(f"{self.library.type}: {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}")
@ -1445,27 +1481,29 @@ class MetadataFile(DataFile):
if "update_seasons" in methods and self.library.is_show: if "update_seasons" in methods and self.library.is_show:
logger.debug("") logger.debug("")
logger.debug("Validating Method: update_seasons") logger.debug("Validating Method: update_seasons")
if meta[methods["update_seasons"]] is None: if not meta[methods["update_seasons"]]:
logger.warning("Metadata Warning: update_seasons has no value and season updates will be performed") logger.warning("Metadata Warning: update_seasons has no value and season updates will be performed")
logger.debug(f"Value: {meta[methods['update_seasons']]}") else:
for library_type in util.get_list(meta[methods["run_definition"]], lower=True): logger.debug(f"Value: {meta[methods['update_seasons']]}")
if library_type not in ["true", "false"]: for library_type in util.get_list(meta[methods["run_definition"]], lower=True):
raise Failed(f"Metadata Error: {library_type} is invalid. Options: true or false") if library_type not in ["true", "false"]:
elif library_type == "false": raise Failed(f"Metadata Error: {library_type} is invalid. Options: true or false")
update_seasons = False elif library_type == "false":
update_seasons = False
update_episodes = True update_episodes = True
if "update_episodes" in methods and self.library.is_show: if "update_episodes" in methods and self.library.is_show:
logger.debug("") logger.debug("")
logger.debug("Validating Method: update_episodes") logger.debug("Validating Method: update_episodes")
if meta[methods["update_episodes"]] is None: if not meta[methods["update_episodes"]]:
logger.warning("Metadata Warning: update_episodes has no value and episode updates will be performed") logger.warning("Metadata Warning: update_episodes has no value and episode updates will be performed")
logger.debug(f"Value: {meta[methods['update_episodes']]}") else:
for library_type in util.get_list(meta[methods["run_definition"]], lower=True): logger.debug(f"Value: {meta[methods['update_episodes']]}")
if library_type not in ["true", "false"]: for library_type in util.get_list(meta[methods["run_definition"]], lower=True):
raise Failed(f"Metadata Error: {library_type} is invalid. Options: true or false") if library_type not in ["true", "false"]:
elif library_type == "false": raise Failed(f"Metadata Error: {library_type} is invalid. Options: true or false")
update_episodes = False elif library_type == "false":
update_episodes = False
if "seasons" in methods and self.library.is_show and (update_seasons or update_episodes): if "seasons" in methods and self.library.is_show and (update_seasons or update_episodes):
if not meta[methods["seasons"]]: if not meta[methods["seasons"]]:
@ -1487,6 +1525,7 @@ class MetadataFile(DataFile):
logger.error(f"Metadata Error: Season: {season_id} not found") logger.error(f"Metadata Error: Season: {season_id} not found")
continue continue
season_methods = {sm.lower(): sm for sm in season_dict} season_methods = {sm.lower(): sm for sm in season_dict}
season_image_set = None
if update_seasons: if update_seasons:
#season.batchEdits() #season.batchEdits()
add_edit("title", season, season_dict, season_methods) add_edit("title", season, season_dict, season_methods)
@ -1495,9 +1534,12 @@ class MetadataFile(DataFile):
if self.edit_tags("label", season, season_dict, season_methods): if self.edit_tags("label", season, season_dict, season_methods):
updated = True updated = True
finish_edit(season, f"Season: {season_id}") finish_edit(season, f"Season: {season_id}")
if main_set_data and "seasons" in main_set_data and main_set_data["seasons"] and season_id in main_set_data["seasons"]:
season_image_set = main_set_data["seasons"][season_id]
_, _, ups = self.library.item_images(season, season_dict, season_methods, asset_location=asset_location, _, _, ups = self.library.item_images(season, season_dict, season_methods, asset_location=asset_location,
title=f"{item.title} Season {season.seasonNumber}", title=f"{item.title} Season {season.seasonNumber}",
image_name=f"Season{'0' if season.seasonNumber < 10 else ''}{season.seasonNumber}", folder_name=folder_name) image_name=f"Season{'0' if season.seasonNumber < 10 else ''}{season.seasonNumber}",
folder_name=folder_name, image_set=season_image_set)
if ups: if ups:
updated = True updated = True
logger.info(f"Season {season_id} of {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}") logger.info(f"Season {season_id} of {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}")
@ -1512,14 +1554,14 @@ class MetadataFile(DataFile):
for episode in season.episodes(): for episode in season.episodes():
episodes[episode.title] = episode episodes[episode.title] = episode
episodes[int(episode.index)] = episode episodes[int(episode.index)] = episode
for episode_str, episode_dict in season_dict[season_methods["episodes"]].items(): for episode_id, episode_dict in season_dict[season_methods["episodes"]].items():
updated = False updated = False
logger.info("") logger.info("")
logger.info(f"Updating episode {episode_str} in {season_id} of {mapping_name}...") logger.info(f"Updating episode {episode_id} in {season_id} of {mapping_name}...")
if episode_str in episodes: if episode_id in episodes:
episode = episodes[episode_str] episode = episodes[episode_id]
else: else:
logger.error(f"Metadata Error: Episode {episode_str} in Season {season_id} not found") logger.error(f"Metadata Error: Episode {episode_id} in Season {season_id} not found")
continue continue
episode_methods = {em.lower(): em for em in episode_dict} episode_methods = {em.lower(): em for em in episode_dict}
#episode.batchEdits() #episode.batchEdits()
@ -1534,13 +1576,17 @@ class MetadataFile(DataFile):
for tag_edit in ["director", "writer", "label"]: for tag_edit in ["director", "writer", "label"]:
if self.edit_tags(tag_edit, episode, episode_dict, episode_methods): if self.edit_tags(tag_edit, episode, episode_dict, episode_methods):
updated = True updated = True
finish_edit(episode, f"Episode: {episode_str} in Season: {season_id}") finish_edit(episode, f"Episode: {episode_id} in Season: {season_id}")
episode_image_set = None
if season_image_set and "episodes" in season_image_set and season_image_set["episodes"] and episode_id in season_image_set["episodes"]:
episode_image_set = season_image_set["episodes"][episode_id]
_, _, ups = self.library.item_images(episode, episode_dict, episode_methods, asset_location=asset_location, _, _, ups = self.library.item_images(episode, episode_dict, episode_methods, asset_location=asset_location,
title=f"{item.title} {episode.seasonEpisode.upper()}", title=f"{item.title} {episode.seasonEpisode.upper()}",
image_name=episode.seasonEpisode.upper(), folder_name=folder_name) image_name=episode.seasonEpisode.upper(), folder_name=folder_name,
image_set=episode_image_set)
if ups: if ups:
updated = True updated = True
logger.info(f"Episode {episode_str} in Season {season_id} of {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}") logger.info(f"Episode {episode_id} in Season {season_id} of {mapping_name} Details Update {'Complete' if updated else 'Not Needed'}")
if "episodes" in methods and update_episodes and self.library.is_show: if "episodes" in methods and update_episodes and self.library.is_show:
if not meta[methods["episodes"]]: if not meta[methods["episodes"]]:

@ -1168,10 +1168,14 @@ class Plex(Library):
else: else:
logger.warning(f"{text} | No Reset Image Found") logger.warning(f"{text} | No Reset Image Found")
def item_images(self, item, group, alias, initial=False, asset_location=None, asset_directory=None, title=None, image_name=None, folder_name=None): def item_images(self, item, group, alias, initial=False, asset_location=None, asset_directory=None, title=None, image_name=None, folder_name=None, image_set=None):
if title is None: if title is None:
title = item.title title = item.title
posters, backgrounds = util.get_image_dicts(group, alias) posters, backgrounds = util.get_image_dicts(group, alias)
if image_set and "poster" in image_set:
posters["image_set"] = image_set["poster"]
if image_set and "background" in image_set:
backgrounds["image_set"] = image_set["background"]
try: try:
asset_poster, asset_background, item_dir, folder_name = self.find_item_assets(item, item_asset_directory=asset_location, asset_directory=asset_directory) asset_poster, asset_background, item_dir, folder_name = self.find_item_assets(item, item_asset_directory=asset_location, asset_directory=asset_directory)
if asset_poster: if asset_poster:

@ -199,6 +199,8 @@ def pick_image(title, images, prioritize_assets, download_url_assets, item_dir,
final_attr = None final_attr = None
if prioritize_assets and "asset_directory" in images: if prioritize_assets and "asset_directory" in images:
return images["asset_directory"] return images["asset_directory"]
elif "image_set" in images:
final_attr = "image_set"
elif f"url_{image_type}" in images: elif f"url_{image_type}" in images:
if download_url_assets and item_dir: if download_url_assets and item_dir:
if "asset_directory" in images: if "asset_directory" in images:
@ -432,11 +434,14 @@ def time_window(tw):
else: else:
return tw return tw
def load_files(files_to_load, method, schedule=None, lib_vars=None): def load_files(files_to_load, method, err_type="Config", schedule=None, lib_vars=None, single=False):
files = [] files = []
if not lib_vars: if not lib_vars:
lib_vars = {} lib_vars = {}
for file in get_list(files_to_load, split=False): files_to_load = get_list(files_to_load, split=False)
if single and len(files_to_load) > 1:
raise Failed(f"{err_type} Error: {method} can only have one entry")
for file in files_to_load:
if isinstance(file, dict): if isinstance(file, dict):
temp_vars = {} temp_vars = {}
if "template_variables" in file and file["template_variables"] and isinstance(file["template_variables"], dict): if "template_variables" in file and file["template_variables"] and isinstance(file["template_variables"], dict):
@ -450,7 +455,7 @@ def load_files(files_to_load, method, schedule=None, lib_vars=None):
if os.path.exists(asset_path): if os.path.exists(asset_path):
asset_directory.append(asset_path) asset_directory.append(asset_path)
else: else:
logger.error(f"Config Error: Asset Directory Does Not Exist: {asset_path}") logger.error(f"{err_type} Error: Asset Directory Does Not Exist: {asset_path}")
current = [] current = []
def check_dict(attr, name): def check_dict(attr, name):
@ -461,25 +466,25 @@ def load_files(files_to_load, method, schedule=None, lib_vars=None):
else: else:
current.append((name, file[attr], temp_vars, asset_directory)) current.append((name, file[attr], temp_vars, asset_directory))
else: else:
logger.error(f"Config Error: {method} {attr} is blank") logger.error(f"{err_type} Error: {method} {attr} is blank")
check_dict("url", "URL") check_dict("url", "URL")
check_dict("git", "Git") check_dict("git", "Git")
check_dict("pmm", "PMM Default") check_dict("pmm", "PMM Default")
check_dict("repo", "Repo") check_dict("repo", "Repo")
check_dict("file", "File") check_dict("file", "File")
if "folder" in file: if not single and "folder" in file:
if file["folder"] is None: if file["folder"] is None:
logger.error(f"Config Error: {method} folder is blank") logger.error(f"{err_type} Error: {method} folder is blank")
elif not os.path.isdir(file["folder"]): elif not os.path.isdir(file["folder"]):
logger.error(f"Config Error: Folder not found: {file['folder']}") logger.error(f"{err_type} Error: Folder not found: {file['folder']}")
else: else:
yml_files = glob_filter(os.path.join(file["folder"], "*.yml")) yml_files = glob_filter(os.path.join(file["folder"], "*.yml"))
yml_files.extend(glob_filter(os.path.join(file["folder"], "*.yaml"))) yml_files.extend(glob_filter(os.path.join(file["folder"], "*.yaml")))
if yml_files: if yml_files:
current.extend([("File", yml, temp_vars, asset_directory) for yml in yml_files]) current.extend([("File", yml, temp_vars, asset_directory) for yml in yml_files])
else: else:
logger.error(f"Config Error: No YAML (.yml|.yaml) files found in {file['folder']}") logger.error(f"{err_type} Error: No YAML (.yml|.yaml) files found in {file['folder']}")
if schedule and "schedule" in file and file["schedule"]: if schedule and "schedule" in file and file["schedule"]:
current_time, run_hour, ignore_schedules = schedule current_time, run_hour, ignore_schedules = schedule
@ -503,7 +508,7 @@ def load_files(files_to_load, method, schedule=None, lib_vars=None):
if os.path.exists(file): if os.path.exists(file):
files.append(("File", file, {}, None)) files.append(("File", file, {}, None))
else: else:
logger.error(f"Config Error: Path not found: {file}") logger.error(f"{err_type} Error: Path not found: {file}")
return files return files
def check_num(num, is_int=True): def check_num(num, is_int=True):

Loading…
Cancel
Save