Plex-Meta-Manager/modules/sonarr.py

196 lines
9 KiB
Python
Raw Normal View History

2021-06-14 01:51:30 +00:00
import logging
2021-01-20 21:37:59 +00:00
from modules import util
from modules.util import Failed
2021-06-14 01:51:30 +00:00
from arrapi import SonarrAPI
2021-11-29 19:04:43 +00:00
from arrapi.exceptions import ArrException, Invalid
2021-01-20 21:37:59 +00:00
logger = logging.getLogger("Plex Meta Manager")
series_type = ["standard", "daily", "anime"]
monitor_translation = {
2021-07-23 19:44:21 +00:00
"all": "all", "future": "future", "missing": "missing", "existing": "existing",
"pilot": "pilot", "first": "firstSeason", "latest": "latestSeason", "none": "none"
}
2021-07-23 19:44:21 +00:00
series_type_descriptions = {
"standard": "Episodes released with SxxEyy pattern",
"daily": "Episodes released daily or less frequently that use year-month-day (2017-05-25)",
"anime": "Episodes released using an absolute episode number"
}
2021-07-23 19:44:21 +00:00
monitor_descriptions = {
"all": "Monitor all episodes except specials",
"future": "Monitor episodes that have not aired yet",
"missing": "Monitor episodes that do not have files or have not aired yet",
"existing": "Monitor episodes that have files or have not aired yet",
"pilot": "Monitor the first episode. All other episodes will be ignored",
"first": "Monitor all episodes of the first season. All other seasons will be ignored",
"latest": "Monitor all episodes of the latest season and future seasons",
"none": "No episodes will be monitored"
}
apply_tags_translation = {"": "add", "sync": "replace", "remove": "remove"}
2021-06-14 01:51:30 +00:00
class Sonarr:
2021-11-29 15:24:36 +00:00
def __init__(self, config, library, params):
2021-07-14 14:47:20 +00:00
self.config = config
2021-11-29 15:24:36 +00:00
self.library = library
self.url = params["url"]
2021-04-02 20:15:59 +00:00
self.token = params["token"]
2021-01-20 21:37:59 +00:00
try:
self.api = SonarrAPI(self.url, self.token, session=self.config.session)
self.api.respect_list_exclusions_when_adding()
2021-12-07 02:10:36 +00:00
self.api._validate_add_options(params["root_folder_path"], params["quality_profile"], params["language_profile"])
2021-06-14 01:51:30 +00:00
except ArrException as e:
raise Failed(e)
self.add = params["add"]
2021-08-16 05:41:04 +00:00
self.add_existing = params["add_existing"]
self.root_folder_path = params["root_folder_path"]
self.monitor = params["monitor"]
2021-06-14 01:51:30 +00:00
self.quality_profile = params["quality_profile"]
2021-04-02 15:45:29 +00:00
self.language_profile_id = None
2021-06-14 01:51:30 +00:00
self.language_profile = params["language_profile"]
self.series_type = params["series_type"]
2021-03-01 22:25:38 +00:00
self.season_folder = params["season_folder"]
2021-02-16 14:31:15 +00:00
self.tag = params["tag"]
self.search = params["search"]
self.cutoff_search = params["cutoff_search"]
self.sonarr_path = params["sonarr_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 ""
2021-04-02 20:15:59 +00:00
def add_tvdb(self, tvdb_ids, **options):
2021-05-24 03:38:46 +00:00
logger.info("")
util.separator("Adding to Sonarr", space=False, border=False)
2021-06-14 01:51:30 +00:00
logger.debug("")
2021-11-29 19:04:43 +00:00
_ids = []
_paths = []
for tvdb_id in tvdb_ids:
2021-11-29 19:04:43 +00:00
if isinstance(tvdb_id, tuple):
_paths.append(tvdb_id)
else:
_ids.append(tvdb_id)
logger.debug(f"Radarr Adds: {_ids if _ids else ''}")
for tvdb_id in _paths:
logger.debug(tvdb_id)
folder = options["folder"] if "folder" in options else self.root_folder_path
2021-06-14 01:51:30 +00:00
monitor = monitor_translation[options["monitor"] if "monitor" in options else self.monitor]
quality_profile = options["quality"] if "quality" in options else self.quality_profile
language_profile = options["language"] if "language" in options else self.language_profile
language_profile = language_profile if self.api._raw.v3 else 1
series = options["series"] if "series" in options else self.series_type
season = options["season"] if "season" in options else self.season_folder
tags = options["tag"] if "tag" in options else self.tag
search = options["search"] if "search" in options else self.search
cutoff_search = options["cutoff_search"] if "cutoff_search" in options else self.cutoff_search
arr_paths = {}
arr_ids = {}
for series in self.api.all_series():
if series.path:
2021-12-09 15:23:51 +00:00
arr_paths[series.path[:-1] if series.path.endswith(("/", "\\")) else series.path] = series.tvdbId
arr_paths[series.tvdbId] = series
2021-12-09 15:23:51 +00:00
logger.debug(arr_paths)
logger.debug(arr_ids)
added = []
exists = []
skipped = []
invalid = []
shows = []
path_lookup = {}
mismatched = {}
2021-12-07 02:10:36 +00:00
path_in_use = {}
for i, item in enumerate(tvdb_ids, 1):
path = item[1] if isinstance(item, tuple) else None
tvdb_id = item[0] if isinstance(item, tuple) else item
2021-11-26 08:24:36 +00:00
util.print_return(f"Loading TVDb ID {i}/{len(tvdb_ids)} ({tvdb_id})")
2021-11-29 15:24:36 +00:00
if self.config.Cache:
_id = self.config.Cache.query_sonarr_adds(tvdb_id, self.library.original_mapping_name)
if _id:
skipped.append(item)
2021-11-29 15:24:36 +00:00
continue
try:
if tvdb_id in arr_ids:
exists.append(arr_ids[tvdb_id])
continue
if path in arr_paths:
mismatched[path] = tvdb_id
continue
show = self.api.get_series(tvdb_id=tvdb_id)
2021-12-07 02:10:36 +00:00
if f"{folder}/{show.folder}" in arr_paths:
path_in_use[f"{folder}/{show.folder}"] = tvdb_id
continue
if path:
shows.append((show, path))
path_lookup[path] = tvdb_id
else:
shows.append(show)
2021-11-29 15:24:36 +00:00
except ArrException:
invalid.append(item)
if len(shows) == 100 or len(tvdb_ids) == i:
try:
_a, _e, _i = self.api.add_multiple_series(shows, folder, quality_profile, language_profile, monitor,
season, search, cutoff_search, series, tags, per_request=100)
added.extend(_a)
exists.extend(_e)
invalid.extend(_i)
shows = []
except Invalid as e:
raise Failed(f"Sonarr Error: {e}")
2021-04-05 04:09:26 +00:00
2021-06-14 01:51:30 +00:00
if len(added) > 0:
2021-07-03 01:47:09 +00:00
logger.info("")
2021-06-14 01:51:30 +00:00
for series in added:
logger.info(f"Added to Sonarr | {series.tvdbId:<6} | {series.title}")
2021-11-29 15:24:36 +00:00
if self.config.Cache:
self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name)
2021-06-14 01:51:30 +00:00
logger.info(f"{len(added)} Series added to Sonarr")
2021-01-20 21:37:59 +00:00
if len(exists) > 0 or len(skipped) > 0:
2021-07-03 01:47:09 +00:00
logger.info("")
if len(exists) > 0:
for series in exists:
logger.info(f"Already in Sonarr | {series.tvdbId:<6} | {series.title}")
if self.config.Cache:
self.config.Cache.update_sonarr_adds(series.tvdbId, self.library.original_mapping_name)
if len(skipped) > 0:
for series in skipped:
logger.info(f"Skipped: In Cache | {series}")
logger.info(f"{len(exists) + len(skipped)} Series already exist in Sonarr")
2021-02-16 14:31:15 +00:00
if len(mismatched) > 0:
logger.info("")
2021-12-07 02:10:36 +00:00
logger.info("Items in Plex that have already been added to Sonarr but under a different TVDb ID then in Plex")
for path, tmdb_id in mismatched.items():
logger.info(f"Plex TVDb ID: {tmdb_id:<7} | Sonarr TVDb ID: {arr_paths[path]:<7} | Path: {path}")
logger.info(f"{len(mismatched)} Series with mismatched TVDb IDs")
2021-12-07 02:10:36 +00:00
if len(path_in_use) > 0:
logger.info("")
logger.info("TVDb IDs that cannot be added to Sonarr because the path they will use is already in use by a different TVDb ID")
for path, tvdb_id in path_in_use.items():
logger.info(f"TVDb ID: {tvdb_id:<7} | Sonarr TVDb ID: {arr_paths[path]:<7} | Path: {path}")
logger.info(f"{len(path_in_use)} Series with paths already in use by other TVDb IDs")
if len(invalid) > 0:
for tvdb_id in invalid:
logger.info("")
logger.info(f"Invalid TVDb ID | {tvdb_id}")
logger.info(f"{len(invalid)} Series with Invalid IDs")
2021-11-03 14:36:11 +00:00
return len(added)
def edit_tags(self, tvdb_ids, tags, apply_tags):
logger.info("")
logger.info(f"{apply_tags_translation[apply_tags].capitalize()} Sonarr Tags: {tags}")
2021-08-26 14:35:29 +00:00
edited, not_exists = self.api.edit_multiple_series(tvdb_ids, tags=tags, apply_tags=apply_tags_translation[apply_tags], per_request=100)
if len(edited) > 0:
logger.info("")
for series in edited:
2021-07-06 13:55:52 +00:00
logger.info(f"Sonarr Tags | {series.title:<25} | {series.tags}")
logger.info(f"{len(edited)} Series edited in Sonarr")
if len(not_exists) > 0:
2021-07-03 01:47:09 +00:00
logger.info("")
for tvdb_id in not_exists:
logger.info(f"TVDb ID Not in Sonarr | {tvdb_id}")