From 6df59157e4ac1401d9683b0ce003950a1302d7d8 Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Wed, 8 Dec 2021 20:57:49 -0500 Subject: [PATCH 1/7] #491 fix nonetype error --- modules/config.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/config.py b/modules/config.py index 6ada542e8..86da3e327 100644 --- a/modules/config.py +++ b/modules/config.py @@ -100,7 +100,9 @@ def hooks(attr): changes = [] def hooks(attr): if attr in temp: - changes.extend([w for w in util.get_list(temp.pop(attr), split=False) if w not in changes]) + items = util.get_list(temp.pop(attr), split=False) + if items: + changes.extend([w for w in items if w not in changes]) hooks("collection_creation") hooks("collection_addition") hooks("collection_removal") From 3abfae7f7941c7eb4daba385b0c6484a1aadcdab Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Wed, 8 Dec 2021 22:30:39 -0500 Subject: [PATCH 2/7] fix range error --- modules/builder.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/builder.py b/modules/builder.py index c04275e82..9c8127c0c 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -416,11 +416,19 @@ def scan_text(og_txt, var, var_value): if not match: logger.error(f"Collection Error: range schedule attribute {schedule} invalid must be in the MM/DD-MM/DD format i.e. range(12/01-12/25)") continue - month_start = int(match.group(1)) - day_start = int(match.group(2)) - month_end = int(match.group(3)) - day_end = int(match.group(4)) - check = datetime.strptime(f"{self.current_time.month}/{self.current_time.day}", "%m/%d") + def check_day(_m, _d): + if _m in [1, 3, 5, 7, 8, 10, 12] and _d > 31: + return _m, 31 + elif _m in [4, 6, 9, 11] and _d > 30: + return _m, 30 + elif _m == 2 and _d > 28: + return _m, 28 + else: + return _m, _d + month_start, day_start = check_day(int(match.group(1)), int(match.group(2))) + month_end, day_end = check_day(int(match.group(3)), int(match.group(4))) + month_check, day_check = check_day(self.current_time.month, self.current_time.day) + check = datetime.strptime(f"{month_check}/{day_check}", "%m/%d") start = datetime.strptime(f"{month_start}/{day_start}", "%m/%d") end = datetime.strptime(f"{month_end}/{day_end}", "%m/%d") self.schedule += f"\nScheduled between {util.pretty_months[month_start]} {util.make_ordinal(day_start)} and {util.pretty_months[month_end]} {util.make_ordinal(day_end)}" From af96c2544a3a29b75020f0e90adb7ca2d935dc49 Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Wed, 8 Dec 2021 23:57:00 -0500 Subject: [PATCH 3/7] added deleted to the collection webhook --- modules/builder.py | 3 +++ modules/webhooks.py | 3 ++- plex_meta_manager.py | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/builder.py b/modules/builder.py index 9c8127c0c..6e72ea22c 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -213,6 +213,7 @@ def __init__(self, config, library, metadata, name, no_missing, data): self.current_year = self.current_time.year self.exists = False self.created = False + self.deleted = False methods = {m.lower(): m for m in self.data} @@ -444,6 +445,7 @@ def check_day(_m, _d): try: self.obj = self.library.get_collection(self.name) self.delete_collection() + self.deleted = True suffix = f" and was deleted" except Failed: suffix = f" and could not be found to delete" @@ -2180,6 +2182,7 @@ def send_notifications(self): self.details["collection_changes_webhooks"], self.obj, created=self.created, + deleted=self.deleted, additions=self.notification_additions, removals=self.notification_removals ) diff --git a/modules/webhooks.py b/modules/webhooks.py index 3a67e7c07..c7cfe135b 100644 --- a/modules/webhooks.py +++ b/modules/webhooks.py @@ -70,7 +70,7 @@ def error_hooks(self, text, library=None, collection=None, critical=True): json["collection"] = str(collection) self._request(self.error_webhooks, json) - def collection_hooks(self, webhooks, collection, created=False, additions=None, removals=None): + def collection_hooks(self, webhooks, collection, created=False, deleted=False, additions=None, removals=None): if self.library: thumb = None if collection.thumb and next((f for f in collection.fields if f.name == "thumb"), None): @@ -84,6 +84,7 @@ def collection_hooks(self, webhooks, collection, created=False, additions=None, "type": "movie" if self.library.is_movie else "show", "collection": collection.title, "created": created, + "deleted": deleted, "poster": thumb, "background": art } diff --git a/plex_meta_manager.py b/plex_meta_manager.py index 7b06e9426..cd43667c1 100644 --- a/plex_meta_manager.py +++ b/plex_meta_manager.py @@ -679,7 +679,7 @@ def run_collection(config, library, metadata, requested_collections): logger.info(f"Collection Minimum: {builder.minimum} not met for {mapping_name} Collection") if builder.details["delete_below_minimum"] and builder.obj: builder.delete_collection() - stats["deleted"] += 1 + builder.deleted = True logger.info("") logger.info(f"Collection {builder.obj.title} deleted") @@ -711,6 +711,9 @@ def run_collection(config, library, metadata, requested_collections): library.run_sort.append(builder) # builder.sort_collection() + if builder.deleted: + stats["deleted"] += 1 + if builder.server_preroll is not None: library.set_server_preroll(builder.server_preroll) logger.info("") From 8066a80028c540cb246276aac97fc02614886e7c Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Thu, 9 Dec 2021 00:40:49 -0500 Subject: [PATCH 4/7] added more options to parts collections --- modules/builder.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/modules/builder.py b/modules/builder.py index 6e72ea22c..0eec37aae 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -99,6 +99,11 @@ "sonarr_add", "sonarr_add_existing", "sonarr_folder", "sonarr_monitor", "sonarr_language", "sonarr_series", "sonarr_quality", "sonarr_season", "sonarr_search", "sonarr_cutoff_search", "sonarr_tag" ] +parts_collection_valid = [ + "plex_search", "trakt_list", "trakt_list_details", "collection_mode", "label", "visible_library", "collection_changes_webhooks" + "visible_home", "visible_shared", "show_missing", "save_missing", "missing_only_released", "server_preroll", + "item_lock_background", "item_lock_poster", "item_lock_title", "item_refresh" +] + summary_details + poster_details + background_details + string_details all_filters = [ "actor", "actor.not", "audio_language", "audio_language.not", @@ -160,10 +165,6 @@ "mal_all", "mal_airing", "mal_upcoming", "mal_tv", "mal_movie", "mal_ova", "mal_special", "mal_popular", "mal_favorite", "mal_suggested", "mal_userlist", "mal_season", "mal_genre", "mal_studio" ] -parts_collection_valid = [ - "plex_search", "trakt_list", "trakt_list_details", "collection_mode", "label", "visible_library", - "visible_home", "visible_shared", "show_missing", "save_missing", "missing_only_released" - ] + summary_details + poster_details + background_details + string_details class CollectionBuilder: def __init__(self, config, library, metadata, name, no_missing, data): @@ -506,8 +507,10 @@ def check_day(_m, _d): if "collection_level" in methods: logger.debug("") logger.debug("Validating Method: collection_level") - if self.data[methods["collection_level"]] is None: - raise Failed(f"Collection Warning: collection_level attribute is blank") + if self.library.is_movie: + raise Failed(f"Collection Error: collection_level attribute only works for show libraries") + elif self.data[methods["collection_level"]] is None: + raise Failed(f"Collection Error: collection_level attribute is blank") else: logger.debug(f"Value: {self.data[methods['collection_level']]}") if self.data[methods["collection_level"]].lower() in plex.collection_level_options: From bbf35d8f44620f7f6886bfca3905e8024700540e Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Thu, 9 Dec 2021 01:37:11 -0500 Subject: [PATCH 5/7] #391 added item_tmdb_season_titles Collection detail --- modules/builder.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/builder.py b/modules/builder.py index 0eec37aae..08087f988 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -66,7 +66,7 @@ all_builders = anidb.builders + anilist.builders + flixpatrol.builders + icheckmovies.builders + imdb.builders + \ letterboxd.builders + mal.builders + plex.builders + stevenlu.builders + tautulli.builders + \ tmdb.builders + trakt.builders + tvdb.builders -show_only_builders = ["tmdb_network", "tmdb_show", "tmdb_show_details", "tvdb_show", "tvdb_show_details", "collection_level"] +show_only_builders = ["tmdb_network", "tmdb_show", "tmdb_show_details", "tvdb_show", "tvdb_show_details", "collection_level", "item_tmdb_season_titles"] movie_only_builders = [ "letterboxd_list", "letterboxd_list_details", "icheckmovies_list", "icheckmovies_list_details", "stevenlu_popular", "tmdb_collection", "tmdb_collection_details", "tmdb_movie", "tmdb_movie_details", "tmdb_now_playing", @@ -91,7 +91,7 @@ "collection_level", "collection_minimum", "label"] + boolean_details + string_details collectionless_details = ["collection_order", "plex_collectionless", "label", "label_sync_mode", "test"] + \ poster_details + background_details + summary_details + string_details -item_bool_details = ["item_assets", "revert_overlay", "item_lock_background", "item_lock_poster", "item_lock_title", "item_refresh"] +item_bool_details = ["item_tmdb_season_titles", "item_assets", "revert_overlay", "item_lock_background", "item_lock_poster", "item_lock_title", "item_refresh"] item_details = ["item_label", "item_radarr_tag", "item_sonarr_tag", "item_overlay"] + item_bool_details + list(plex.item_advance_keys.keys()) none_details = ["label.sync", "item_label.sync"] radarr_details = ["radarr_add", "radarr_add_existing", "radarr_folder", "radarr_monitor", "radarr_search", "radarr_availability", "radarr_quality", "radarr_tag"] @@ -1956,16 +1956,26 @@ def update_item_details(self): advance_edits[key] = options[method_data] self.library.edit_item(item, item.title, self.collection_level.capitalize(), advance_edits, advanced=True) + if "item_tmdb_season_titles" in self.item_details and item.ratingKey in self.library.show_rating_key_map: + try: + tmdb_id = self.config.Convert.tvdb_to_tmdb(self.library.show_rating_key_map[item.ratingKey]) + names = {str(s.season_number): s.name for s in self.config.TMDb.get_show(tmdb_id).seasons} + for season in self.library.query(item.seasons): + if str(season.index) in names: + self.library.edit_query(season, {"title.locked": 1, "title.value": names[str(season.index)]}) + except Failed as e: + logger.error(e) + # Locking should come before refreshing since refreshing can change metadata (i.e. if specified to both lock # background/poster and also refreshing, assume that the current background/poster should be kept) if "item_lock_background" in self.item_details: - item.lockArt() + self.library.query(item.lockArt) if "item_lock_poster" in self.item_details: - item.lockPoster() + self.library.query(item.lockPoster) if "item_lock_title" in self.item_details: - item.edit(**{"title.locked": 1}) + self.library.edit_query(item, {"title.locked": 1}) if "item_refresh" in self.item_details: - item.refresh() + self.library.query(item.refresh) if self.library.Radarr and tmdb_paths: if "item_radarr_tag" in self.item_details: From 495b730b30c984b16e482e7b7a160f6bf3206ddd Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Thu, 9 Dec 2021 10:23:51 -0500 Subject: [PATCH 6/7] fix for sonarr/radarr --- modules/builder.py | 8 ++++++-- modules/radarr.py | 4 +++- modules/sonarr.py | 4 +++- plex_meta_manager.py | 8 ++++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/modules/builder.py b/modules/builder.py index 08087f988..f0e11e49b 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -1945,9 +1945,13 @@ def update_item_details(self): self.library.edit_tags("label", item, add_tags=add_tags, remove_tags=remove_tags, sync_tags=sync_tags) path = os.path.dirname(str(item.locations[0])) if self.library.is_movie else str(item.locations[0]) if self.library.Radarr and item.ratingKey in self.library.movie_rating_key_map: - tmdb_paths.append((self.library.movie_rating_key_map[item.ratingKey], f"{path.replace(self.library.Radarr.plex_path, self.library.Radarr.radarr_path)}/")) + path = path.replace(self.library.Radarr.plex_path, self.library.Radarr.radarr_path) + path = path[:-1] if path.endswith(('/', '\\')) else path + tmdb_paths.append((self.library.movie_rating_key_map[item.ratingKey], path)) if self.library.Sonarr and item.ratingKey in self.library.show_rating_key_map: - tvdb_paths.append((self.library.show_rating_key_map[item.ratingKey], f"{path.replace(self.library.Sonarr.plex_path, self.library.Sonarr.sonarr_path)}/")) + path = path.replace(self.library.Sonarr.plex_path, self.library.Sonarr.sonarr_path) + path = path[:-1] if path.endswith(('/', '\\')) else path + tvdb_paths.append((self.library.show_rating_key_map[item.ratingKey], path)) advance_edits = {} for method_name, method_data in self.item_details.items(): if method_name in plex.item_advance_keys: diff --git a/modules/radarr.py b/modules/radarr.py index 2269ad9c5..c6fb1a21f 100644 --- a/modules/radarr.py +++ b/modules/radarr.py @@ -58,8 +58,10 @@ def add_tmdb(self, tmdb_ids, **options): arr_ids = {} for movie in self.api.all_movies(): if movie.path: - arr_paths[movie.path] = movie.tmdbId + arr_paths[movie.path[:-1] if movie.path.endswith(("/", "\\")) else movie.path] = movie.tmdbId arr_ids[movie.tmdbId] = movie + logger.debug(arr_paths) + logger.debug(arr_ids) added = [] exists = [] diff --git a/modules/sonarr.py b/modules/sonarr.py index 0eefe4ce6..00608643d 100644 --- a/modules/sonarr.py +++ b/modules/sonarr.py @@ -84,8 +84,10 @@ def add_tvdb(self, tvdb_ids, **options): arr_ids = {} for series in self.api.all_series(): if series.path: - arr_paths[series.path] = series.tvdbId + arr_paths[series.path[:-1] if series.path.endswith(("/", "\\")) else series.path] = series.tvdbId arr_paths[series.tvdbId] = series + logger.debug(arr_paths) + logger.debug(arr_ids) added = [] exists = [] diff --git a/plex_meta_manager.py b/plex_meta_manager.py index cd43667c1..101378d0b 100644 --- a/plex_meta_manager.py +++ b/plex_meta_manager.py @@ -410,9 +410,13 @@ def library_operations(config, library): path = os.path.dirname(str(item.locations[0])) if library.is_movie else str(item.locations[0]) if library.Radarr and library.radarr_add_all and tmdb_id: - radarr_adds.append((tmdb_id, f"{path.replace(library.Radarr.plex_path, library.Radarr.radarr_path)}/")) + path = path.replace(library.Radarr.plex_path, library.Radarr.radarr_path) + path = path[:-1] if path.endswith(('/', '\\')) else path + radarr_adds.append((tmdb_id, path)) if library.Sonarr and library.sonarr_add_all and tvdb_id: - sonarr_adds.append((tvdb_id, f"{path.replace(library.Sonarr.plex_path, library.Sonarr.sonarr_path)}/")) + path = path.replace(library.Sonarr.plex_path, library.Sonarr.sonarr_path) + path = path[:-1] if path.endswith(('/', '\\')) else path + sonarr_adds.append((tvdb_id, path)) tmdb_item = None if library.tmdb_collections or library.mass_genre_update == "tmdb" or library.mass_audience_rating_update == "tmdb" or library.mass_critic_rating_update == "tmdb": From 9bce9004e379ec738bdb6b74e82f6a01f404e616 Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Thu, 9 Dec 2021 19:37:19 -0500 Subject: [PATCH 7/7] Version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f0df1f7d5..d9ee6574b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.13.2 \ No newline at end of file +1.13.3 \ No newline at end of file