diff --git a/helpers/misc.py b/helpers/misc.py new file mode 100644 index 0000000..6e0202e --- /dev/null +++ b/helpers/misc.py @@ -0,0 +1,46 @@ +from misc.log import logger + +log = logger.get_logger(__name__) + + +def get_response_dict(response, key_field=None, key_value=None): + found_response = None + try: + if isinstance(response, list): + if not key_field or not key_value: + found_response = response[0] + else: + for result in response: + if isinstance(result, dict) and key_field in result and result[key_field] == key_value: + found_response = result + break + + if not found_response: + log.error("Unable to find a result with key %s where the value is %s", key_field, key_value) + + elif isinstance(response, dict): + found_response = response + else: + log.error("Unexpected response instance type of %s for %s", type(response).__name__, response) + + except Exception: + log.exception("Exception determining response for %s: ", response) + return found_response + + +def backoff_handler(details): + log.warning("Backing off {wait:0.1f} seconds afters {tries} tries " + "calling function {target} with args {args} and kwargs " + "{kwargs}".format(**details)) + + +def dict_merge(dct, merge_dct): + for k, v in merge_dct.items(): + import collections + + if k in dct and isinstance(dct[k], dict) and isinstance(merge_dct[k], collections.Mapping): + dict_merge(dct[k], merge_dct[k]) + else: + dct[k] = merge_dct[k] + + return dct diff --git a/helpers/radarr.py b/helpers/radarr.py new file mode 100644 index 0000000..c8732f2 --- /dev/null +++ b/helpers/radarr.py @@ -0,0 +1,50 @@ +from misc.log import logger + +log = logger.get_logger(__name__) + + +def movies_to_tmdb_dict(radarr_movies): + movies = {} + try: + for tmp in radarr_movies: + if 'tmdbId' not in tmp: + log.debug("Could not handle movie: %s", tmp['title']) + continue + movies[tmp['tmdbId']] = tmp + return movies + except Exception: + log.exception("Exception processing Radarr movies to TMDB dict: ") + return None + + +def remove_existing_movies(radarr_movies, trakt_movies): + new_movies_list = [] + + if not radarr_movies or not trakt_movies: + log.error("Inappropriate parameters were supplied") + return None + + try: + # turn radarr movies result into a dict with tmdb id as keys + processed_movies = movies_to_tmdb_dict(radarr_movies) + if not processed_movies: + return None + + # loop list adding to movies that do not already exist + for tmp in trakt_movies: + if 'movie' not in tmp or 'ids' not in tmp['movie'] or 'tmdb' not in tmp['movie']['ids']: + log.debug("Skipping movie because it did not have required fields: %s", tmp) + continue + # check if movie exists in processed_movies + if tmp['movie']['ids']['tmdb'] in processed_movies: + log.debug("Removing existing movie: %s", tmp['movie']['title']) + continue + + new_movies_list.append(tmp) + + log.debug("Filtered %d Trakt movies to %d movies that weren't already in Radarr", len(trakt_movies), + len(new_movies_list)) + return new_movies_list + except Exception: + log.exception("Exception removing existing movies from Trakt list: ") + return None diff --git a/helpers/sonarr.py b/helpers/sonarr.py new file mode 100644 index 0000000..52c2f91 --- /dev/null +++ b/helpers/sonarr.py @@ -0,0 +1,81 @@ +from misc.log import logger + +log = logger.get_logger(__name__) + + +def series_tag_id_from_network(profile_tags, network_tags, network): + try: + tags = [] + for tag_name, tag_networks in network_tags.items(): + for tag_network in tag_networks: + if tag_network.lower() in network.lower() and tag_name.lower() in profile_tags: + log.debug("Using %s tag for network: %s", tag_name, network) + tags.append(profile_tags[tag_name.lower()]) + if tags: + return tags + except Exception: + log.exception("Exception determining tag to use for network %s: ", network) + return None + + +def readable_tag_from_ids(profile_tag_ids, chosen_tag_ids): + try: + if not chosen_tag_ids: + return None + + tags = [] + for tag_name, tag_id in profile_tag_ids.items(): + if tag_id in chosen_tag_ids: + tags.append(tag_name) + if tags: + return tags + except Exception: + log.exception("Exception building readable tag name list from ids %s: ", chosen_tag_ids) + return None + + +def series_to_tvdb_dict(sonarr_series): + series = {} + try: + for tmp in sonarr_series: + if 'tvdbId' not in tmp: + log.debug("Could not handle show: %s", tmp['title']) + continue + series[tmp['tvdbId']] = tmp + return series + except Exception: + log.exception("Exception processing Sonarr shows to TVDB dict: ") + return None + + +def remove_existing_series(sonarr_series, trakt_series): + new_series_list = [] + + if not sonarr_series or not trakt_series: + log.error("Inappropriate parameters were supplied") + return None + + try: + # turn sonarr series result into a dict with tvdb id as keys + processed_series = series_to_tvdb_dict(sonarr_series) + if not processed_series: + return None + + # loop list adding to series that do not already exist + for tmp in trakt_series: + if 'show' not in tmp or 'ids' not in tmp['show'] or 'tvdb' not in tmp['show']['ids']: + log.debug("Skipping show because it did not have required fields: %s", tmp) + continue + # check if show exists in processed_series + if tmp['show']['ids']['tvdb'] in processed_series: + log.debug("Removing existing show: %s", tmp['show']['title']) + continue + + new_series_list.append(tmp) + + log.debug("Filtered %d Trakt shows to %d shows that weren't already in Sonarr", len(trakt_series), + len(new_series_list)) + return new_series_list + except Exception: + log.exception("Exception removing existing shows from Trakt list: ") + return None diff --git a/misc/str.py b/helpers/str.py similarity index 100% rename from misc/str.py rename to helpers/str.py diff --git a/helpers/trakt.py b/helpers/trakt.py new file mode 100644 index 0000000..be6df47 --- /dev/null +++ b/helpers/trakt.py @@ -0,0 +1,249 @@ +from helpers import str as misc_str +from misc.log import logger + +log = logger.get_logger(__name__) + + +def blacklisted_show_genre(show, genres): + blacklisted = False + try: + if not show['show']['genres']: + log.debug("%s was blacklisted because it had no genres", show['show']['title']) + blacklisted = True + else: + for genre in genres: + if genre.lower() in show['show']['genres']: + log.debug("%s was blacklisted because it has genre: %s", show['show']['title'], genre) + blacklisted = True + break + + except Exception: + log.exception("Exception determining if show has a blacklisted genre %s: ", show) + return blacklisted + + +def blacklisted_show_year(show, earliest_year, latest_year): + blacklisted = False + try: + year = misc_str.get_year_from_timestamp(show['show']['first_aired']) + if not year: + log.debug("%s was blacklisted due to having an unknown first_aired date", show['show']['title']) + blacklisted = True + else: + if year < earliest_year or year > latest_year: + log.debug("%s was blacklisted because it first aired in: %d", show['show']['title'], year) + blacklisted = True + except Exception: + log.exception("Exception determining if show is within min_year and max_year range %s:", show) + return blacklisted + + +def blacklisted_show_country(show, allowed_countries): + blacklisted = False + try: + if not show['show']['country']: + log.debug("%s was blacklisted because it had no country", show['show']['title']) + blacklisted = True + else: + if show['show']['country'].lower() not in allowed_countries: + log.debug("%s was blacklisted because it's from country: %s", show['show']['title'], + show['show']['country']) + blacklisted = True + + except Exception: + log.exception("Exception determining if show was from an allowed country %s: ", show) + return blacklisted + + +def blacklisted_show_network(show, networks): + blacklisted = False + try: + if not show['show']['network']: + log.debug("%s was blacklisted because it had no network", show['show']['title']) + blacklisted = True + else: + for network in networks: + if network.lower() in show['show']['network'].lower(): + log.debug("%s was blacklisted because it's from network: %s", show['show']['title'], + show['show']['network']) + blacklisted = True + break + + except Exception: + log.exception("Exception determining if show is from a blacklisted network %s: ", show) + return blacklisted + + +def blacklisted_show_runtime(show, lowest_runtime): + blacklisted = False + try: + if not show['show']['runtime'] or not isinstance(show['show']['runtime'], int): + log.debug("%s was blacklisted because it had no runtime", show['show']['title']) + blacklisted = True + elif int(show['show']['runtime']) < lowest_runtime: + log.debug("%s was blacklisted because it had a runtime of: %d", show['show']['title'], + show['show']['runtime']) + blacklisted = True + + except Exception: + log.exception("Exception determining if show had sufficient runtime %s: ", show) + return blacklisted + + +def blacklisted_show_id(show, blacklisted_ids): + blacklisted = False + try: + if not show['show']['ids']['tvdb'] or not isinstance(show['show']['ids']['tvdb'], int): + log.debug("%s was blacklisted because it had an invalid tvdb id", show['show']['title']) + blacklisted = True + elif show['show']['ids']['tvdb'] in blacklisted_ids: + log.debug("%s was blacklisted because it had a blacklisted tvdb id of: %d", show['show']['title'], + show['show']['ids']['tvdb']) + blacklisted = True + + except Exception: + log.exception("Exception determining if show had a blacklisted tvdb id %s: ", show) + return blacklisted + + +def is_show_blacklisted(show, blacklist_settings): + blacklisted = False + try: + if blacklisted_show_year(show, blacklist_settings.blacklisted_min_year, + blacklist_settings.blacklisted_max_year): + blacklisted = True + if blacklisted_show_country(show, blacklist_settings.allowed_countries): + blacklisted = True + if blacklisted_show_genre(show, blacklist_settings.blacklisted_genres): + blacklisted = True + if blacklisted_show_network(show, blacklist_settings.blacklisted_networks): + blacklisted = True + if blacklisted_show_runtime(show, blacklist_settings.blacklisted_min_runtime): + blacklisted = True + if blacklisted_show_id(show, blacklist_settings.blacklisted_tvdb_ids): + blacklisted = True + except Exception: + log.exception("Exception determining if show was blacklisted %s: ", show) + return blacklisted + + +def blacklisted_movie_genre(movie, genres): + blacklisted = False + try: + if not movie['movie']['genres']: + log.debug("%s was blacklisted because it had no genres", movie['movie']['title']) + blacklisted = True + else: + for genre in genres: + if genre.lower() in movie['movie']['genres']: + log.debug("%s was blacklisted because it has genre: %s", movie['movie']['title'], genre) + blacklisted = True + break + + except Exception: + log.exception("Exception determining if movie has a blacklisted genre %s: ", movie) + return blacklisted + + +def blacklisted_movie_year(movie, earliest_year, latest_year): + blacklisted = False + try: + year = movie['movie']['year'] + if year is None or not isinstance(year, int): + log.debug("%s was blacklisted due to having an unknown year", movie['movie']['title']) + blacklisted = True + else: + if int(year) < earliest_year or int(year) > latest_year: + log.debug("%s was blacklisted because it's year is: %d", movie['movie']['title'], int(year)) + blacklisted = True + except Exception: + log.exception("Exception determining if movie is within min_year and max_year ranger %s:", movie) + return blacklisted + + +def blacklisted_movie_country(movie, allowed_countries): + blacklisted = False + try: + if not movie['movie']['country']: + log.debug("%s was blacklisted because it had no country", movie['movie']['title']) + blacklisted = True + else: + if movie['movie']['country'].lower() not in allowed_countries: + log.debug("%s was blacklisted because it's from country: %s", movie['movie']['title'], + movie['movie']['country']) + blacklisted = True + + except Exception: + log.exception("Exception determining if movie was from an allowed country %s: ", movie) + return blacklisted + + +def blacklisted_movie_title(movie, blacklisted_keywords): + blacklisted = False + try: + if not movie['movie']['title']: + log.debug("Blacklisted movie because it had no title: %s", movie) + blacklisted = True + else: + for keyword in blacklisted_keywords: + if keyword.lower() in movie['movie']['title'].lower(): + log.debug("%s was blacklisted because it had title keyword: %s", movie['movie']['title'], keyword) + blacklisted = True + break + + except Exception: + log.exception("Exception determining if movie had a blacklisted title %s: ", movie) + return blacklisted + + +def blacklisted_movie_runtime(movie, lowest_runtime): + blacklisted = False + try: + if not movie['movie']['runtime'] or not isinstance(movie['movie']['runtime'], int): + log.debug("%s was blacklisted because it had no runtime", movie['movie']['title']) + blacklisted = True + elif int(movie['movie']['runtime']) < lowest_runtime: + log.debug("%s was blacklisted because it had a runtime of: %d", movie['movie']['title'], + movie['movie']['runtime']) + blacklisted = True + + except Exception: + log.exception("Exception determining if movie had sufficient runtime %s: ", movie) + return blacklisted + + +def blacklisted_movie_id(movie, blacklisted_ids): + blacklisted = False + try: + if not movie['movie']['ids']['tmdb'] or not isinstance(movie['movie']['ids']['tmdb'], int): + log.debug("%s was blacklisted because it had an invalid tmdb id", movie['movie']['title']) + blacklisted = True + elif movie['movie']['ids']['tmdb'] in blacklisted_ids: + log.debug("%s was blacklisted because it had a blacklisted tmdb id of: %d", movie['movie']['title'], + movie['movie']['ids']['tmdb']) + blacklisted = True + + except Exception: + log.exception("Exception determining if show had a blacklisted tmdb id %s: ", movie) + return blacklisted + + +def is_movie_blacklisted(movie, blacklist_settings): + blacklisted = False + try: + if blacklisted_movie_title(movie, blacklist_settings.blacklist_title_keywords): + blacklisted = True + if blacklisted_movie_year(movie, blacklist_settings.blacklisted_min_year, + blacklist_settings.blacklisted_max_year): + blacklisted = True + if blacklisted_movie_country(movie, blacklist_settings.allowed_countries): + blacklisted = True + if blacklisted_movie_genre(movie, blacklist_settings.blacklisted_genres): + blacklisted = True + if blacklisted_movie_runtime(movie, blacklist_settings.blacklisted_min_runtime): + blacklisted = True + if blacklisted_movie_id(movie, blacklist_settings.blacklisted_tmdb_ids): + blacklisted = True + except Exception: + log.exception("Exception determining if movie was blacklisted %s: ", movie) + return blacklisted diff --git a/media/pvr.py b/media/pvr.py index 8221ae7..f51d827 100644 --- a/media/pvr.py +++ b/media/pvr.py @@ -4,9 +4,9 @@ from abc import ABC, abstractmethod import backoff import requests -from misc import helpers -from misc import str as misc_str -from misc.helpers import backoff_handler +from helpers.misc import backoff_handler +from helpers import str as misc_str +from helpers import misc from misc.log import logger log = logger.get_logger(__name__) @@ -120,7 +120,7 @@ class PVR(ABC): response_json = None if 'json' in req.headers['Content-Type'].lower(): - response_json = helpers.get_response_dict(req.json(), identifier_field, identifier) + response_json = misc.get_response_dict(req.json(), identifier_field, identifier) if (req.status_code == 201 or req.status_code == 200) \ and (response_json and identifier_field in response_json) \ diff --git a/media/radarr.py b/media/radarr.py index 5bb61fa..7d52f92 100644 --- a/media/radarr.py +++ b/media/radarr.py @@ -1,7 +1,7 @@ import backoff +from helpers.misc import backoff_handler, dict_merge from media.pvr import PVR -from misc.helpers import backoff_handler, dict_merge from misc.log import logger log = logger.get_logger(__name__) diff --git a/media/sonarr.py b/media/sonarr.py index 6f287f9..637e5ad 100644 --- a/media/sonarr.py +++ b/media/sonarr.py @@ -2,10 +2,10 @@ import os.path import backoff import requests +from helpers.misc import backoff_handler, dict_merge +from helpers import str as misc_str from media.pvr import PVR -from misc import str as misc_str -from misc.helpers import backoff_handler, dict_merge from misc.log import logger log = logger.get_logger(__name__) diff --git a/media/trakt.py b/media/trakt.py index a2c67c5..8ea69ab 100644 --- a/media/trakt.py +++ b/media/trakt.py @@ -3,7 +3,7 @@ import time import backoff import requests -from misc.helpers import backoff_handler +from helpers.misc import backoff_handler from misc.log import logger log = logger.get_logger(__name__) diff --git a/misc/helpers.py b/misc/helpers.py deleted file mode 100644 index e4f654a..0000000 --- a/misc/helpers.py +++ /dev/null @@ -1,430 +0,0 @@ -from misc import str as misc_str -from misc.log import logger - -log = logger.get_logger(__name__) - - -############################################################ -# SONARR -############################################################ - -def sonarr_series_tag_id_from_network(profile_tags, network_tags, network): - try: - tags = [] - for tag_name, tag_networks in network_tags.items(): - for tag_network in tag_networks: - if tag_network.lower() in network.lower() and tag_name.lower() in profile_tags: - log.debug("Using %s tag for network: %s", tag_name, network) - tags.append(profile_tags[tag_name.lower()]) - if tags: - return tags - except Exception: - log.exception("Exception determining tag to use for network %s: ", network) - return None - - -def sonarr_readable_tag_from_ids(profile_tag_ids, chosen_tag_ids): - try: - if not chosen_tag_ids: - return None - - tags = [] - for tag_name, tag_id in profile_tag_ids.items(): - if tag_id in chosen_tag_ids: - tags.append(tag_name) - if tags: - return tags - except Exception: - log.exception("Exception building readable tag name list from ids %s: ", chosen_tag_ids) - return None - - -def sonarr_series_to_tvdb_dict(sonarr_series): - series = {} - try: - for tmp in sonarr_series: - if 'tvdbId' not in tmp: - log.debug("Could not handle show: %s", tmp['title']) - continue - series[tmp['tvdbId']] = tmp - return series - except Exception: - log.exception("Exception processing Sonarr shows to TVDB dict: ") - return None - - -def sonarr_remove_existing_series(sonarr_series, trakt_series): - new_series_list = [] - - if not sonarr_series or not trakt_series: - log.error("Inappropriate parameters were supplied") - return None - - try: - # turn sonarr series result into a dict with tvdb id as keys - processed_series = sonarr_series_to_tvdb_dict(sonarr_series) - if not processed_series: - return None - - # loop list adding to series that do not already exist - for tmp in trakt_series: - if 'show' not in tmp or 'ids' not in tmp['show'] or 'tvdb' not in tmp['show']['ids']: - log.debug("Skipping show because it did not have required fields: %s", tmp) - continue - # check if show exists in processed_series - if tmp['show']['ids']['tvdb'] in processed_series: - log.debug("Removing existing show: %s", tmp['show']['title']) - continue - - new_series_list.append(tmp) - - log.debug("Filtered %d Trakt shows to %d shows that weren't already in Sonarr", len(trakt_series), - len(new_series_list)) - return new_series_list - except Exception: - log.exception("Exception removing existing shows from Trakt list: ") - return None - - -def trakt_blacklisted_show_genre(show, genres): - blacklisted = False - try: - if not show['show']['genres']: - log.debug("%s was blacklisted because it had no genres", show['show']['title']) - blacklisted = True - else: - for genre in genres: - if genre.lower() in show['show']['genres']: - log.debug("%s was blacklisted because it has genre: %s", show['show']['title'], genre) - blacklisted = True - break - - except Exception: - log.exception("Exception determining if show has a blacklisted genre %s: ", show) - return blacklisted - - -def trakt_blacklisted_show_year(show, earliest_year, latest_year): - blacklisted = False - try: - year = misc_str.get_year_from_timestamp(show['show']['first_aired']) - if not year: - log.debug("%s was blacklisted due to having an unknown first_aired date", show['show']['title']) - blacklisted = True - else: - if year < earliest_year or year > latest_year: - log.debug("%s was blacklisted because it first aired in: %d", show['show']['title'], year) - blacklisted = True - except Exception: - log.exception("Exception determining if show is within min_year and max_year range %s:", show) - return blacklisted - - -def trakt_blacklisted_show_country(show, allowed_countries): - blacklisted = False - try: - if not show['show']['country']: - log.debug("%s was blacklisted because it had no country", show['show']['title']) - blacklisted = True - else: - if show['show']['country'].lower() not in allowed_countries: - log.debug("%s was blacklisted because it's from country: %s", show['show']['title'], - show['show']['country']) - blacklisted = True - - except Exception: - log.exception("Exception determining if show was from an allowed country %s: ", show) - return blacklisted - - -def trakt_blacklisted_show_network(show, networks): - blacklisted = False - try: - if not show['show']['network']: - log.debug("%s was blacklisted because it had no network", show['show']['title']) - blacklisted = True - else: - for network in networks: - if network.lower() in show['show']['network'].lower(): - log.debug("%s was blacklisted because it's from network: %s", show['show']['title'], - show['show']['network']) - blacklisted = True - break - - except Exception: - log.exception("Exception determining if show is from a blacklisted network %s: ", show) - return blacklisted - - -def trakt_blacklisted_show_runtime(show, lowest_runtime): - blacklisted = False - try: - if not show['show']['runtime'] or not isinstance(show['show']['runtime'], int): - log.debug("%s was blacklisted because it had no runtime", show['show']['title']) - blacklisted = True - elif int(show['show']['runtime']) < lowest_runtime: - log.debug("%s was blacklisted because it had a runtime of: %d", show['show']['title'], - show['show']['runtime']) - blacklisted = True - - except Exception: - log.exception("Exception determining if show had sufficient runtime %s: ", show) - return blacklisted - - -def trakt_blacklisted_show_id(show, blacklisted_ids): - blacklisted = False - try: - if not show['show']['ids']['tvdb'] or not isinstance(show['show']['ids']['tvdb'], int): - log.debug("%s was blacklisted because it had an invalid tvdb id", show['show']['title']) - blacklisted = True - elif show['show']['ids']['tvdb'] in blacklisted_ids: - log.debug("%s was blacklisted because it had a blacklisted tvdb id of: %d", show['show']['title'], - show['show']['ids']['tvdb']) - blacklisted = True - - except Exception: - log.exception("Exception determining if show had a blacklisted tvdb id %s: ", show) - return blacklisted - - -def trakt_is_show_blacklisted(show, blacklist_settings): - blacklisted = False - try: - if trakt_blacklisted_show_year(show, blacklist_settings.blacklisted_min_year, - blacklist_settings.blacklisted_max_year): - blacklisted = True - if trakt_blacklisted_show_country(show, blacklist_settings.allowed_countries): - blacklisted = True - if trakt_blacklisted_show_genre(show, blacklist_settings.blacklisted_genres): - blacklisted = True - if trakt_blacklisted_show_network(show, blacklist_settings.blacklisted_networks): - blacklisted = True - if trakt_blacklisted_show_runtime(show, blacklist_settings.blacklisted_min_runtime): - blacklisted = True - if trakt_blacklisted_show_id(show, blacklist_settings.blacklisted_tvdb_ids): - blacklisted = True - except Exception: - log.exception("Exception determining if show was blacklisted %s: ", show) - return blacklisted - - -############################################################ -# RADARR -############################################################ - -def radarr_movies_to_tmdb_dict(radarr_movies): - movies = {} - try: - for tmp in radarr_movies: - if 'tmdbId' not in tmp: - log.debug("Could not handle movie: %s", tmp['title']) - continue - movies[tmp['tmdbId']] = tmp - return movies - except Exception: - log.exception("Exception processing Radarr movies to TMDB dict: ") - return None - - -def radarr_remove_existing_movies(radarr_movies, trakt_movies): - new_movies_list = [] - - if not radarr_movies or not trakt_movies: - log.error("Inappropriate parameters were supplied") - return None - - try: - # turn radarr movies result into a dict with tmdb id as keys - processed_movies = radarr_movies_to_tmdb_dict(radarr_movies) - if not processed_movies: - return None - - # loop list adding to movies that do not already exist - for tmp in trakt_movies: - if 'movie' not in tmp or 'ids' not in tmp['movie'] or 'tmdb' not in tmp['movie']['ids']: - log.debug("Skipping movie because it did not have required fields: %s", tmp) - continue - # check if movie exists in processed_movies - if tmp['movie']['ids']['tmdb'] in processed_movies: - log.debug("Removing existing movie: %s", tmp['movie']['title']) - continue - - new_movies_list.append(tmp) - - log.debug("Filtered %d Trakt movies to %d movies that weren't already in Radarr", len(trakt_movies), - len(new_movies_list)) - return new_movies_list - except Exception: - log.exception("Exception removing existing movies from Trakt list: ") - return None - - -def trakt_blacklisted_movie_genre(movie, genres): - blacklisted = False - try: - if not movie['movie']['genres']: - log.debug("%s was blacklisted because it had no genres", movie['movie']['title']) - blacklisted = True - else: - for genre in genres: - if genre.lower() in movie['movie']['genres']: - log.debug("%s was blacklisted because it has genre: %s", movie['movie']['title'], genre) - blacklisted = True - break - - except Exception: - log.exception("Exception determining if movie has a blacklisted genre %s: ", movie) - return blacklisted - - -def trakt_blacklisted_movie_year(movie, earliest_year, latest_year): - blacklisted = False - try: - year = movie['movie']['year'] - if year is None or not isinstance(year, int): - log.debug("%s was blacklisted due to having an unknown year", movie['movie']['title']) - blacklisted = True - else: - if int(year) < earliest_year or int(year) > latest_year: - log.debug("%s was blacklisted because it's year is: %d", movie['movie']['title'], int(year)) - blacklisted = True - except Exception: - log.exception("Exception determining if movie is within min_year and max_year ranger %s:", movie) - return blacklisted - - -def trakt_blacklisted_movie_country(movie, allowed_countries): - blacklisted = False - try: - if not movie['movie']['country']: - log.debug("%s was blacklisted because it had no country", movie['movie']['title']) - blacklisted = True - else: - if movie['movie']['country'].lower() not in allowed_countries: - log.debug("%s was blacklisted because it's from country: %s", movie['movie']['title'], - movie['movie']['country']) - blacklisted = True - - except Exception: - log.exception("Exception determining if movie was from an allowed country %s: ", movie) - return blacklisted - - -def trakt_blacklisted_movie_title(movie, blacklisted_keywords): - blacklisted = False - try: - if not movie['movie']['title']: - log.debug("Blacklisted movie because it had no title: %s", movie) - blacklisted = True - else: - for keyword in blacklisted_keywords: - if keyword.lower() in movie['movie']['title'].lower(): - log.debug("%s was blacklisted because it had title keyword: %s", movie['movie']['title'], keyword) - blacklisted = True - break - - except Exception: - log.exception("Exception determining if movie had a blacklisted title %s: ", movie) - return blacklisted - - -def trakt_blacklisted_movie_runtime(movie, lowest_runtime): - blacklisted = False - try: - if not movie['movie']['runtime'] or not isinstance(movie['movie']['runtime'], int): - log.debug("%s was blacklisted because it had no runtime", movie['movie']['title']) - blacklisted = True - elif int(movie['movie']['runtime']) < lowest_runtime: - log.debug("%s was blacklisted because it had a runtime of: %d", movie['movie']['title'], - movie['movie']['runtime']) - blacklisted = True - - except Exception: - log.exception("Exception determining if movie had sufficient runtime %s: ", movie) - return blacklisted - - -def trakt_blacklisted_movie_id(movie, blacklisted_ids): - blacklisted = False - try: - if not movie['movie']['ids']['tmdb'] or not isinstance(movie['movie']['ids']['tmdb'], int): - log.debug("%s was blacklisted because it had an invalid tmdb id", movie['movie']['title']) - blacklisted = True - elif movie['movie']['ids']['tmdb'] in blacklisted_ids: - log.debug("%s was blacklisted because it had a blacklisted tmdb id of: %d", movie['movie']['title'], - movie['movie']['ids']['tmdb']) - blacklisted = True - - except Exception: - log.exception("Exception determining if show had a blacklisted tmdb id %s: ", movie) - return blacklisted - - -def trakt_is_movie_blacklisted(movie, blacklist_settings): - blacklisted = False - try: - if trakt_blacklisted_movie_title(movie, blacklist_settings.blacklist_title_keywords): - blacklisted = True - if trakt_blacklisted_movie_year(movie, blacklist_settings.blacklisted_min_year, - blacklist_settings.blacklisted_max_year): - blacklisted = True - if trakt_blacklisted_movie_country(movie, blacklist_settings.allowed_countries): - blacklisted = True - if trakt_blacklisted_movie_genre(movie, blacklist_settings.blacklisted_genres): - blacklisted = True - if trakt_blacklisted_movie_runtime(movie, blacklist_settings.blacklisted_min_runtime): - blacklisted = True - if trakt_blacklisted_movie_id(movie, blacklist_settings.blacklisted_tmdb_ids): - blacklisted = True - except Exception: - log.exception("Exception determining if movie was blacklisted %s: ", movie) - return blacklisted - - -############################################################ -# MISC -############################################################ - - -def get_response_dict(response, key_field=None, key_value=None): - found_response = None - try: - if isinstance(response, list): - if not key_field or not key_value: - found_response = response[0] - else: - for result in response: - if isinstance(result, dict) and key_field in result and result[key_field] == key_value: - found_response = result - break - - if not found_response: - log.error("Unable to find a result with key %s where the value is %s", key_field, key_value) - - elif isinstance(response, dict): - found_response = response - else: - log.error("Unexpected response instance type of %s for %s", type(response).__name__, response) - - except Exception: - log.exception("Exception determining response for %s: ", response) - return found_response - - -def backoff_handler(details): - log.warning("Backing off {wait:0.1f} seconds afters {tries} tries " - "calling function {target} with args {args} and kwargs " - "{kwargs}".format(**details)) - - -def dict_merge(dct, merge_dct): - for k, v in merge_dct.items(): - import collections - - if k in dct and isinstance(dct[k], dict) and isinstance(merge_dct[k], collections.Mapping): - dict_merge(dct[k], merge_dct[k]) - else: - dct[k] = merge_dct[k] - - return dct diff --git a/traktarr.py b/traktarr.py index 21af418..f7f5378 100755 --- a/traktarr.py +++ b/traktarr.py @@ -80,7 +80,7 @@ def trakt_authentication(): def show(show_id, folder=None, no_search=False): from media.sonarr import Sonarr from media.trakt import Trakt - from misc import helpers + from helpers import sonarr as sonarr_helper # replace sonarr root_folder if folder is supplied if folder: @@ -128,17 +128,17 @@ def show(show_id, folder=None, no_search=False): trakt_show['year']) # determine which tags to use when adding this series - use_tags = helpers.sonarr_series_tag_id_from_network(profile_tags, cfg.sonarr.tags, + use_tags = sonarr_helper.series_tag_id_from_network(profile_tags, cfg.sonarr.tags, trakt_show['network']) # add show to sonarr if sonarr.add_series(trakt_show['ids']['tvdb'], trakt_show['title'], trakt_show['ids']['slug'], profile_id, cfg.sonarr.root_folder, use_tags, not no_search): log.info("ADDED %s (%d) with tags: %s", trakt_show['title'], trakt_show['year'], - helpers.sonarr_readable_tag_from_ids(profile_tags, use_tags)) + sonarr_helper.readable_tag_from_ids(profile_tags, use_tags)) else: log.error("FAILED adding %s (%d) with tags: %s", trakt_show['title'], trakt_show['year'], - helpers.sonarr_readable_tag_from_ids(profile_tags, use_tags)) + sonarr_helper.readable_tag_from_ids(profile_tags, use_tags)) return @@ -159,7 +159,8 @@ def shows(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_sea authenticate_user=None): from media.sonarr import Sonarr from media.trakt import Trakt - from misc import helpers + from helpers import sonarr as sonarr_helper + from helpers import trakt as trakt_helper added_shows = 0 @@ -250,7 +251,7 @@ def shows(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_sea log.info("Retrieved Trakt %s shows list, shows found: %d", list_type, len(trakt_series_list)) # build filtered series list without series that exist in sonarr - processed_series_list = helpers.sonarr_remove_existing_series(sonarr_series_list, trakt_series_list) + processed_series_list = sonarr_helper.remove_existing_series(sonarr_series_list, trakt_series_list) if processed_series_list is None: log.error("Aborting due to failure to remove existing Sonarr shows from retrieved Trakt shows list") if notifications: @@ -276,26 +277,26 @@ def shows(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_sea continue # check if series passes out blacklist criteria inspection - if not helpers.trakt_is_show_blacklisted(series, cfg.filters.shows): + if not trakt_helper.is_show_blacklisted(series, cfg.filters.shows): log.info("Adding: %s | Genres: %s | Network: %s | Country: %s", series['show']['title'], ', '.join(series['show']['genres']), series['show']['network'], series['show']['country'].upper()) # determine which tags to use when adding this series - use_tags = helpers.sonarr_series_tag_id_from_network(profile_tags, cfg.sonarr.tags, + use_tags = sonarr_helper.series_tag_id_from_network(profile_tags, cfg.sonarr.tags, series['show']['network']) # add show to sonarr if sonarr.add_series(series['show']['ids']['tvdb'], series['show']['title'], series['show']['ids']['slug'], profile_id, cfg.sonarr.root_folder, use_tags, not no_search): log.info("ADDED %s (%d) with tags: %s", series['show']['title'], series['show']['year'], - helpers.sonarr_readable_tag_from_ids(profile_tags, use_tags)) + sonarr_helper.readable_tag_from_ids(profile_tags, use_tags)) if notifications: callback_notify({'event': 'add_show', 'list_type': list_type, 'show': series['show']}) added_shows += 1 else: log.error("FAILED adding %s (%d) with tags: %s", series['show']['title'], series['show']['year'], - helpers.sonarr_readable_tag_from_ids(profile_tags, use_tags)) + sonarr_helper.readable_tag_from_ids(profile_tags, use_tags)) # stop adding shows, if added_shows >= add_limit if add_limit and added_shows >= add_limit: @@ -392,7 +393,8 @@ def movies(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_se authenticate_user=None): from media.radarr import Radarr from media.trakt import Trakt - from misc import helpers + from helpers import radarr as radarr_helper + from helpers import trakt as trakt_helper added_movies = 0 @@ -475,7 +477,7 @@ def movies(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_se log.info("Retrieved Trakt %s movies list, movies found: %d", list_type, len(trakt_movies_list)) # build filtered movie list without movies that exist in radarr - processed_movies_list = helpers.radarr_remove_existing_movies(radarr_movie_list, trakt_movies_list) + processed_movies_list = radarr_helper.remove_existing_movies(radarr_movie_list, trakt_movies_list) if processed_movies_list is None: log.error("Aborting due to failure to remove existing Radarr movies from retrieved Trakt movies list") if notifications: @@ -501,7 +503,7 @@ def movies(list_type, add_limit=0, add_delay=2.5, genre=None, folder=None, no_se continue # check if movie passes out blacklist criteria inspection - if not helpers.trakt_is_movie_blacklisted(movie, cfg.filters.movies): + if not trakt_helper.is_movie_blacklisted(movie, cfg.filters.movies): log.info("Adding: %s (%d) | Genres: %s | Country: %s", movie['movie']['title'], movie['movie']['year'], ', '.join(movie['movie']['genres']), movie['movie']['country'].upper()) # add movie to radarr