From f4df4d747165f1611b0ea18d5e5fa8b035733651 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Wed, 13 Apr 2022 17:51:10 -0600 Subject: [PATCH 1/6] Handle empty library specification --- modules/PreferenceParser.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/PreferenceParser.py b/modules/PreferenceParser.py index 58335b4b6..536a5c315 100755 --- a/modules/PreferenceParser.py +++ b/modules/PreferenceParser.py @@ -273,11 +273,11 @@ def iterate_series_files(self) -> [Show]: continue # Get library map for this file; error+skip missing library paths - library_map = file_yaml.get('libraries', {}) - if not all('path' in library_map[lib] for lib in library_map): - log.error(f'Libraries in series file "{file_object.resolve()}" ' - f'are missing their "path" attributes.') - continue + if (library_map := file_yaml.get('library', {})): + if not all('path' in library_map[lib] for lib in library_map): + log.error(f'Libraries in series file "{file_object.resolve()}' + f'"are missing their "path" attributes.') + continue # Get font map for this file font_map = file_yaml.get('fonts', {}) From bf289134a408e01d30d6ab03cd2cdc19a10a0dff Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Wed, 13 Apr 2022 17:52:41 -0600 Subject: [PATCH 2/6] Attempt to not use magick prefix first This is a potential fix for some situations where if magick prefix is not valid, and IM is not in docker container, FIleNotFound error would be raised --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index f844c1e4b..09120d4ba 100755 --- a/main.py +++ b/main.py @@ -65,7 +65,7 @@ # Validate that ImageMagick is configured correctly found = False -for prefix in ('magick ', ''): +for prefix in ('', 'magick '): pp.use_magick_prefix = 'magick' in prefix imi = ImageMagickInterface(pp.imagemagick_container) font_output = imi.run_get_output(f'convert -list font') From 902734ea06f40c4505f26b9db033e4e660aa9f44 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Wed, 13 Apr 2022 18:18:11 -0600 Subject: [PATCH 3/6] Update PreferenceParser.py --- modules/PreferenceParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/PreferenceParser.py b/modules/PreferenceParser.py index 536a5c315..90741e440 100755 --- a/modules/PreferenceParser.py +++ b/modules/PreferenceParser.py @@ -273,7 +273,7 @@ def iterate_series_files(self) -> [Show]: continue # Get library map for this file; error+skip missing library paths - if (library_map := file_yaml.get('library', {})): + if (library_map := file_yaml.get('libraries', {})): if not all('path' in library_map[lib] for lib in library_map): log.error(f'Libraries in series file "{file_object.resolve()}' f'"are missing their "path" attributes.') From 6b28b91ab678d7aa207987abfad09444e619b1c6 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Fri, 15 Apr 2022 08:49:53 -0600 Subject: [PATCH 4/6] Add option to skip specials from Sonarr Implements #73 --- modules/PreferenceParser.py | 5 +++++ modules/Show.py | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/modules/PreferenceParser.py b/modules/PreferenceParser.py index 90741e440..1e3f18f88 100755 --- a/modules/PreferenceParser.py +++ b/modules/PreferenceParser.py @@ -56,6 +56,7 @@ def __init__(self, file: Path) -> None: self.use_sonarr = False self.sonarr_url = None self.sonarr_api_key = None + self.sonarr_sync_specials = True self.use_tmdb = False self.tmdb_api_key = None self.tmdb_retry_count = TMDbInterface.BLACKLIST_THRESHOLD @@ -186,6 +187,10 @@ def __parse_yaml(self) -> None: self.sonarr_api_key = self.__yaml['sonarr']['api_key'] self.use_sonarr = True + if self.__is_specified('sonarr', 'sync_specials'): + value = self.__yaml['sonarr']['sync_specials'] + self.sonarr_sync_specials = bool(value) + if self.__is_specified('tmdb'): if not self.__is_specified('tmdb', 'api_key'): log.critical(f'TMDb preferences must contain "api_key"') diff --git a/modules/Show.py b/modules/Show.py index 07231b649..203bea429 100755 --- a/modules/Show.py +++ b/modules/Show.py @@ -73,6 +73,7 @@ def __init__(self, name: str, yaml_dict: dict, library_map: dict, self.library = None self.archive = True self.sonarr_sync = True + self.sync_specials = self.preferences.sonarr_sync_specials self.tmdb_sync = True self.hide_seasons = False self.__episode_range = {} @@ -178,6 +179,9 @@ def __parse_yaml(self): if self.__is_specified('sonarr_sync'): self.sonarr_sync = bool(self.__yaml['sonarr_sync']) + if self.__is_specified('sync_specials'): + self.sync_specials = bool(self.__yaml['sync_specials']) + if self.__is_specified('tmdb_sync'): self.tmdb_sync = bool(self.__yaml['tmdb_sync']) @@ -392,6 +396,13 @@ def query_sonarr(self, sonarr_interface: 'SonarrInterface') -> None: all_episodes, )) + # Filter episodes that are specials if sync_specials is False + if not self.sync_specials: + new_episodes = list(filter( + lambda e: e.season_number != 0, + new_episodes, + )) + # If there are new episodes, add to the datafile, return True if new_episodes: self.file_interface.add_many_entries(new_episodes) From 0e9c3e601d2f03c61d34cb6f99854911f372c2c6 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Fri, 15 Apr 2022 10:45:03 -0600 Subject: [PATCH 5/6] Potential fix for image downloading without local certificate - Moved from using urllib.request.urlretrieve method to using requests.get so fix potential certificate issue - Moved download image method from TMDbInterface class to parent WebInterface class --- modules/TMDbInterface.py | 19 ------------------- modules/WebInterface.py | 24 +++++++++++++++++++++++- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/modules/TMDbInterface.py b/modules/TMDbInterface.py index ade7cf8e7..c72658cb8 100755 --- a/modules/TMDbInterface.py +++ b/modules/TMDbInterface.py @@ -1,7 +1,6 @@ from datetime import datetime, timedelta from pathlib import Path from yaml import dump, safe_load -from urllib.request import urlretrieve from modules.Debug import log from modules.EpisodeInfo import EpisodeInfo @@ -634,24 +633,6 @@ def get_series_logo(self, series_info: SeriesInfo) -> str: return f'https://image.tmdb.org/t/p/original{best["file_path"]}' - def download_image(self, image_url: str, destination: Path) -> None: - """ - Downloads the provided image URL to the destination filepath. - - :param image_url: The image url to download. - :param destination: The destination for the requested image. - """ - - # Make parent folder structure - destination.parent.mkdir(parents=True, exist_ok=True) - - # Download the image and store it in destination - try: - urlretrieve(image_url, destination.resolve()) - except Exception as e: - log.error(f'Cannot download, TMDb errored: "{e}"') - - @staticmethod def manually_download_season(api_key: str, title: str, year: int, season: int, episode_count: int, diff --git a/modules/WebInterface.py b/modules/WebInterface.py index e9ae401cb..19ef24f9e 100755 --- a/modules/WebInterface.py +++ b/modules/WebInterface.py @@ -54,4 +54,26 @@ def _get(self, url: str, params: dict) -> dict: self.__cached_results.pop(0) # Return latest result - return self.__cached_results[-1] \ No newline at end of file + return self.__cached_results[-1] + + + def download_image(self, image_url: str, destination: 'Path') -> None: + """ + Downloads the provided image URL to the destination filepath. + + :param image_url: The image url to download. + :param destination: The destination for the requested image. + """ + + # Make parent folder structure + destination.parent.mkdir(parents=True, exist_ok=True) + + try: + with destination.open('wb') as file_handle: + file_handle.write(get(image_url).content) + log.debug(f'downloaded {image_url} to {destination}') + except Exception as e: + log.error(f'Cannot download image, error: "{e}"') + + + \ No newline at end of file From fb8253282e27eaadd1c15cea05f8820a2452b3c2 Mon Sep 17 00:00:00 2001 From: Collin Heist Date: Fri, 15 Apr 2022 11:02:47 -0600 Subject: [PATCH 6/6] Change TMDb default blacklist threshold to 5 --- modules/TMDbInterface.py | 2 +- modules/WebInterface.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/TMDbInterface.py b/modules/TMDbInterface.py index c72658cb8..d62aad8e6 100755 --- a/modules/TMDbInterface.py +++ b/modules/TMDbInterface.py @@ -20,7 +20,7 @@ class TMDbInterface(WebInterface): API_BASE_URL = 'https://api.themoviedb.org/3/' """Default for how many failed requests lead to a blacklisted entry""" - BLACKLIST_THRESHOLD = 3 + BLACKLIST_THRESHOLD = 5 """Generic translated episode format strings for each language code""" GENERIC_TITLE_FORMATS = { diff --git a/modules/WebInterface.py b/modules/WebInterface.py index 19ef24f9e..cadc6c3b4 100755 --- a/modules/WebInterface.py +++ b/modules/WebInterface.py @@ -59,7 +59,7 @@ def _get(self, url: str, params: dict) -> dict: def download_image(self, image_url: str, destination: 'Path') -> None: """ - Downloads the provided image URL to the destination filepath. + Download the provided image URL to the destination filepath. :param image_url: The image url to download. :param destination: The destination for the requested image. @@ -68,6 +68,7 @@ def download_image(self, image_url: str, destination: 'Path') -> None: # Make parent folder structure destination.parent.mkdir(parents=True, exist_ok=True) + # Attempt to download the image, if an error happens log to user try: with destination.open('wb') as file_handle: file_handle.write(get(image_url).content)