From 18038d77d08c9cbce4738abba5ed6316b27fbd1a Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Thu, 30 Dec 2021 23:51:46 -0500 Subject: [PATCH] add genre_collections --- modules/config.py | 29 ++++++++++++++++++++++++++++- modules/library.py | 3 ++- modules/plex.py | 4 ++++ plex_meta_manager.py | 37 +++++++++++++++++++++++++++---------- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/modules/config.py b/modules/config.py index 73f78569..1a7ff012 100644 --- a/modules/config.py +++ b/modules/config.py @@ -534,7 +534,8 @@ class ConfigFile: "genre_mapper": None, "radarr_remove_by_tag": None, "sonarr_remove_by_tag": None, - "mass_collection_mode": None + "mass_collection_mode": None, + "genre_collections": None } display_name = f"{params['name']} ({params['mapping_name']})" if lib and "library_name" in lib and lib["library_name"] else params["mapping_name"] @@ -642,6 +643,32 @@ class ConfigFile: params["genre_mapper"][old_genre] = new_genre else: logger.error("Config Error: genre_mapper is blank") + if "genre_collections" in lib["operations"]: + params["genre_collections"] = { + "exclude_genres": [], + "dictionary_variables": {}, + "title_format": "Top <> <>s", + "template": {"smart_filter": {"limit": 50, "sort_by": "critic_rating.desc", "all": {"genre": "<>"}}} + } + if lib["operations"]["genre_collections"] and isinstance(lib["operations"]["genre_collections"], dict): + params["genre_collections"]["exclude_genres"] = check_for_attribute(lib["operations"]["genre_collections"], "exclude_genres", var_type="comma_list", default_is_none=True, save=False) + title_format = check_for_attribute(lib["operations"]["genre_collections"], "title_format", default=params["genre_collections"]["title_format"], save=False) + if "<>" in title_format: + params["genre_collections"]["title_format"] = title_format + else: + logger.error(f"Config Error: using default title_format. <> not in title_format attribute: {title_format} ") + if "dictionary_variables" in lib["operations"]["genre_collections"] and lib["operations"]["genre_collections"]["dictionary_variables"] and isinstance(lib["operations"]["genre_collections"]["dictionary_variables"], dict): + for key, value in lib["operations"]["genre_collections"]["dictionary_variables"].items(): + if isinstance(value, dict): + params["genre_collections"]["dictionary_variables"][key] = value + else: + logger.warning(f"Config Warning: genre_collections dictionary_variables {key} must be a dictionary") + if "template" in lib["operations"]["genre_collections"] and lib["operations"]["genre_collections"]["template"] and isinstance(lib["operations"]["genre_collections"]["template"], dict): + params["genre_collections"]["template"] = lib["operations"]["genre_collections"]["template"] + else: + logger.warning("Config Warning: Using default template for genre_collections") + else: + logger.error("Config Error: genre_collections blank using default settings") else: logger.error("Config Error: operations must be a dictionary") diff --git a/modules/library.py b/modules/library.py index 0be02c8a..d43e4199 100644 --- a/modules/library.py +++ b/modules/library.py @@ -73,6 +73,7 @@ class Library(ABC): self.sonarr_remove_by_tag = params["sonarr_remove_by_tag"] self.mass_collection_mode = params["mass_collection_mode"] self.tmdb_collections = params["tmdb_collections"] + self.genre_collections = params["genre_collections"] self.genre_mapper = params["genre_mapper"] self.error_webhooks = params["error_webhooks"] self.changes_webhooks = params["changes_webhooks"] @@ -88,7 +89,7 @@ class Library(ABC): or self.tmdb_collections or self.radarr_add_all_existing or self.sonarr_add_all_existing self.library_operation = self.tmdb_library_operation or self.delete_unmanaged_collections or self.delete_collections_with_less \ or self.radarr_remove_by_tag or self.sonarr_remove_by_tag or self.mass_collection_mode \ - or self.genre_mapper + or self.genre_collections or self.genre_mapper metadata = [] for file_type, metadata_file in self.metadata_path: if file_type == "Folder": diff --git a/modules/plex.py b/modules/plex.py index 6bfb5e75..d4b80221 100644 --- a/modules/plex.py +++ b/modules/plex.py @@ -537,6 +537,10 @@ class Plex(Library): item.uploadPoster(filepath=image) self.reload(item) + @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex) + def get_genres(self): + return [genre.title for genre in self.Plex.listFilterChoices("genre")] + @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_failed) def get_search_choices(self, search_name, title=True): final_search = search_translation[search_name] if search_name in search_translation else search_name diff --git a/plex_meta_manager.py b/plex_meta_manager.py index d97ac9f2..b782780c 100644 --- a/plex_meta_manager.py +++ b/plex_meta_manager.py @@ -426,6 +426,7 @@ def library_operations(config, library): logger.debug(f"Sonarr Add All Existing: {library.sonarr_add_all_existing}") logger.debug(f"Sonarr Remove by Tag: {library.sonarr_remove_by_tag}") logger.debug(f"TMDb Collections: {library.tmdb_collections}") + logger.debug(f"Genre Collections: {library.genre_collections}") logger.debug(f"Genre Mapper: {library.genre_mapper}") logger.debug(f"TMDb Operation: {library.tmdb_library_operation}") @@ -435,11 +436,11 @@ def library_operations(config, library): item.split() logger.info(util.adjust_space(f"{item.title[:25]:<25} | Splitting")) + tmdb_collections = {} if library.tmdb_library_operation: items = library.get_all() radarr_adds = [] sonarr_adds = [] - tmdb_collections = {} trakt_ratings = config.Trakt.user_ratings(library.is_movie) if library.mass_trakt_rating_update else [] for i, item in enumerate(items, 1): @@ -605,11 +606,15 @@ def library_operations(config, library): except Failed as e: logger.error(e) + if tmdb_collections or library.genre_collections: + logger.info("") + util.separator(f"Starting Automated Collections") + logger.info("") + new_collections = {} + templates = {} + if tmdb_collections: - logger.info("") - util.separator(f"Starting TMDb Collections") - logger.info("") - new_collections = {} + templates["TMDb Collection"] = library.tmdb_collections["template"] for _i, _n in tmdb_collections.items(): if int(_i) not in library.tmdb_collections["exclude_ids"]: template = {"name": "TMDb Collection", "collection_id": _i} @@ -620,11 +625,23 @@ def library_operations(config, library): if _n.endswith(suffix): _n = _n[:-len(suffix)] new_collections[_n.strip()] = {"template": template} - metadata = MetadataFile(config, library, "Data", { - "collections": new_collections, - "templates": {"TMDb Collection": library.tmdb_collections["template"]} - }) - run_collection(config, library, metadata, metadata.get_collections(None)) + + if library.genre_collections: + templates["Genre Collection"] = library.genre_collections["template"] + for genre in library.get_genres(): + if genre not in library.genre_collections["exclude_genres"]: + template = {"name": "Genre Collection", "genre": genre} + for k, v in library.genre_collections["dictionary_variables"]: + if genre in v: + template[k] = v[genre] + title = library.genre_collections["title_format"] + title = title.replace("<>", genre) + if "<>" in title: + title = title.replace("<>", library.type) + new_collections[title] = {"template": template} + + metadata = MetadataFile(config, library, "Data", {"collections": new_collections, "templates": templates}) + run_collection(config, library, metadata, metadata.get_collections(None)) if library.radarr_remove_by_tag: library.Radarr.remove_all_with_tags(library.radarr_remove_by_tag)