def tautulli_tests(config): if config.libraries[0].Tautulli: util.seperator("Tautulli Tests") try: config.libraries[0].Tautulli.get_section_id( config.libraries[0].name) logger.info("Success | Get Section ID") except Failed as e: util.print_stacktrace() logger.error("Failure | Get Section ID: {}".format(e)) try: config.libraries[0].Tautulli.get_popular(config.libraries[0], status_message=False) logger.info("Success | Get Popular") except Failed as e: util.print_stacktrace() logger.error("Failure | Get Popular: {}".format(e)) try: config.libraries[0].Tautulli.get_top(config.libraries[0], status_message=False) logger.info("Success | Get Top") except Failed as e: util.print_stacktrace() logger.error("Failure | Get Top: {}".format(e)) else: util.seperator("Tautulli Not Configured")
def start(config_path): try: util.seperator("Starting Daily Run") config = Config(default_dir, config_path) config.update_libraries() except Exception as e: util.print_stacktrace() logger.critical(e) logger.info("") util.seperator("Finished Daily Run")
def start(config_path, test, daily, collections): if daily: type = "Daily " elif test: type = "Test " elif collections: type = "Collections " else: type = "" util.seperator("Starting {}Run".format(type)) try: config = Config(default_dir, config_path) config.update_libraries(test, collections) except Exception as e: util.print_stacktrace() logger.critical(e) logger.info("") util.seperator("Finished {}Run".format(type))
def imdb_tests(config): if config.IMDb: util.seperator("IMDb Tests") tmdb_ids, tvdb_ids = config.IMDb.get_items("imdb_list", { "url": "https://www.imdb.com/search/title/?groups=top_1000", "limit": 0 }, "en", status_message=False) if len(tmdb_ids) == 1000: logger.info("Success | IMDb URL get TMDb IDs") else: logger.error( "Failure | IMDb URL get TMDb IDs: {} Should be 1000".format( len(tmdb_ids))) tmdb_ids, tvdb_ids = config.IMDb.get_items("imdb_list", { "url": "https://www.imdb.com/list/ls026173135/", "limit": 0 }, "en", status_message=False) if len(tmdb_ids) == 250: logger.info("Success | IMDb URL get TMDb IDs") else: logger.error( "Failure | IMDb URL get TMDb IDs: {} Should be 250".format( len(tmdb_ids))) tmdb_ids, tvdb_ids = config.IMDb.get_items("imdb_id", "tt0814243", "en", status_message=False) if len(tmdb_ids) == 1: logger.info("Success | IMDb ID get TMDb IDs") else: logger.error( "Failure | IMDb ID get TMDb IDs: {} Should be 1".format( len(tmdb_ids))) else: util.seperator("IMDb Not Configured")
def run_tests(default_dir): try: config = Config(default_dir) logger.info("") util.seperator("Mapping Tests") for library in config.libraries: config.map_guids(library) anidb_tests(config) imdb_tests(config) mal_tests(config) tautulli_tests(config) tmdb_tests(config) trakt_tests(config) tvdb_tests(config) util.seperator("Finished All Plex Meta Manager Tests") except KeyboardInterrupt: util.seperator("Canceled Plex Meta Manager Tests")
def update_metadata(self): logger.info("") util.seperator("{} Library Metadata".format(self.name)) logger.info("") if not self.metadata: raise Failed("No metadata to edit") for m in self.metadata: logger.info("") util.seperator() logger.info("") year = None if "year" in self.metadata[m]: now = datetime.datetime.now() if self.metadata[m]["year"] is None: logger.error("Metadata Error: year attribute is blank") elif not isinstance(self.metadata[m]["year"], int): logger.error("Metadata Error: year attribute must be an integer") elif self.metadata[m]["year"] not in range(1800, now.year + 2): logger.error("Metadata Error: year attribute must be between 1800-{}".format(now.year + 1)) else: year = self.metadata[m]["year"] alt_title = None used_alt = False if "alt_title" in self.metadata[m]: if self.metadata[m]["alt_title"] is None: logger.error("Metadata Error: alt_title attribute is blank") else: alt_title = self.metadata[m]["alt_title"] try: item = self.get_item(m, year=year) except Failed as e: if alt_title: try: item = self.get_item(alt_title, year=year) used_alt = True except Failed as alt_e: logger.error(alt_e) logger.error("Skipping {}".format(m)) continue else: logger.error(e) logger.error("Skipping {}".format(m)) continue logger.info("Updating {}: {}...".format("Movie" if self.is_movie else "Show", alt_title if used_alt else m)) edits = {} def add_edit(name, group, key=None, value=None, sub=None): if value or name in group: if value or group[name]: if key is None: key = name if value is None: value = group[name] if sub and "sub" in group: if group["sub"]: if group["sub"] is True and "(SUB)" not in value: value = "{} (SUB)".format(value) elif group["sub"] is False and " (SUB)" in value: value = value[:-6] else: logger.error("Metadata Error: sub attribute is blank") edits["{}.value".format(key)] = value edits["{}.locked".format(key)] = 1 else: logger.error("Metadata Error: {} attribute is blank".format(name)) if used_alt or "sub" in self.metadata[m]: add_edit("title", self.metadata[m], value=m, sub=True) add_edit("sort_title", self.metadata[m], key="titleSort") add_edit("originally_available", self.metadata[m], key="originallyAvailableAt") add_edit("rating", self.metadata[m]) add_edit("content_rating", self.metadata[m], key="contentRating") add_edit("original_title", self.metadata[m], key="originalTitle") add_edit("studio", self.metadata[m]) add_edit("tagline", self.metadata[m]) add_edit("summary", self.metadata[m]) try: item.edit(**edits) item.reload() logger.info("{}: {} Details Update Successful".format("Movie" if self.is_movie else "Show", m)) except BadRequest: logger.error("{}: {} Details Update Failed".format("Movie" if self.is_movie else "Show", m)) logger.debug("Details Update: {}".format(edits)) util.print_stacktrace() if "genre" in self.metadata[m]: if self.metadata[m]["genre"]: genre_sync = False if "genre_sync_mode" in self.metadata[m]: if self.metadata[m]["genre_sync_mode"] is None: logger.error("Metadata Error: genre_sync_mode attribute is blank defaulting to append") elif self.metadata[m]["genre_sync_mode"] not in ["append", "sync"]: logger.error("Metadata Error: genre_sync_mode attribute must be either 'append' or 'sync' defaulting to append") elif self.metadata[m]["genre_sync_mode"] == "sync": genre_sync = True genres = [genre.tag for genre in item.genres] values = util.get_list(self.metadata[m]["genre"]) if genre_sync: for genre in (g for g in genres if g not in values): item.removeGenre(genre) logger.info("Detail: Genre {} removed".format(genre)) for value in (v for v in values if v not in genres): item.addGenre(value) logger.info("Detail: Genre {} added".format(value)) else: logger.error("Metadata Error: genre attribute is blank") if "label" in self.metadata[m]: if self.metadata[m]["label"]: label_sync = False if "label_sync_mode" in self.metadata[m]: if self.metadata[m]["label_sync_mode"] is None: logger.error("Metadata Error: label_sync_mode attribute is blank defaulting to append") elif self.metadata[m]["label_sync_mode"] not in ["append", "sync"]: logger.error("Metadata Error: label_sync_mode attribute must be either 'append' or 'sync' defaulting to append") elif self.metadata[m]["label_sync_mode"] == "sync": label_sync = True labels = [label.tag for label in item.labels] values = util.get_list(self.metadata[m]["label"]) if label_sync: for label in (l for l in labels if l not in values): item.removeLabel(label) logger.info("Detail: Label {} removed".format(label)) for value in (v for v in values if v not in labels): item.addLabel(v) logger.info("Detail: Label {} added".format(v)) else: logger.error("Metadata Error: label attribute is blank") if "seasons" in self.metadata[m] and self.is_show: if self.metadata[m]["seasons"]: for season_id in self.metadata[m]["seasons"]: logger.info("") logger.info("Updating season {} of {}...".format(season_id, alt_title if used_alt else m)) if isinstance(season_id, int): try: season = item.season(season_id) except NotFound: logger.error("Metadata Error: Season: {} not found".format(season_id)) else: edits = {} add_edit("title", self.metadata[m]["seasons"][season_id], sub=True) add_edit("summary", self.metadata[m]["seasons"][season_id]) try: season.edit(**edits) season.reload() logger.info("Season: {} Details Update Successful".format(season_id)) except BadRequest: logger.debug("Season: {} Details Update: {}".format(season_id, edits)) logger.error("Season: {} Details Update Failed".format(season_id)) util.print_stacktrace() else: logger.error("Metadata Error: Season: {} invalid, it must be an integer".format(season_id)) else: logger.error("Metadata Error: seasons attribute is blank") if "episodes" in self.metadata[m] and self.is_show: if self.metadata[m]["episodes"]: for episode_str in self.metadata[m]["episodes"]: logger.info("") match = re.search("[Ss]{1}\d+[Ee]{1}\d+", episode_str) if match: output = match.group(0)[1:].split("E" if "E" in m.group(0) else "e") episode_id = int(output[0]) season_id = int(output[1]) logger.info("Updating episode S{}E{} of {}...".format(episode_id, season_id, alt_title if used_alt else m)) try: episode = item.episode(season=season_id, episode=episode_id) except NotFound: logger.error("Metadata Error: episode {} of season {} not found".format(episode_id, season_id)) else: edits = {} add_edit("title", self.metadata[m]["episodes"][episode_str], sub=True) add_edit("sort_title", self.metadata[m]["episodes"][episode_str], key="titleSort") add_edit("rating", self.metadata[m]["episodes"][episode_str]) add_edit("originally_available", self.metadata[m]["episodes"][episode_str], key="originallyAvailableAt") add_edit("summary", self.metadata[m]["episodes"][episode_str]) try: episode.edit(**edits) episode.reload() logger.info("Season: {} Episode: {} Details Update Successful".format(season_id, episode_id)) except BadRequest: logger.debug("Season: {} Episode: {} Details Update: {}".format(season_id, episode_id, edits)) logger.error("Season: {} Episode: {} Details Update Failed".format(season_id, episode_id)) util.print_stacktrace() else: logger.error("Metadata Error: episode {} invlaid must have S##E## format".format(episode_str)) else: logger.error("Metadata Error: episodes attribute is blank")
file_handler.addFilter(fmt_filter) file_handler.setFormatter( logging.Formatter( "[%(asctime)s] %(filename)-27s %(levelname)-10s | %(message)-100s |")) cmd_handler = logging.StreamHandler() cmd_handler.setFormatter(logging.Formatter("| %(message)-100s |")) cmd_handler.setLevel( logging.DEBUG if args.tests or args.test or args.debug else logging.INFO) logger.addHandler(cmd_handler) logger.addHandler(file_handler) sys.excepthook = util.my_except_hook util.seperator() logger.info( util.get_centered_text( " " )) logger.info( util.get_centered_text( " ____ _ __ __ _ __ __ " )) logger.info( util.get_centered_text( "| _ \| | _____ __ | \/ | ___| |_ __ _ | \/ | __ _ _ __ __ _ __ _ ___ _ __ " )) logger.info( util.get_centered_text( "| |_) | |/ _ \ \/ / | |\/| |/ _ \ __/ _` | | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '__|"
def update_libraries(self, test, requested_collections): for library in self.libraries: os.environ["PLEXAPI_PLEXAPI_TIMEOUT"] = str(library.timeout) logger.info("") util.seperator("{} Library".format(library.name)) try: library.update_metadata(self.TMDb, test) except Failed as e: logger.error(e) logger.info("") util.seperator("{} Library {}Collections".format(library.name, "Test " if test else "")) collections = {c: library.collections[c] for c in util.get_list(requested_collections) if c in library.collections} if requested_collections else library.collections if collections: logger.info("") util.seperator("Mapping {} Library".format(library.name)) logger.info("") movie_map, show_map = self.map_guids(library) for c in collections: if test and ("test" not in collections[c] or collections[c]["test"] is not True): no_template_test = True if "template" in collections[c] and collections[c]["template"]: for data_template in util.get_list(collections[c]["template"], split=False): if "name" in data_template \ and data_template["name"] \ and library.templates \ and data_template["name"] in self.library.templates \ and self.library.templates[data_template["name"]] \ and "test" in self.library.templates[data_template["name"]] \ and self.library.templates[data_template["name"]]["test"] == True: no_template_test = False if no_template_test: continue try: logger.info("") util.seperator("{} Collection".format(c)) logger.info("") map = {} try: builder = CollectionBuilder(self, library, c, collections[c]) except Exception as e: util.print_stacktrace() logger.error(e) continue try: collection_obj = library.get_collection(c) collection_name = collection_obj.title except Failed as e: collection_obj = None collection_name = c if builder.schedule is not None: print_multiline(builder.schedule, info=True) logger.info("") if builder.sync: logger.info("Sync Mode: sync") if collection_obj: for item in collection_obj.items(): map[item.ratingKey] = item else: logger.info("Sync Mode: append") for i, f in enumerate(builder.filters): if i == 0: logger.info("") logger.info("Collection Filter {}: {}".format(f[0], f[1])) builder.run_methods(collection_obj, collection_name, map, movie_map, show_map) try: plex_collection = library.get_collection(collection_name) except Failed as e: logger.debug(e) continue builder.update_details(plex_collection) except Exception as e: util.print_stacktrace() logger.error("Unknown Error: {}".format(e)) if library.show_unmanaged is True and not test and not requested_collections: logger.info("") util.seperator("Unmanaged Collections in {} Library".format(library.name)) logger.info("") unmanaged_count = 0 collections_in_plex = [str(pcol) for pcol in collections] for col in library.get_all_collections(): if col.title not in collections_in_plex: logger.info(col.title) unmanaged_count += 1 logger.info("{} Unmanaged Collections".format(unmanaged_count)) else: logger.info("") logger.error("No collection to update")
def __init__(self, default_dir, config_path=None): logger.info("Locating config...") if config_path and os.path.exists(config_path): self.config_path = os.path.abspath(config_path) elif config_path and not os.path.exists(config_path): raise Failed("Config Error: config not found at {}".format(os.path.abspath(config_path))) elif os.path.exists(os.path.join(default_dir, "config.yml")): self.config_path = os.path.abspath(os.path.join(default_dir, "config.yml")) else: raise Failed("Config Error: config not found at {}".format(os.path.abspath(default_dir))) logger.info("Using {} as config".format(self.config_path)) yaml.YAML().allow_duplicate_keys = True try: new_config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path)) def replace_attr(all_data, attr, par): if "settings" not in all_data: all_data["settings"] = {} if par in all_data and all_data[par] and attr in all_data[par] and attr not in all_data["settings"]: all_data["settings"][attr] = all_data[par][attr] del all_data[par][attr] if "libraries" not in new_config: new_config["libraries"] = {} if "settings" not in new_config: new_config["settings"] = {} if "tmdb" not in new_config: new_config["tmdb"] = {} replace_attr(new_config, "cache", "cache") replace_attr(new_config, "cache_expiration", "cache") if "config" in new_config: del new_config["cache"] replace_attr(new_config, "asset_directory", "plex") replace_attr(new_config, "sync_mode", "plex") replace_attr(new_config, "show_unmanaged", "plex") replace_attr(new_config, "show_filtered", "plex") replace_attr(new_config, "show_missing", "plex") replace_attr(new_config, "save_missing", "plex") if new_config["libraries"]: for library in new_config["libraries"]: if "plex" in new_config["libraries"][library]: replace_attr(new_config["libraries"][library], "asset_directory", "plex") replace_attr(new_config["libraries"][library], "sync_mode", "plex") replace_attr(new_config["libraries"][library], "show_unmanaged", "plex") replace_attr(new_config["libraries"][library], "show_filtered", "plex") replace_attr(new_config["libraries"][library], "show_missing", "plex") replace_attr(new_config["libraries"][library], "save_missing", "plex") if "libraries" in new_config: new_config["libraries"] = new_config.pop("libraries") if "settings" in new_config: new_config["settings"] = new_config.pop("settings") if "plex" in new_config: new_config["plex"] = new_config.pop("plex") if "tmdb" in new_config: new_config["tmdb"] = new_config.pop("tmdb") if "tautulli" in new_config: new_config["tautulli"] = new_config.pop("tautulli") if "radarr" in new_config: new_config["radarr"] = new_config.pop("radarr") if "sonarr" in new_config: new_config["sonarr"] = new_config.pop("sonarr") if "trakt" in new_config: new_config["trakt"] = new_config.pop("trakt") if "mal" in new_config: new_config["mal"] = new_config.pop("mal") yaml.round_trip_dump(new_config, open(self.config_path, "w"), indent=ind, block_seq_indent=bsi) self.data = new_config except yaml.scanner.ScannerError as e: raise Failed("YAML Error: {}".format(str(e).replace("\n", "\n|\t "))) def check_for_attribute(data, attribute, parent=None, test_list=None, options="", default=None, do_print=True, default_is_none=False, req_default=False, var_type="str", throw=False, save=True): message = "" endline = "" if parent is not None: if parent in data: data = data[parent] else: data = None do_print = False save = False text = "{} attribute".format(attribute) if parent is None else "{} sub-attribute {}".format(parent, attribute) if data is None or attribute not in data: message = "{} not found".format(text) if parent and save is True: new_config, ind, bsi = yaml.util.load_yaml_guess_indent(open(self.config_path)) endline = "\n{} sub-attribute {} added to config".format(parent, attribute) if parent not in new_config: new_config = {parent: {attribute: default}} elif not new_config[parent]: new_config[parent] = {attribute: default} elif attribute not in new_config[parent]: new_config[parent][attribute] = default else: endLine = "" yaml.round_trip_dump(new_config, open(self.config_path, "w"), indent=ind, block_seq_indent=bsi) elif not data[attribute] and data[attribute] != False: if default_is_none is True: return None else: message = "{} is blank".format(text) elif var_type == "bool": if isinstance(data[attribute], bool): return data[attribute] else: message = "{} must be either true or false".format(text) elif var_type == "int": if isinstance(data[attribute], int) and data[attribute] > 0: return data[attribute] else: message = "{} must an integer > 0".format(text) elif var_type == "path": if os.path.exists(os.path.abspath(data[attribute])): return data[attribute] else: message = "Path {} does not exist".format(os.path.abspath(data[attribute])) elif var_type == "list": return util.get_list(data[attribute]) elif var_type == "listpath": temp_list = [path for path in util.get_list(data[attribute], split=True) if os.path.exists(os.path.abspath(path))] if len(temp_list) > 0: return temp_list else: message = "No Paths exist" elif var_type == "lowerlist": return util.get_list(data[attribute], lower=True) elif test_list is None or data[attribute] in test_list: return data[attribute] else: message = "{}: {} is an invalid input".format(text, data[attribute]) if var_type == "path" and default and os.path.exists(os.path.abspath(default)): return default elif var_type == "path" and default: default = None message = "neither {} or the default path {} could be found".format(data[attribute], default) if default is not None or default_is_none: message = message + " using {} as default".format(default) message = message + endline if req_default and default is None: raise Failed("Config Error: {} attribute must be set under {} globally or under this specific Library".format(attribute, parent)) if (default is None and not default_is_none) or throw: if len(options) > 0: message = message + "\n" + options raise Failed("Config Error: {}".format(message)) if do_print: util.print_multiline("Config Warning: {}".format(message)) if attribute in data and data[attribute] and test_list is not None and data[attribute] not in test_list: util.print_multiline(options) return default self.general = {} self.general["cache"] = check_for_attribute(self.data, "cache", parent="settings", options=" true (Create a cache to store ids)\n false (Do not create a cache to store ids)", var_type="bool", default=True) self.general["cache_expiration"] = check_for_attribute(self.data, "cache_expiration", parent="settings", var_type="int", default=60) if self.general["cache"]: util.seperator() self.Cache = Cache(self.config_path, self.general["cache_expiration"]) else: self.Cache = None self.general["asset_directory"] = check_for_attribute(self.data, "asset_directory", parent="settings", var_type="listpath", default=[os.path.join(default_dir, "assets")]) self.general["sync_mode"] = check_for_attribute(self.data, "sync_mode", parent="settings", default="append", test_list=["append", "sync"], options=" append (Only Add Items to the Collection)\n sync (Add & Remove Items from the Collection)") self.general["show_unmanaged"] = check_for_attribute(self.data, "show_unmanaged", parent="settings", var_type="bool", default=True) self.general["show_filtered"] = check_for_attribute(self.data, "show_filtered", parent="settings", var_type="bool", default=False) self.general["show_missing"] = check_for_attribute(self.data, "show_missing", parent="settings", var_type="bool", default=True) self.general["save_missing"] = check_for_attribute(self.data, "save_missing", parent="settings", var_type="bool", default=True) util.seperator() self.TMDb = None if "tmdb" in self.data: logger.info("Connecting to TMDb...") self.tmdb = {} try: self.tmdb["apikey"] = check_for_attribute(self.data, "apikey", parent="tmdb", throw=True) except Failed as e: raise Failed(e) self.tmdb["language"] = check_for_attribute(self.data, "language", parent="tmdb", default="en") self.TMDb = TMDbAPI(self.tmdb) logger.info("TMDb Connection {}".format("Failed" if self.TMDb is None else "Successful")) else: raise Failed("Config Error: tmdb attribute not found") util.seperator() self.Trakt = None if "trakt" in self.data: logger.info("Connecting to Trakt...") self.trakt = {} try: self.trakt["client_id"] = check_for_attribute(self.data, "client_id", parent="trakt", throw=True) self.trakt["client_secret"] = check_for_attribute(self.data, "client_secret", parent="trakt", throw=True) self.trakt["config_path"] = self.config_path authorization = self.data["trakt"]["authorization"] if "authorization" in self.data["trakt"] and self.data["trakt"]["authorization"] else None self.Trakt = TraktAPI(self.trakt, authorization) except Failed as e: logger.error(e) logger.info("Trakt Connection {}".format("Failed" if self.Trakt is None else "Successful")) else: logger.warning("trakt attribute not found") util.seperator() self.MyAnimeList = None self.MyAnimeListIDList = MyAnimeListIDList() if "mal" in self.data: logger.info("Connecting to My Anime List...") self.mal = {} try: self.mal["client_id"] = check_for_attribute(self.data, "client_id", parent="mal", throw=True) self.mal["client_secret"] = check_for_attribute(self.data, "client_secret", parent="mal", throw=True) self.mal["config_path"] = self.config_path authorization = self.data["mal"]["authorization"] if "authorization" in self.data["mal"] and self.data["mal"]["authorization"] else None self.MyAnimeList = MyAnimeListAPI(self.mal, self.MyAnimeListIDList, authorization) except Failed as e: logger.error(e) logger.info("My Anime List Connection {}".format("Failed" if self.MyAnimeList is None else "Successful")) else: logger.warning("mal attribute not found") self.TVDb = TVDbAPI(Cache=self.Cache, TMDb=self.TMDb, Trakt=self.Trakt) self.IMDb = IMDbAPI(Cache=self.Cache, TMDb=self.TMDb, Trakt=self.Trakt, TVDb=self.TVDb) if self.TMDb or self.Trakt else None self.AniDB = AniDBAPI(Cache=self.Cache, TMDb=self.TMDb, Trakt=self.Trakt) util.seperator() logger.info("Connecting to Plex Libraries...") self.general["plex"] = {} self.general["plex"]["url"] = check_for_attribute(self.data, "url", parent="plex", default_is_none=True) self.general["plex"]["token"] = check_for_attribute(self.data, "token", parent="plex", default_is_none=True) self.general["plex"]["timeout"] = check_for_attribute(self.data, "timeout", parent="plex", var_type="int", default=60) self.general["radarr"] = {} self.general["radarr"]["url"] = check_for_attribute(self.data, "url", parent="radarr", default_is_none=True) self.general["radarr"]["version"] = check_for_attribute(self.data, "version", parent="radarr", test_list=["v2", "v3"], options=" v2 (For Radarr 0.2)\n v3 (For Radarr 3.0)", default="v2") self.general["radarr"]["token"] = check_for_attribute(self.data, "token", parent="radarr", default_is_none=True) self.general["radarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="radarr", default_is_none=True) self.general["radarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="radarr", default_is_none=True) self.general["radarr"]["add"] = check_for_attribute(self.data, "add", parent="radarr", var_type="bool", default=False) self.general["radarr"]["search"] = check_for_attribute(self.data, "search", parent="radarr", var_type="bool", default=False) self.general["radarr"]["tag"] = check_for_attribute(self.data, "tag", parent="radarr", var_type="lowerlist", default_is_none=True) self.general["sonarr"] = {} self.general["sonarr"]["url"] = check_for_attribute(self.data, "url", parent="sonarr", default_is_none=True) self.general["sonarr"]["token"] = check_for_attribute(self.data, "token", parent="sonarr", default_is_none=True) self.general["sonarr"]["version"] = check_for_attribute(self.data, "version", parent="sonarr", test_list=["v2", "v3"], options=" v2 (For Sonarr 0.2)\n v3 (For Sonarr 3.0)", default="v2") self.general["sonarr"]["quality_profile"] = check_for_attribute(self.data, "quality_profile", parent="sonarr", default_is_none=True) self.general["sonarr"]["root_folder_path"] = check_for_attribute(self.data, "root_folder_path", parent="sonarr", default_is_none=True) self.general["sonarr"]["add"] = check_for_attribute(self.data, "add", parent="sonarr", var_type="bool", default=False) self.general["sonarr"]["search"] = check_for_attribute(self.data, "search", parent="sonarr", var_type="bool", default=False) self.general["sonarr"]["tag"] = check_for_attribute(self.data, "tag", parent="sonarr", var_type="lowerlist", default_is_none=True) self.general["tautulli"] = {} self.general["tautulli"]["url"] = check_for_attribute(self.data, "url", parent="tautulli", default_is_none=True) self.general["tautulli"]["apikey"] = check_for_attribute(self.data, "apikey", parent="tautulli", default_is_none=True) self.libraries = [] try: libs = check_for_attribute(self.data, "libraries", throw=True) except Failed as e: raise Failed(e) for lib in libs: util.seperator() params = {} if "library_name" in libs[lib] and libs[lib]["library_name"]: params["name"] = str(libs[lib]["library_name"]) logger.info("Connecting to {} ({}) Library...".format(params["name"], lib)) else: params["name"] = str(lib) logger.info("Connecting to {} Library...".format(params["name"])) default_lib = os.path.join(default_dir, "{}.yml".format(lib)) params["asset_directory"] = check_for_attribute(libs[lib], "asset_directory", parent="settings", var_type="listpath", default=self.general["asset_directory"], default_is_none=True, save=False) if params["asset_directory"] is None: logger.warning("Config Warning: Assets will not be used asset_directory attribute must be set under config or under this specific Library") params["sync_mode"] = check_for_attribute(libs[lib], "sync_mode", parent="settings", test_list=["append", "sync"], options=" append (Only Add Items to the Collection)\n sync (Add & Remove Items from the Collection)", default=self.general["sync_mode"], save=False) params["show_unmanaged"] = check_for_attribute(libs[lib], "show_unmanaged", parent="settings", var_type="bool", default=self.general["show_unmanaged"], save=False) params["show_filtered"] = check_for_attribute(libs[lib], "show_filtered", parent="settings", var_type="bool", default=self.general["show_filtered"], save=False) params["show_missing"] = check_for_attribute(libs[lib], "show_missing", parent="settings", var_type="bool", default=self.general["show_missing"], save=False) params["save_missing"] = check_for_attribute(libs[lib], "save_missing", parent="settings", var_type="bool", default=self.general["save_missing"], save=False) try: params["metadata_path"] = check_for_attribute(libs[lib], "metadata_path", var_type="path", default=os.path.join(default_dir, "{}.yml".format(lib)), throw=True) params["library_type"] = check_for_attribute(libs[lib], "library_type", test_list=["movie", "show"], options=" movie (For Movie Libraries)\n show (For Show Libraries)", throw=True) params["plex"] = {} params["plex"]["url"] = check_for_attribute(libs[lib], "url", parent="plex", default=self.general["plex"]["url"], req_default=True, save=False) params["plex"]["token"] = check_for_attribute(libs[lib], "token", parent="plex", default=self.general["plex"]["token"], req_default=True, save=False) params["plex"]["timeout"] = check_for_attribute(libs[lib], "timeout", parent="plex", var_type="int", default=self.general["plex"]["timeout"], save=False) library = PlexAPI(params, self.TMDb, self.TVDb) logger.info("{} Library Connection Successful".format(params["name"])) except Failed as e: util.print_multiline(e) logger.info("{} Library Connection Failed".format(params["name"])) continue if self.general["radarr"]["url"] or "radarr" in libs[lib]: logger.info("Connecting to {} library's Radarr...".format(params["name"])) radarr_params = {} try: radarr_params["url"] = check_for_attribute(libs[lib], "url", parent="radarr", default=self.general["radarr"]["url"], req_default=True, save=False) radarr_params["token"] = check_for_attribute(libs[lib], "token", parent="radarr", default=self.general["radarr"]["token"], req_default=True, save=False) radarr_params["version"] = check_for_attribute(libs[lib], "version", parent="radarr", test_list=["v2", "v3"], options=" v2 (For Radarr 0.2)\n v3 (For Radarr 3.0)", default=self.general["radarr"]["version"], save=False) radarr_params["quality_profile"] = check_for_attribute(libs[lib], "quality_profile", parent="radarr", default=self.general["radarr"]["quality_profile"], req_default=True, save=False) radarr_params["root_folder_path"] = check_for_attribute(libs[lib], "root_folder_path", parent="radarr", default=self.general["radarr"]["root_folder_path"], req_default=True, save=False) radarr_params["add"] = check_for_attribute(libs[lib], "add", parent="radarr", var_type="bool", default=self.general["radarr"]["add"], save=False) radarr_params["search"] = check_for_attribute(libs[lib], "search", parent="radarr", var_type="bool", default=self.general["radarr"]["search"], save=False) radarr_params["tag"] = check_for_attribute(libs[lib], "search", parent="radarr", var_type="lowerlist", default=self.general["radarr"]["tag"], default_is_none=True, save=False) library.add_Radarr(RadarrAPI(self.TMDb, radarr_params)) except Failed as e: util.print_multiline(e) logger.info("{} library's Radarr Connection {}".format(params["name"], "Failed" if library.Radarr is None else "Successful")) if self.general["sonarr"]["url"] or "sonarr" in libs[lib]: logger.info("Connecting to {} library's Sonarr...".format(params["name"])) sonarr_params = {} try: sonarr_params["url"] = check_for_attribute(libs[lib], "url", parent="sonarr", default=self.general["sonarr"]["url"], req_default=True, save=False) sonarr_params["token"] = check_for_attribute(libs[lib], "token", parent="sonarr", default=self.general["sonarr"]["token"], req_default=True, save=False) sonarr_params["version"] = check_for_attribute(libs[lib], "version", parent="sonarr", test_list=["v2", "v3"], options=" v2 (For Sonarr 0.2)\n v3 (For Sonarr 3.0)", default=self.general["sonarr"]["version"], save=False) sonarr_params["quality_profile"] = check_for_attribute(libs[lib], "quality_profile", parent="sonarr", default=self.general["sonarr"]["quality_profile"], req_default=True, save=False) sonarr_params["root_folder_path"] = check_for_attribute(libs[lib], "root_folder_path", parent="sonarr", default=self.general["sonarr"]["root_folder_path"], req_default=True, save=False) sonarr_params["add"] = check_for_attribute(libs[lib], "add", parent="sonarr", var_type="bool", default=self.general["sonarr"]["add"], save=False) sonarr_params["search"] = check_for_attribute(libs[lib], "search", parent="sonarr", var_type="bool", default=self.general["sonarr"]["search"], save=False) sonarr_params["tag"] = check_for_attribute(libs[lib], "search", parent="sonarr", var_type="lowerlist", default=self.general["sonarr"]["tag"], default_is_none=True, save=False) library.add_Sonarr(SonarrAPI(self.TVDb, sonarr_params, library.Plex.language)) except Failed as e: util.print_multiline(e) logger.info("{} library's Sonarr Connection {}".format(params["name"], "Failed" if library.Sonarr is None else "Successful")) if self.general["tautulli"]["url"] or "tautulli" in libs[lib]: logger.info("Connecting to {} library's Tautulli...".format(params["name"])) tautulli_params = {} try: tautulli_params["url"] = check_for_attribute(libs[lib], "url", parent="tautulli", default=self.general["tautulli"]["url"], req_default=True, save=False) tautulli_params["apikey"] = check_for_attribute(libs[lib], "apikey", parent="tautulli", default=self.general["tautulli"]["apikey"], req_default=True, save=False) library.add_Tautulli(TautulliAPI(tautulli_params)) except Failed as e: util.print_multiline(e) logger.info("{} library's Tautulli Connection {}".format(params["name"], "Failed" if library.Tautulli is None else "Successful")) self.libraries.append(library) util.seperator() if len(self.libraries) > 0: logger.info("{} Plex Library Connection{} Successful".format(len(self.libraries), "s" if len(self.libraries) > 1 else "")) else: raise Failed("Plex Error: No Plex libraries were found") util.seperator()
def update_metadata(self, TMDb): logger.info("") util.seperator("{} Library Metadata".format(self.name)) logger.info("") if not self.metadata: raise Failed("No metadata to edit") for m in self.metadata: logger.info("") util.seperator() logger.info("") year = None if "year" in self.metadata[m]: now = datetime.datetime.now() if self.metadata[m]["year"] is None: logger.error("Metadata Error: year attribute is blank") elif not isinstance(self.metadata[m]["year"], int): logger.error("Metadata Error: year attribute must be an integer") elif self.metadata[m]["year"] not in range(1800, now.year + 2): logger.error("Metadata Error: year attribute must be between 1800-{}".format(now.year + 1)) else: year = self.metadata[m]["year"] title = m if "title" in self.metadata[m]: if self.metadata[m]["title"] is None: logger.error("Metadata Error: title attribute is blank") else: title = self.metadata[m]["title"] item = self.search_item(title, year=year) if item is None: item = self.search_item("{} (SUB)".format(title), year=year) if item is None and "alt_title" in self.metadata[m]: if self.metadata[m]["alt_title"] is None: logger.error("Metadata Error: alt_title attribute is blank") else: alt_title = self.metadata[m]["alt_title"] item = self.search_item(alt_title, year=year) if item is None: logger.error("Plex Error: Item {} not found".format(m)) logger.error("Skipping {}".format(m)) continue logger.info("Updating {}: {}...".format("Movie" if self.is_movie else "Show", title)) tmdb_item = None try: if "tmdb_id" in self.metadata[m]: if self.metadata[m]["tmdb_id"] is None: logger.error("Metadata Error: tmdb_id attribute is blank") elif self.is_show: logger.error("Metadata Error: tmdb_id attribute only works with movie libraries") else: tmdb_item = TMDb.get_show(util.regex_first_int(self.metadata[m]["tmdb_id"], "Show")) except Failed as e: logger.error(e) originally_available = tmdb_item.first_air_date if tmdb_item else None rating = tmdb_item.vote_average if tmdb_item else None original_title = tmdb_item.original_name if tmdb_item and tmdb_item.original_name != tmdb_item.name else None studio = tmdb_item.networks[0].name if tmdb_item else None tagline = tmdb_item.tagline if tmdb_item and len(tmdb_item.tagline) > 0 else None summary = tmdb_item.overview if tmdb_item else None edits = {} def add_edit(name, current, group, key=None, value=None): if value or name in group: if value or group[name]: if key is None: key = name if value is None: value = group[name] if str(current) != str(value): edits["{}.value".format(key)] = value edits["{}.locked".format(key)] = 1 else: logger.error("Metadata Error: {} attribute is blank".format(name)) add_edit("title", item.title, self.metadata[m], value=title) add_edit("sort_title", item.titleSort, self.metadata[m], key="titleSort") add_edit("originally_available", str(item.originallyAvailableAt)[:-9], self.metadata[m], key="originallyAvailableAt", value=originally_available) add_edit("rating", item.rating, self.metadata[m], value=rating) add_edit("content_rating", item.contentRating, self.metadata[m], key="contentRating") add_edit("original_title", item.originalTitle, self.metadata[m], key="originalTitle", value=original_title) add_edit("studio", item.studio, self.metadata[m], value=studio) add_edit("tagline", item.tagline, self.metadata[m], value=tagline) add_edit("summary", item.summary, self.metadata[m], value=summary) if len(edits) > 0: logger.debug("Details Update: {}".format(edits)) try: item.edit(**edits) item.reload() logger.info("{}: {} Details Update Successful".format("Movie" if self.is_movie else "Show", m)) except BadRequest: util.print_stacktrace() logger.error("{}: {} Details Update Failed".format("Movie" if self.is_movie else "Show", m)) else: logger.info("{}: {} Details Update Not Needed".format("Movie" if self.is_movie else "Show", m)) genres = [] if tmdb_item: genres.extend([genre.name for genre in tmdb_item.genres]) if "genre" in self.metadata[m]: if self.metadata[m]["genre"]: genres.extend(util.get_list(self.metadata[m]["genre"])) else: logger.error("Metadata Error: genre attribute is blank") if len(genres) > 0: item_genres = [genre.tag for genre in item.genres] if "genre_sync_mode" in self.metadata[m]: if self.metadata[m]["genre_sync_mode"] is None: logger.error("Metadata Error: genre_sync_mode attribute is blank defaulting to append") elif self.metadata[m]["genre_sync_mode"] not in ["append", "sync"]: logger.error("Metadata Error: genre_sync_mode attribute must be either 'append' or 'sync' defaulting to append") elif self.metadata[m]["genre_sync_mode"] == "sync": for genre in (g for g in item_genres if g not in genres): item.removeGenre(genre) logger.info("Detail: Genre {} removed".format(genre)) for genre in (g for g in genres if g not in item_genres): item.addGenre(genre) logger.info("Detail: Genre {} added".format(genre)) if "label" in self.metadata[m]: if self.metadata[m]["label"]: item_labels = [label.tag for label in item.labels] labels = util.get_list(self.metadata[m]["label"]) if "label_sync_mode" in self.metadata[m]: if self.metadata[m]["label_sync_mode"] is None: logger.error("Metadata Error: label_sync_mode attribute is blank defaulting to append") elif self.metadata[m]["label_sync_mode"] not in ["append", "sync"]: logger.error("Metadata Error: label_sync_mode attribute must be either 'append' or 'sync' defaulting to append") elif self.metadata[m]["label_sync_mode"] == "sync": for label in (l for l in item_labels if l not in labels): item.removeLabel(label) logger.info("Detail: Label {} removed".format(label)) for label in (l for l in labels if l not in item_labels): item.addLabel(label) logger.info("Detail: Label {} added".format(label)) else: logger.error("Metadata Error: label attribute is blank") if "seasons" in self.metadata[m] and self.is_show: if self.metadata[m]["seasons"]: for season_id in self.metadata[m]["seasons"]: logger.info("") logger.info("Updating season {} of {}...".format(season_id, m)) if isinstance(season_id, int): try: season = item.season(season_id) except NotFound: logger.error("Metadata Error: Season: {} not found".format(season_id)) else: if "title" in self.metadata[m]["seasons"][season_id] and self.metadata[m]["seasons"][season_id]["title"]: title = self.metadata[m]["seasons"][season_id]["title"] else: title = season.title if "sub" in self.metadata[m]["seasons"][season_id]: if self.metadata[m]["seasons"][season_id]["sub"] is None: logger.error("Metadata Error: sub attribute is blank") elif self.metadata[m]["seasons"][season_id]["sub"] is True and "(SUB)" not in title: title = "{} (SUB)".format(title) elif self.metadata[m]["seasons"][season_id]["sub"] is False and title.endswith(" (SUB)"): title = title[:-6] else: logger.error("Metadata Error: sub attribute must be True or False") edits = {} add_edit("title", season.title, self.metadata[m]["seasons"][season_id], value=title) add_edit("summary", season.summary, self.metadata[m]["seasons"][season_id]) if len(edits) > 0: logger.debug("Season: {} Details Update: {}".format(season_id, edits)) try: season.edit(**edits) season.reload() logger.info("Season: {} Details Update Successful".format(season_id)) except BadRequest: util.print_stacktrace() logger.error("Season: {} Details Update Failed".format(season_id)) else: logger.info("Season: {} Details Update Not Needed".format(season_id)) else: logger.error("Metadata Error: Season: {} invalid, it must be an integer".format(season_id)) else: logger.error("Metadata Error: seasons attribute is blank") if "episodes" in self.metadata[m] and self.is_show: if self.metadata[m]["episodes"]: for episode_str in self.metadata[m]["episodes"]: logger.info("") match = re.search("[Ss]{1}\d+[Ee]{1}\d+", episode_str) if match: output = match.group(0)[1:].split("E" if "E" in m.group(0) else "e") episode_id = int(output[0]) season_id = int(output[1]) logger.info("Updating episode S{}E{} of {}...".format(episode_id, season_id, m)) try: episode = item.episode(season=season_id, episode=episode_id) except NotFound: logger.error("Metadata Error: episode {} of season {} not found".format(episode_id, season_id)) else: if "title" in self.metadata[m]["episodes"][episode_str] and self.metadata[m]["episodes"][episode_str]["title"]: title = self.metadata[m]["episodes"][episode_str]["title"] else: title = episode.title if "sub" in self.metadata[m]["episodes"][episode_str]: if self.metadata[m]["episodes"][episode_str]["sub"] is None: logger.error("Metadata Error: sub attribute is blank") elif self.metadata[m]["episodes"][episode_str]["sub"] is True and "(SUB)" not in title: title = "{} (SUB)".format(title) elif self.metadata[m]["episodes"][episode_str]["sub"] is False and title.endswith(" (SUB)"): title = title[:-6] else: logger.error("Metadata Error: sub attribute must be True or False") edits = {} add_edit("title", episode.title, self.metadata[m]["episodes"][episode_str], value=title) add_edit("sort_title", episode.titleSort, self.metadata[m]["episodes"][episode_str], key="titleSort") add_edit("rating", episode.rating, self.metadata[m]["episodes"][episode_str]) add_edit("originally_available", str(episode.originallyAvailableAt)[:-9], self.metadata[m]["episodes"][episode_str], key="originallyAvailableAt") add_edit("summary", episode.summary, self.metadata[m]["episodes"][episode_str]) if len(edits) > 0: logger.debug("Season: {} Episode: {} Details Update: {}".format(season_id, episode_id, edits)) try: episode.edit(**edits) episode.reload() logger.info("Season: {} Episode: {} Details Update Successful".format(season_id, episode_id)) except BadRequest: util.print_stacktrace() logger.error("Season: {} Episode: {} Details Update Failed".format(season_id, episode_id)) else: logger.info("Season: {} Episode: {} Details Update Not Needed".format(season_id, episode_id)) else: logger.error("Metadata Error: episode {} invlaid must have S##E## format".format(episode_str)) else: logger.error("Metadata Error: episodes attribute is blank")
def tvdb_tests(config): if config.TVDb: util.seperator("TVDb Tests") tmdb_ids, tvdb_ids = config.TVDb.get_items( "tvdb_list", "https://www.thetvdb.com/lists/arrowverse", "en", status_message=False) if len(tvdb_ids) == 10 and len(tmdb_ids) == 0: logger.info("Success | TVDb URL get TVDb IDs and TMDb IDs") else: logger.error( "Failure | TVDb URL get TVDb IDs and TMDb IDs: {} Should be 10 and {} Should be 0" .format(len(tvdb_ids), len(tmdb_ids))) tmdb_ids, tvdb_ids = config.TVDb.get_items( "tvdb_list", "https://www.thetvdb.com/lists/6957", "en", status_message=False) if len(tvdb_ids) == 4 and len(tmdb_ids) == 2: logger.info("Success | TVDb URL get TVDb IDs and TMDb IDs") else: logger.error( "Failure | TVDb URL get TVDb IDs and TMDb IDs: {} Should be 4 and {} Should be 2" .format(len(tvdb_ids), len(tmdb_ids))) try: config.TVDb.get_items("tvdb_show", "https://www.thetvdb.com/series/arrow", "en", status_message=False) logger.info("Success | TVDb URL get TVDb Series ID") except Failed as e: util.print_stacktrace() logger.error("Failure | TVDb URL get TVDb Series ID: {}".format(e)) try: config.TVDb.get_items("tvdb_show", 279121, "en", status_message=False) logger.info("Success | TVDb ID get TVDb Series ID") except Failed as e: util.print_stacktrace() logger.error("Failure | TVDb ID get TVDb Series ID: {}".format(e)) try: config.TVDb.get_items( "tvdb_movie", "https://www.thetvdb.com/movies/the-lord-of-the-rings-the-fellowship-of-the-ring", "en", status_message=False) logger.info("Success | TVDb URL get TVDb Movie ID") except Failed as e: util.print_stacktrace() logger.error("Failure | TVDb URL get TVDb Movie ID: {}".format(e)) try: config.TVDb.get_items("tvdb_movie", 107, "en", status_message=False) logger.info("Success | TVDb ID get TVDb Movie ID") except Failed as e: util.print_stacktrace() logger.error("Failure | TVDb ID get TVDb Movie ID: {}".format(e)) else: util.seperator("TVDb Not Configured")
def trakt_tests(config): if config.Trakt: util.seperator("Trakt Tests") try: config.Trakt.convert_imdb_to_tmdb("tt0076759") logger.info("Success | Convert IMDb to TMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert IMDb to TMDb: {}".format(e)) try: config.Trakt.convert_tmdb_to_imdb(11) logger.info("Success | Convert TMDb to IMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TMDb to IMDb: {}".format(e)) try: config.Trakt.convert_imdb_to_tvdb("tt0458290") logger.info("Success | Convert IMDb to TVDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert IMDb to TVDb: {}".format(e)) try: config.Trakt.convert_tvdb_to_imdb(83268) logger.info("Success | Convert TVDb to IMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TVDb to IMDb: {}".format(e)) try: config.Trakt.convert_tmdb_to_tvdb(11) logger.info("Success | Convert TMDb to TVDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TMDb to TVDb: {}".format(e)) try: config.Trakt.convert_tvdb_to_tmdb(83268) logger.info("Success | Convert TVDb to TMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TVDb to TMDb: {}".format(e)) try: config.Trakt.validate_trakt_list( ["https://trakt.tv/users/movistapp/lists/christmas-movies"]) logger.info("Success | Get List") except Failed as e: util.print_stacktrace() logger.error("Failure | Get List: {}".format(e)) try: config.Trakt.validate_trakt_watchlist(["me"], True) logger.info("Success | Get Watchlist Movies") except Failed as e: util.print_stacktrace() logger.error("Failure | Get Watchlist Movies: {}".format(e)) try: config.Trakt.validate_trakt_watchlist(["me"], False) logger.info("Success | Get Watchlist Shows") except Failed as e: util.print_stacktrace() logger.error("Failure | Get Watchlist Shows: {}".format(e)) trakt_list_tests = [ ("trakt_list", "https://trakt.tv/users/movistapp/lists/christmas-movies", True), ("trakt_trending", 10, True), ("trakt_trending", 10, False), ("trakt_watchlist", "me", True), ("trakt_watchlist", "me", False) ] for trakt_list_test in trakt_list_tests: try: config.Trakt.get_items(trakt_list_test[0], trakt_list_test[1], trakt_list_test[2], status_message=False) logger.info("Success | Get {} using {}".format( "Movies" if trakt_list_test[2] else "Shows", util.pretty_names[trakt_list_test[0]])) except Failed as e: util.print_stacktrace() logger.error("Failure | Get {} using {}: {}".format( "Movies" if trakt_list_test[2] else "Shows", util.pretty_names[trakt_list_test[0]], e)) else: util.seperator("Trakt Not Configured")
def anidb_tests(config): if config.AniDB: util.seperator("AniDB Tests") try: config.AniDB.convert_anidb_to_tvdb(69) logger.info("Success | Convert AniDB to TVDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert AniDB to TVDb: {}".format(e)) try: config.AniDB.convert_anidb_to_imdb(112) logger.info("Success | Convert AniDB to IMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert AniDB to IMDb: {}".format(e)) try: config.AniDB.convert_tvdb_to_anidb(81797) logger.info("Success | Convert TVDb to AniDB") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TVDb to AniDB: {}".format(e)) try: config.AniDB.convert_imdb_to_anidb("tt0245429") logger.info("Success | Convert IMDb to AniDB") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert IMDb to AniDB: {}".format(e)) try: config.AniDB.get_items("anidb_id", 69, "en", status_message=False) logger.info("Success | Get AniDB ID") except Failed as e: util.print_stacktrace() logger.error("Failure | Get AniDB ID: {}".format(e)) try: config.AniDB.get_items("anidb_relation", 69, "en", status_message=False) logger.info("Success | Get AniDB Relation") except Failed as e: util.print_stacktrace() logger.error("Failure | Get AniDB Relation: {}".format(e)) try: config.AniDB.get_items("anidb_popular", 30, "en", status_message=False) logger.info("Success | Get AniDB Popular") except Failed as e: util.print_stacktrace() logger.error("Failure | Get AniDB Popular: {}".format(e)) try: config.AniDB.validate_anidb_list(["69", "112"], "en") logger.info("Success | Validate AniDB List") except Failed as e: util.print_stacktrace() logger.error("Failure | Validate AniDB List: {}".format(e)) else: util.seperator("AniDB Not Configured")
def tmdb_tests(config): if config.TMDb: util.seperator("TMDb Tests") try: config.TMDb.convert_imdb_to_tmdb("tt0076759") logger.info("Success | Convert IMDb to TMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert IMDb to TMDb: {}".format(e)) try: config.TMDb.convert_tmdb_to_imdb(11) logger.info("Success | Convert TMDb to IMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TMDb to IMDb: {}".format(e)) try: config.TMDb.convert_imdb_to_tvdb("tt0458290") logger.info("Success | Convert IMDb to TVDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert IMDb to TVDb: {}".format(e)) try: config.TMDb.convert_tvdb_to_imdb(83268) logger.info("Success | Convert TVDb to IMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TVDb to IMDb: {}".format(e)) tmdb_list_tests = [([11], "Movie"), ([4194], "Show"), ([10], "Collection"), ([1], "Person"), ([1], "Company"), ([2739], "Network"), ([8136], "List")] for tmdb_list_test in tmdb_list_tests: try: config.TMDb.validate_tmdb_list(tmdb_list_test[0], tmdb_type=tmdb_list_test[1]) logger.info("Success | Get TMDb {}".format(tmdb_list_test[1])) except Failed as e: util.print_stacktrace() logger.error("Failure | Get TMDb {}: {}".format( tmdb_list_test[1], e)) tmdb_list_tests = [("tmdb_discover", { "sort_by": "popularity.desc", "limit": 100 }, True), ("tmdb_discover", { "sort_by": "popularity.desc", "limit": 100 }, False), ("tmdb_company", 1, True), ("tmdb_company", 1, False), ("tmdb_network", 2739, False), ("tmdb_keyword", 180547, True), ("tmdb_keyword", 180547, False), ("tmdb_now_playing", 10, True), ("tmdb_popular", 10, True), ("tmdb_popular", 10, False), ("tmdb_top_rated", 10, True), ("tmdb_top_rated", 10, False), ("tmdb_trending_daily", 10, True), ("tmdb_trending_daily", 10, False), ("tmdb_trending_weekly", 10, True), ("tmdb_trending_weekly", 10, False), ("tmdb_list", 7068209, True), ("tmdb_list", 7068209, False), ("tmdb_movie", 11, True), ("tmdb_collection", 10, True), ("tmdb_show", 4194, False)] for tmdb_list_test in tmdb_list_tests: try: config.TMDb.get_items(tmdb_list_test[0], tmdb_list_test[1], tmdb_list_test[2], status_message=False) logger.info("Success | Get {} using {}".format( "Movies" if tmdb_list_test[2] else "Shows", util.pretty_names[tmdb_list_test[0]])) except Failed as e: util.print_stacktrace() logger.error("Failure | Get {} using {}: {}".format( "Movies" if tmdb_list_test[2] else "Shows", util.pretty_names[tmdb_list_test[0]], e)) else: util.seperator("TMDb Not Configured")
def mal_tests(config): if config.MyAnimeListIDList: util.seperator("MyAnimeListXML Tests") try: config.MyAnimeListIDList.convert_mal_to_tvdb(21) logger.info("Success | Convert MyAnimeList to TVDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert MyAnimeList to TVDb: {}".format(e)) try: config.MyAnimeListIDList.convert_mal_to_tmdb(199) logger.info("Success | Convert MyAnimeList to TMDb") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert MyAnimeList to TMDb: {}".format(e)) try: config.MyAnimeListIDList.convert_tvdb_to_mal(81797) logger.info("Success | Convert TVDb to MyAnimeList") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TVDb to MyAnimeList: {}".format(e)) try: config.MyAnimeListIDList.convert_tmdb_to_mal(129) logger.info("Success | Convert TMDb to MyAnimeList") except Failed as e: util.print_stacktrace() logger.error("Failure | Convert TMDb to MyAnimeList: {}".format(e)) try: config.MyAnimeListIDList.find_mal_ids(21) logger.info("Success | Find MyAnimeList ID") except Failed as e: util.print_stacktrace() logger.error("Failure | Find MyAnimeList ID: {}".format(e)) else: util.seperator("MyAnimeListXML Not Configured") if config.MyAnimeList: util.seperator("MyAnimeList Tests") mal_list_tests = [("mal_all", 10), ("mal_airing", 10), ("mal_upcoming", 10), ("mal_tv", 10), ("mal_movie", 10), ("mal_ova", 10), ("mal_special", 10), ("mal_popular", 10), ("mal_favorite", 10), ("mal_suggested", 10), ("mal_userlist", { "limit": 10, "username": "******", "status": "completed", "sort_by": "list_score" }), ("mal_season", { "limit": 10, "season": "fall", "year": 2020, "sort_by": "anime_score" })] for mal_list_test in mal_list_tests: try: config.MyAnimeList.get_items(mal_list_test[0], mal_list_test[1], status_message=False) logger.info("Success | Get Anime using {}".format( util.pretty_names[mal_list_test[0]])) except Failed as e: util.print_stacktrace() logger.error("Failure | Get Anime using {}: {}".format( util.pretty_names[mal_list_test[0]], e)) else: util.seperator("MyAnimeList Not Configured")