#552 add extra check to arrs

pull/556/head
meisnate12 3 years ago
parent eb9fe219aa
commit 1c56b0665e

@ -10,21 +10,21 @@
The original concept for Plex Meta Manager is [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections), but this is rewritten from the ground up to be able to include a scheduler, metadata edits, multiple libraries, and logging. Plex Meta Manager is a Python 3 script that can be continuously run using YAML configuration files to update on a schedule the metadata of the movies, shows, and collections in your libraries as well as automatically build collections based on various methods all detailed in the wiki. Some collection examples that the script can automatically build and update daily include Plex Based Searches like actor, genre, or studio collections or Collections based on TMDb, IMDb, Trakt, TVDb, AniDB, or MyAnimeList lists and various other services. The original concept for Plex Meta Manager is [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections), but this is rewritten from the ground up to be able to include a scheduler, metadata edits, multiple libraries, and logging. Plex Meta Manager is a Python 3 script that can be continuously run using YAML configuration files to update on a schedule the metadata of the movies, shows, and collections in your libraries as well as automatically build collections based on various methods all detailed in the wiki. Some collection examples that the script can automatically build and update daily include Plex Based Searches like actor, genre, or studio collections or Collections based on TMDb, IMDb, Trakt, TVDb, AniDB, or MyAnimeList lists and various other services.
The script can update many metadata fields for movies, shows, collections, seasons, and episodes and can act as a backup if your plex DB goes down. It can even update metadata the plex UI can't like Season Names. If the time is put into the metadata configuration file you can have a way to recreate your library and all its metadata changes with the click of a button. The script can update many metadata fields for movies, shows, collections, seasons, and episodes and can act as a backup if your plex DB goes down. If the time is put into the metadata configuration file you can have a way to recreate your library and all its metadata changes with the click of a button.
The script works with most Metadata agents including the New Plex Movie Agent, New Plex TV Agent, [Hama Anime Agent](https://github.com/ZeroQI/Hama.bundle), [MyAnimeList Anime Agent](https://github.com/Fribb/MyAnimeList.bundle), and [XBMC NFO Movie and TV Agents](https://github.com/gboudreau/XBMCnfoMoviesImporter.bundle). The script works with most Metadata agents including the New Plex Movie Agent, New Plex TV Agent, [Hama Anime Agent](https://github.com/ZeroQI/Hama.bundle), [MyAnimeList Anime Agent](https://github.com/Fribb/MyAnimeList.bundle), and [XBMC NFO Movie and TV Agents](https://github.com/gboudreau/XBMCnfoMoviesImporter.bundle).
## Getting Started ## Getting Started
1. Install Plex Meta Manager either by installing Python3 and following the [Local Installation Guide](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Local-Walkthrough) 1. Install Plex Meta Manager either by installing Python3 and following the [Local Walkthrough](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Local-Walkthrough)
or by installing Docker and following the [Docker Installation Guide](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Docker-Walkthrough) or the [unRAID Installation Guide](https://github.com/meisnate12/Plex-Meta-Manager/wiki/unRAID-Walkthrough). or by installing Docker and following the [Docker Walkthrough](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Docker-Walkthrough) or the [unRAID Walkthrough](https://github.com/meisnate12/Plex-Meta-Manager/wiki/unRAID-Walkthrough).
2. Once installed, you have to create a [Configuration File](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Configuration-File) filled with all your values to connect to the various services. 2. Once installed, you have to create a [Configuration File](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Configuration-File) filled with all your values to connect to the various services.
3. After that you can start updating Metadata and building automatic Collections by creating a [Metadata File](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Metadata-File) for each Library you want to interact with. 3. After that you can start updating Metadata and building automatic Collections by creating a [Metadata and Playlist File](https://github.com/meisnate12/Plex-Meta-Manager/wiki/Metadata-and-Playlist-File) for each Library you want to interact with.
4. Explore the [Wiki](https://github.com/meisnate12/Plex-Meta-Manager/wiki) to see all the different Collection Builders that can be used to create collections. 4. Explore the [Wiki](https://github.com/meisnate12/Plex-Meta-Manager/wiki) to see all the different Collection Builders that can be used to create collections.
## IBRACORP Video Walkthrough ## IBRACORP Video Walkthrough
[IBRACORP](https://ibracorp.io/) made a video walkthough for installing Plex Meta Manager on Unraid. While you might not be using Unraid the video goes over many key aspects of Plex Meta Manager and can be a great place to start learning how to use the script. [IBRACORP](https://ibracorp.io/) made a video walkthough for installing Plex Meta Manager on unRAID. While you might not be using unRAID the video goes over many key aspects of Plex Meta Manager and can be a great place to start learning how to use the script.
[![Plex Meta Manager](https://img.youtube.com/vi/dF69MNoot3w/0.jpg)](https://www.youtube.com/watch?v=dF69MNoot3w "Plex Meta Manager") [![Plex Meta Manager](https://img.youtube.com/vi/dF69MNoot3w/0.jpg)](https://www.youtube.com/watch?v=dF69MNoot3w "Plex Meta Manager")

@ -338,7 +338,6 @@ class MetadataFile(DataFile):
else: else:
logger.error(f"Metadata Error: {attr} attribute is blank") logger.error(f"Metadata Error: {attr} attribute is blank")
logger.info("") logger.info("")
util.separator() util.separator()
logger.info("") logger.info("")

@ -399,7 +399,7 @@ class Plex(Library):
self.Plex = s self.Plex = s
break break
if not self.Plex: if not self.Plex:
raise Failed(f"Plex Error: Plex Library {params['name']} not found. Options: {library_names}") raise Failed(f"Plex Error: Plex Library '{params['name']}' not found. Options: {library_names}")
if self.Plex.type in ["movie", "show", "artist"]: if self.Plex.type in ["movie", "show", "artist"]:
self.type = self.Plex.type.capitalize() self.type = self.Plex.type.capitalize()
else: else:

@ -34,9 +34,6 @@ class Radarr:
self.plex_path = params["plex_path"] if params["radarr_path"] and params["plex_path"] else "" self.plex_path = params["plex_path"] if params["radarr_path"] and params["plex_path"] else ""
def add_tmdb(self, tmdb_ids, **options): def add_tmdb(self, tmdb_ids, **options):
logger.info("")
util.separator("Adding to Radarr", space=False, border=False)
logger.debug("")
_ids = [] _ids = []
_paths = [] _paths = []
for tmdb_id in tmdb_ids: for tmdb_id in tmdb_ids:
@ -44,6 +41,9 @@ class Radarr:
_paths.append(tmdb_id) _paths.append(tmdb_id)
else: else:
_ids.append(tmdb_id) _ids.append(tmdb_id)
logger.info("")
util.separator(f"Adding {'Missing' if _ids else 'Existing'} to Radarr", space=False, border=False)
logger.debug("")
logger.debug(f"Radarr Adds: {_ids if _ids else ''}") logger.debug(f"Radarr Adds: {_ids if _ids else ''}")
for tmdb_id in _paths: for tmdb_id in _paths:
logger.debug(tmdb_id) logger.debug(tmdb_id)
@ -68,10 +68,23 @@ class Radarr:
exists = [] exists = []
skipped = [] skipped = []
invalid = [] invalid = []
invalid_root = []
movies = [] movies = []
path_lookup = {} path_lookup = {}
mismatched = {} mismatched = {}
path_in_use = {} path_in_use = {}
def mass_add():
try:
_a, _e, _i = self.api.add_multiple_movies(movies, folder, quality_profile, monitor, search,
availability, tags, per_request=100)
added.extend(_a)
exists.extend(_e)
invalid.extend(_i)
except ArrException as e:
util.print_stacktrace()
raise Failed(f"Radarr Error: {e}")
for i, item in enumerate(tmdb_ids, 1): for i, item in enumerate(tmdb_ids, 1):
path = item[1] if isinstance(item, tuple) else None path = item[1] if isinstance(item, tuple) else None
tmdb_id = item[0] if isinstance(item, tuple) else item tmdb_id = item[0] if isinstance(item, tuple) else item
@ -88,6 +101,9 @@ class Radarr:
if path and path.lower() in arr_paths: if path and path.lower() in arr_paths:
mismatched[path] = tmdb_id mismatched[path] = tmdb_id
continue continue
if path and not path.startswith(folder):
invalid_root.append(item)
continue
movie = self.api.get_movie(tmdb_id=tmdb_id) movie = self.api.get_movie(tmdb_id=tmdb_id)
if self.config.trace_mode: if self.config.trace_mode:
logger.debug(f"Folder to Check: {folder}/{movie.folder}") logger.debug(f"Folder to Check: {folder}/{movie.folder}")
@ -102,21 +118,16 @@ class Radarr:
except ArrException: except ArrException:
invalid.append(item) invalid.append(item)
if len(movies) == 100 or len(tmdb_ids) == i: if len(movies) == 100 or len(tmdb_ids) == i:
try: mass_add()
_a, _e, _i = self.api.add_multiple_movies(movies, folder, quality_profile, monitor, search, movies = []
availability, tags, per_request=100) if movies:
added.extend(_a) mass_add()
exists.extend(_e)
invalid.extend(_i)
movies = [] movies = []
except ArrException as e:
util.print_stacktrace()
raise Failed(f"Radarr Error: {e}")
if len(added) > 0: if len(added) > 0:
logger.info("") logger.info("")
for movie in added: for movie in added:
logger.info(f"Added to Radarr | {movie.tmdbId:<6} | {movie.title}") logger.info(f"Added to Radarr | {movie.tmdbId:<7} | {movie.title}")
if self.config.Cache: if self.config.Cache:
self.config.Cache.update_radarr_adds(movie.tmdbId, self.library.original_mapping_name) self.config.Cache.update_radarr_adds(movie.tmdbId, self.library.original_mapping_name)
logger.info(f"{len(added)} Movie{'s' if len(added) > 1 else ''} added to Radarr") logger.info(f"{len(added)} Movie{'s' if len(added) > 1 else ''} added to Radarr")
@ -125,7 +136,7 @@ class Radarr:
logger.info("") logger.info("")
if len(exists) > 0: if len(exists) > 0:
for movie in exists: for movie in exists:
logger.info(f"Already in Radarr | {movie.tmdbId:<6} | {movie.title}") logger.info(f"Already in Radarr | {movie.tmdbId:<7} | {movie.title}")
if self.config.Cache: if self.config.Cache:
self.config.Cache.update_radarr_adds(movie.tmdbId, self.library.original_mapping_name) self.config.Cache.update_radarr_adds(movie.tmdbId, self.library.original_mapping_name)
if len(skipped) > 0: if len(skipped) > 0:
@ -153,6 +164,12 @@ class Radarr:
logger.info(f"Invalid TMDb ID | {tmdb_id}") logger.info(f"Invalid TMDb ID | {tmdb_id}")
logger.info(f"{len(invalid)} Movie{'s' if len(invalid) > 1 else ''} with Invalid IDs") logger.info(f"{len(invalid)} Movie{'s' if len(invalid) > 1 else ''} with Invalid IDs")
if len(invalid_root) > 0:
logger.info("")
for tmdb_id, path in invalid_root:
logger.info(f"Invalid Root Folder for TMDb ID | {tmdb_id:<7} | {path}")
logger.info(f"{len(invalid_root)} Movie{'s' if len(invalid_root) > 1 else ''} with Invalid Paths")
return len(added) return len(added)
def edit_tags(self, tmdb_ids, tags, apply_tags): def edit_tags(self, tmdb_ids, tags, apply_tags):

@ -56,9 +56,6 @@ class Sonarr:
self.plex_path = params["plex_path"] if params["sonarr_path"] and params["plex_path"] else "" self.plex_path = params["plex_path"] if params["sonarr_path"] and params["plex_path"] else ""
def add_tvdb(self, tvdb_ids, **options): def add_tvdb(self, tvdb_ids, **options):
logger.info("")
util.separator("Adding to Sonarr", space=False, border=False)
logger.debug("")
_ids = [] _ids = []
_paths = [] _paths = []
for tvdb_id in tvdb_ids: for tvdb_id in tvdb_ids:
@ -66,6 +63,9 @@ class Sonarr:
_paths.append(tvdb_id) _paths.append(tvdb_id)
else: else:
_ids.append(tvdb_id) _ids.append(tvdb_id)
logger.info("")
util.separator(f"Adding {'Missing' if _ids else 'Existing'} to Sonarr", space=False, border=False)
logger.debug("")
logger.debug(f"Sonarr Adds: {_ids if _ids else ''}") logger.debug(f"Sonarr Adds: {_ids if _ids else ''}")
for tvdb_id in _paths: for tvdb_id in _paths:
logger.debug(tvdb_id) logger.debug(tvdb_id)
@ -94,10 +94,23 @@ class Sonarr:
exists = [] exists = []
skipped = [] skipped = []
invalid = [] invalid = []
invalid_root = []
shows = [] shows = []
path_lookup = {} path_lookup = {}
mismatched = {} mismatched = {}
path_in_use = {} path_in_use = {}
def mass_add():
try:
_a, _e, _i = self.api.add_multiple_series(shows, folder, quality_profile, language_profile, monitor,
season, search, cutoff_search, series_type, tags, per_request=100)
added.extend(_a)
exists.extend(_e)
invalid.extend(_i)
except ArrException as e:
util.print_stacktrace()
raise Failed(f"Radarr Error: {e}")
for i, item in enumerate(tvdb_ids, 1): for i, item in enumerate(tvdb_ids, 1):
path = item[1] if isinstance(item, tuple) else None path = item[1] if isinstance(item, tuple) else None
tvdb_id = item[0] if isinstance(item, tuple) else item tvdb_id = item[0] if isinstance(item, tuple) else item
@ -114,6 +127,9 @@ class Sonarr:
if path and path.lower() in arr_paths: if path and path.lower() in arr_paths:
mismatched[path] = tvdb_id mismatched[path] = tvdb_id
continue continue
if path and not path.startswith(folder):
invalid_root.append(item)
continue
show = self.api.get_series(tvdb_id=tvdb_id) show = self.api.get_series(tvdb_id=tvdb_id)
if self.config.trace_mode: if self.config.trace_mode:
logger.debug(f"Folder to Check: {folder}/{show.folder}") logger.debug(f"Folder to Check: {folder}/{show.folder}")
@ -128,21 +144,16 @@ class Sonarr:
except ArrException: except ArrException:
invalid.append(item) invalid.append(item)
if len(shows) == 100 or len(tvdb_ids) == i: if len(shows) == 100 or len(tvdb_ids) == i:
try: mass_add()
_a, _e, _i = self.api.add_multiple_series(shows, folder, quality_profile, language_profile, monitor, shows = []
season, search, cutoff_search, series_type, tags, per_request=100) if shows:
added.extend(_a) mass_add()
exists.extend(_e)
invalid.extend(_i)
shows = [] shows = []
except ArrException as e:
util.print_stacktrace()
raise Failed(f"Sonarr Error: {e}")
if len(added) > 0: if len(added) > 0:
logger.info("") logger.info("")
for series in added: for series in added:
logger.info(f"Added to Sonarr | {series.tvdbId:<6} | {series.title}") logger.info(f"Added to Sonarr | {series.tvdbId:<7} | {series.title}")
if self.config.Cache: if self.config.Cache:
self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name) self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name)
logger.info(f"{len(added)} Series added to Sonarr") logger.info(f"{len(added)} Series added to Sonarr")
@ -151,7 +162,7 @@ class Sonarr:
logger.info("") logger.info("")
if len(exists) > 0: if len(exists) > 0:
for series in exists: for series in exists:
logger.info(f"Already in Sonarr | {series.tvdbId:<6} | {series.title}") logger.info(f"Already in Sonarr | {series.tvdbId:<7} | {series.title}")
if self.config.Cache: if self.config.Cache:
self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name) self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name)
if len(skipped) > 0: if len(skipped) > 0:
@ -179,6 +190,12 @@ class Sonarr:
logger.info(f"Invalid TVDb ID | {tvdb_id}") logger.info(f"Invalid TVDb ID | {tvdb_id}")
logger.info(f"{len(invalid)} Series with Invalid IDs") logger.info(f"{len(invalid)} Series with Invalid IDs")
if len(invalid_root) > 0:
logger.info("")
for tvdb_id, path in invalid_root:
logger.info(f"Invalid Root Folder for TVDb ID | {tvdb_id:<7} | {path}")
logger.info(f"{len(invalid_root)} Series with Invalid Paths")
return len(added) return len(added)
def edit_tags(self, tvdb_ids, tags, apply_tags): def edit_tags(self, tvdb_ids, tags, apply_tags):

Loading…
Cancel
Save