mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-10 06:54:21 +00:00
final cleanup for v1.12.0
This commit is contained in:
parent
ae34662ad7
commit
1e2fc34911
11 changed files with 146 additions and 132 deletions
|
@ -89,6 +89,6 @@ mal:
|
|||
token_type:
|
||||
expires_in:
|
||||
refresh_token:
|
||||
anidb:
|
||||
username: ###### - optional
|
||||
anidb: # Optional
|
||||
username: ######
|
||||
password: ######
|
|
@ -4,10 +4,7 @@ from modules.util import Failed
|
|||
|
||||
logger = logging.getLogger("Plex Meta Manager")
|
||||
|
||||
builders = [
|
||||
"anilist_genre", "anilist_id", "anilist_popular", "anilist_relations",
|
||||
"anilist_season", "anilist_studio", "anilist_tag", "anilist_top_rated", "anilist_search"
|
||||
]
|
||||
builders = ["anilist_id", "anilist_popular", "anilist_relations", "anilist_studio", "anilist_top_rated", "anilist_search"]
|
||||
pretty_names = {"score": "Average Score", "popular": "Popularity"}
|
||||
attr_translation = {"year": "seasonYear", "adult": "isAdult", "start": "startDate", "end": "endDate", "tag_category": "tagCategory", "score": "averageScore", "min_tag_percent": "minimumTagRank"}
|
||||
mod_translation = {"": "in", "not": "not_in", "before": "greater", "after": "lesser", "gt": "greater", "gte": "greater", "lt": "lesser", "lte": "lesser"}
|
||||
|
@ -17,12 +14,13 @@ mod_searches = [
|
|||
"episodes.gt", "episodes.gte", "episodes.lt", "episodes.lte", "duration.gt", "duration.gte", "duration.lt", "duration.lte",
|
||||
"score.gt", "score.gte", "score.lt", "score.lte", "popularity.gt", "popularity.gte", "popularity.lt", "popularity.lte"
|
||||
]
|
||||
no_mod_searches = ["season", "year", "adult", "min_tag_percent"]
|
||||
no_mod_searches = ["search", "season", "year", "adult", "min_tag_percent"]
|
||||
searches = mod_searches + no_mod_searches
|
||||
search_types = {
|
||||
"season": "MediaSeason", "seasonYear": "Int", "isAdult": "Boolean", "startDate": "FuzzyDateInt", "endDate": "FuzzyDateInt",
|
||||
"format": "[MediaFormat]", "status": "[MediaStatus]", "genre": "[String]", "tag": "[String]", "tagCategory": "[String]",
|
||||
"episodes": "Int", "duration": "Int", "averageScore": "Int", "popularity": "Int", "minimumTagRank": "Int"
|
||||
"search": "String", "season": "MediaSeason", "seasonYear": "Int", "isAdult": "Boolean", "minimumTagRank": "Int",
|
||||
"startDate": "FuzzyDateInt", "endDate": "FuzzyDateInt", "format": "[MediaFormat]", "status": "[MediaStatus]",
|
||||
"genre": "[String]", "tag": "[String]", "tagCategory": "[String]",
|
||||
"episodes": "Int", "duration": "Int", "averageScore": "Int", "popularity": "Int"
|
||||
}
|
||||
media_season = {"winter": "WINTER", "spring": "SPRING", "summer": "SUMMER", "fall": "FALL"}
|
||||
media_format = {"tv": "TV", "short": "TV_SHORT", "movie": "MOVIE", "special": "SPECIAL", "ova": "OVA", "ona": "ONA", "music": "MUSIC"}
|
||||
|
|
|
@ -39,7 +39,8 @@ method_alias = {
|
|||
"years": "year", "show_year": "year", "show_years": "year",
|
||||
"show_title": "title",
|
||||
"seasonyear": "year", "isadult": "adult", "startdate": "start", "enddate": "end", "averagescore": "score",
|
||||
"minimum_tag_percentage": "min_tag_percent", "minimumtagrank": "min_tag_percent", "minimum_tag_rank": "min_tag_percent"
|
||||
"minimum_tag_percentage": "min_tag_percent", "minimumtagrank": "min_tag_percent", "minimum_tag_rank": "min_tag_percent",
|
||||
"anilist_tag": "anilist_search", "anilist_genre": "anilist_search", "anilist_season": "anilist_search"
|
||||
}
|
||||
filter_translation = {
|
||||
"actor": "actors",
|
||||
|
@ -74,15 +75,15 @@ summary_details = [
|
|||
]
|
||||
poster_details = ["url_poster", "tmdb_poster", "tmdb_profile", "tvdb_poster", "file_poster"]
|
||||
background_details = ["url_background", "tmdb_background", "tvdb_background", "file_background"]
|
||||
boolean_details = ["visible_library", "visible_home", "visible_shared", "show_filtered", "show_missing", "save_missing", "item_assets", "create_asset_folders", "released_missing_only"]
|
||||
boolean_details = ["visible_library", "visible_home", "visible_shared", "show_filtered", "show_missing", "save_missing", "item_assets", "missing_only_released"]
|
||||
string_details = ["sort_title", "content_rating", "name_mapping"]
|
||||
ignored_details = ["smart_filter", "smart_label", "smart_url", "run_again", "schedule", "sync_mode", "template", "test", "tmdb_person", "build_collection", "collection_order", "validate_builders"]
|
||||
details = ["collection_mode", "collection_order", "label"] + boolean_details + string_details
|
||||
collectionless_details = ["collection_order", "plex_collectionless", "label", "label_sync_mode", "test"] + \
|
||||
poster_details + background_details + summary_details + string_details
|
||||
item_details = ["item_label", "item_radarr_tag", "item_sonarr_tag", "item_overlay"] + list(plex.item_advance_keys.keys())
|
||||
radarr_details = ["radarr_add", "radarr_folder", "radarr_monitor", "radarr_search", "radarr_availability", "radarr_quality", "radarr_tag"]
|
||||
sonarr_details = ["sonarr_add", "sonarr_folder", "sonarr_monitor", "sonarr_language", "sonarr_series", "sonarr_quality", "sonarr_season", "sonarr_search", "sonarr_cutoff_search", "sonarr_tag"]
|
||||
radarr_details = ["radarr_add", "radarr_add_existing", "radarr_folder", "radarr_monitor", "radarr_search", "radarr_availability", "radarr_quality", "radarr_tag"]
|
||||
sonarr_details = ["sonarr_add", "sonarr_add_existing", "sonarr_folder", "sonarr_monitor", "sonarr_language", "sonarr_series", "sonarr_quality", "sonarr_season", "sonarr_search", "sonarr_cutoff_search", "sonarr_tag"]
|
||||
all_filters = [
|
||||
"actor", "actor.not",
|
||||
"audio_language", "audio_language.not",
|
||||
|
@ -133,35 +134,34 @@ smart_url_invalid = ["filters", "run_again", "sync_mode", "show_filtered", "show
|
|||
custom_sort_builders = [
|
||||
"tmdb_list", "tmdb_popular", "tmdb_now_playing", "tmdb_top_rated",
|
||||
"tmdb_trending_daily", "tmdb_trending_weekly", "tmdb_discover",
|
||||
"tvdb_list",
|
||||
"imdb_list",
|
||||
"tvdb_list", "imdb_list", "stevenlu_popular", "anidb_popular",
|
||||
"trakt_list", "trakt_trending", "trakt_popular", "trakt_recommended", "trakt_watched", "trakt_collected",
|
||||
"tautulli_popular", "tautulli_watched", "letterboxd_list", "icheckmovies_list",
|
||||
"anidb_popular",
|
||||
"anilist_top_rated", "anilist_popular", "anilist_season", "anilist_studio", "anilist_genre", "anilist_tag",
|
||||
"anilist_top_rated", "anilist_popular", "anilist_season", "anilist_studio", "anilist_genre", "anilist_tag", "anilist_search",
|
||||
"mal_all", "mal_airing", "mal_upcoming", "mal_tv", "mal_movie", "mal_ova", "mal_special",
|
||||
"mal_popular", "mal_favorite", "mal_suggested", "mal_userlist", "mal_season", "mal_genre", "mal_producer"
|
||||
]
|
||||
|
||||
class CollectionBuilder:
|
||||
def __init__(self, config, library, metadata, name, data):
|
||||
def __init__(self, config, library, metadata, name, no_missing, data):
|
||||
self.config = config
|
||||
self.library = library
|
||||
self.metadata = metadata
|
||||
self.name = name
|
||||
self.no_missing = no_missing
|
||||
self.data = data
|
||||
self.language = self.library.Plex.language
|
||||
self.details = {
|
||||
"show_filtered": self.library.show_filtered,
|
||||
"show_missing": self.library.show_missing,
|
||||
"save_missing": self.library.save_missing,
|
||||
"released_missing_only": self.library.released_missing_only,
|
||||
"missing_only_released": self.library.missing_only_released,
|
||||
"create_asset_folders": self.library.create_asset_folders,
|
||||
"item_assets": False
|
||||
}
|
||||
self.item_details = {}
|
||||
self.radarr_options = {}
|
||||
self.sonarr_options = {}
|
||||
self.radarr_details = {}
|
||||
self.sonarr_details = {}
|
||||
self.missing_movies = []
|
||||
self.missing_shows = []
|
||||
self.builders = []
|
||||
|
@ -175,8 +175,6 @@ class CollectionBuilder:
|
|||
self.backgrounds = {}
|
||||
self.summaries = {}
|
||||
self.schedule = ""
|
||||
self.add_to_radarr = None
|
||||
self.add_to_sonarr = None
|
||||
self.current_time = datetime.now()
|
||||
self.current_year = self.current_time.year
|
||||
|
||||
|
@ -538,21 +536,30 @@ class CollectionBuilder:
|
|||
if self.custom_sort and self.builders[0][0] not in custom_sort_builders:
|
||||
raise Failed(f"Collection Error: collection_order: custom cannot be used with {self.builders[0][0]}")
|
||||
|
||||
if self.add_to_radarr is None:
|
||||
self.add_to_radarr = self.library.Radarr.add if self.library.Radarr else False
|
||||
if self.add_to_sonarr is None:
|
||||
self.add_to_sonarr = self.library.Sonarr.add if self.library.Sonarr else False
|
||||
if "add" not in self.radarr_details:
|
||||
self.radarr_details["add"] = self.library.Radarr.add if self.library.Radarr else False
|
||||
if "add_existing" not in self.radarr_details:
|
||||
self.radarr_details["add_existing"] = self.library.Radarr.add_existing if self.library.Radarr else False
|
||||
|
||||
if "add" not in self.sonarr_details:
|
||||
self.sonarr_details["add"] = self.library.Sonarr.add if self.library.Sonarr else False
|
||||
if "add_existing" not in self.sonarr_details:
|
||||
self.sonarr_details["add_existing"] = self.library.Sonarr.add_existing if self.library.Sonarr else False
|
||||
|
||||
if self.smart_url:
|
||||
self.add_to_radarr = False
|
||||
self.add_to_sonarr = False
|
||||
if self.smart_url or self.collectionless:
|
||||
self.radarr_details["add"] = False
|
||||
self.radarr_details["add_existing"] = False
|
||||
self.sonarr_details["add"] = False
|
||||
self.sonarr_details["add_existing"] = False
|
||||
|
||||
if self.collectionless:
|
||||
self.add_to_radarr = False
|
||||
self.add_to_sonarr = False
|
||||
self.details["collection_mode"] = "hide"
|
||||
self.sync = True
|
||||
|
||||
self.do_missing = not self.no_missing and (self.details["show_missing"] or self.details["save_missing"]
|
||||
or (self.library.Radarr and self.radarr_details["add"])
|
||||
or (self.library.Sonarr and self.sonarr_details["add"]))
|
||||
|
||||
if self.build_collection:
|
||||
try:
|
||||
self.obj = self.library.get_collection(self.name)
|
||||
|
@ -684,48 +691,44 @@ class CollectionBuilder:
|
|||
self.item_details[method_name] = str(method_data).lower()
|
||||
|
||||
def _radarr(self, method_name, method_data):
|
||||
if method_name == "radarr_add":
|
||||
self.add_to_radarr = util.parse(method_name, method_data, datatype="bool")
|
||||
if method_name in ["radarr_add", "radarr_add_existing", "radarr_monitor", "radarr_search"]:
|
||||
self.radarr_details[method_name[7:]] = util.parse(method_name, method_data, datatype="bool")
|
||||
elif method_name == "radarr_folder":
|
||||
self.radarr_options["folder"] = method_data
|
||||
elif method_name in ["radarr_monitor", "radarr_search"]:
|
||||
self.radarr_options[method_name[7:]] = util.parse(method_name, method_data, datatype="bool")
|
||||
self.radarr_details["folder"] = method_data
|
||||
elif method_name == "radarr_availability":
|
||||
if str(method_data).lower() in radarr.availability_translation:
|
||||
self.radarr_options["availability"] = str(method_data).lower()
|
||||
self.radarr_details["availability"] = str(method_data).lower()
|
||||
else:
|
||||
raise Failed(f"Collection Error: {method_name} attribute must be either announced, cinemas, released or db")
|
||||
elif method_name == "radarr_quality":
|
||||
self.library.Radarr.get_profile_id(method_data)
|
||||
self.radarr_options["quality"] = method_data
|
||||
self.radarr_details["quality"] = method_data
|
||||
elif method_name == "radarr_tag":
|
||||
self.radarr_options["tag"] = util.get_list(method_data)
|
||||
self.radarr_details["tag"] = util.get_list(method_data)
|
||||
|
||||
def _sonarr(self, method_name, method_data):
|
||||
if method_name == "sonarr_add":
|
||||
self.add_to_sonarr = util.parse(method_name, method_data, datatype="bool")
|
||||
if method_name in ["sonarr_add", "sonarr_add_existing", "sonarr_season", "sonarr_search", "sonarr_cutoff_search"]:
|
||||
self.sonarr_details[method_name[7:]] = util.parse(method_name, method_data, datatype="bool")
|
||||
elif method_name == "sonarr_folder":
|
||||
self.sonarr_options["folder"] = method_data
|
||||
self.sonarr_details["folder"] = method_data
|
||||
elif method_name == "sonarr_monitor":
|
||||
if str(method_data).lower() in sonarr.monitor_translation:
|
||||
self.sonarr_options["monitor"] = str(method_data).lower()
|
||||
self.sonarr_details["monitor"] = str(method_data).lower()
|
||||
else:
|
||||
raise Failed(f"Collection Error: {method_name} attribute must be either all, future, missing, existing, pilot, first, latest or none")
|
||||
elif method_name == "sonarr_quality":
|
||||
self.library.Sonarr.get_profile_id(method_data, "quality_profile")
|
||||
self.sonarr_options["quality"] = method_data
|
||||
self.sonarr_details["quality"] = method_data
|
||||
elif method_name == "sonarr_language":
|
||||
self.library.Sonarr.get_profile_id(method_data, "language_profile")
|
||||
self.sonarr_options["language"] = method_data
|
||||
self.sonarr_details["language"] = method_data
|
||||
elif method_name == "sonarr_series":
|
||||
if str(method_data).lower() in sonarr.series_type:
|
||||
self.sonarr_options["series"] = str(method_data).lower()
|
||||
self.sonarr_details["series"] = str(method_data).lower()
|
||||
else:
|
||||
raise Failed(f"Collection Error: {method_name} attribute must be either standard, daily, or anime")
|
||||
elif method_name in ["sonarr_season", "sonarr_search", "sonarr_cutoff_search"]:
|
||||
self.sonarr_options[method_name[7:]] = util.parse(method_name, method_data, datatype="bool")
|
||||
elif method_name == "sonarr_tag":
|
||||
self.sonarr_options["tag"] = util.get_list(method_data)
|
||||
self.sonarr_details["tag"] = util.get_list(method_data)
|
||||
|
||||
def _anidb(self, method_name, method_data):
|
||||
if method_name == "anidb_popular":
|
||||
|
@ -751,55 +754,47 @@ class CollectionBuilder:
|
|||
self.builders.append((method_name, anilist_id))
|
||||
elif method_name in ["anilist_popular", "anilist_top_rated"]:
|
||||
self.builders.append((method_name, util.parse(method_name, method_data, datatype="int", default=10)))
|
||||
elif method_name in ["anilist_season", "anilist_genre", "anilist_tag"]:
|
||||
elif method_name == "anilist_search":
|
||||
if self.current_time.month in [12, 1, 2]: current_season = "winter"
|
||||
elif self.current_time.month in [3, 4, 5]: current_season = "spring"
|
||||
elif self.current_time.month in [6, 7, 8]: current_season = "summer"
|
||||
else: current_season = "fall"
|
||||
for dict_data, dict_methods in util.parse(method_name, method_data, datatype="dictlist"):
|
||||
new_dictionary = {}
|
||||
if method_name == "anilist_season":
|
||||
if self.current_time.month in [12, 1, 2]: new_dictionary["season"] = "winter"
|
||||
elif self.current_time.month in [3, 4, 5]: new_dictionary["season"] = "spring"
|
||||
elif self.current_time.month in [6, 7, 8]: new_dictionary["season"] = "summer"
|
||||
elif self.current_time.month in [9, 10, 11]: new_dictionary["season"] = "fall"
|
||||
new_dictionary["season"] = util.parse("season", dict_data, methods=dict_methods, parent=method_name, default=new_dictionary["season"], options=util.seasons)
|
||||
new_dictionary["year"] = util.parse("year", dict_data, datatype="int", methods=dict_methods, default=self.current_year, parent=method_name, minimum=1917, maximum=self.current_year + 1)
|
||||
elif method_name == "anilist_genre":
|
||||
new_dictionary["genre"] = self.config.AniList.validate("Genre", util.parse("genre", dict_data, methods=dict_methods, parent=method_name))
|
||||
elif method_name == "anilist_tag":
|
||||
new_dictionary["tag"] = self.config.AniList.validate("Tag", util.parse("tag", dict_data, methods=dict_methods, parent=method_name))
|
||||
elif method_name == "anilist_search":
|
||||
for search_method, search_data in dict_data.items():
|
||||
search_attr, modifier, search_final = self._split(search_method)
|
||||
if search_data is None:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute is blank")
|
||||
elif search_final not in anilist.searches:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute not supported")
|
||||
elif search_attr == "season":
|
||||
if self.current_time.month in [12, 1, 2]: new_dictionary["season"] = "winter"
|
||||
elif self.current_time.month in [3, 4, 5]: new_dictionary["season"] = "spring"
|
||||
elif self.current_time.month in [6, 7, 8]: new_dictionary["season"] = "summer"
|
||||
elif self.current_time.month in [9, 10, 11]: new_dictionary["season"] = "fall"
|
||||
new_dictionary["season"] = util.parse("season", dict_data, parent=method_name, default=new_dictionary["season"], options=util.seasons)
|
||||
if "year" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: {method_name} {search_final} attribute must be used with the year attribute using this year by default")
|
||||
elif search_attr == "year":
|
||||
if "season" not in dict_methods:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute must be used with the season attribute")
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="int", parent=method_name, default=self.current_year, minimum=1917, maximum=self.current_year + 1)
|
||||
elif search_attr == "adult":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="bool", parent=method_name)
|
||||
elif search_attr in ["episodes", "duration", "score", "popularity"]:
|
||||
new_dictionary[search_final] = util.parse(search_final, search_data, datatype="int", parent=method_name)
|
||||
elif search_attr in ["format", "status", "genre", "tag", "tag_category"]:
|
||||
new_dictionary[search_final] = self.config.AniList.validate(search_attr.replace("_", " ").title(), util.parse(search_final, search_data))
|
||||
elif search_attr in ["start", "end"]:
|
||||
new_dictionary[search_final] = util.validate_date(search_data, f"{method_name} {search_final} attribute", return_as="%m/%d/%Y")
|
||||
elif search_attr == "min_tag_percent":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="int", parent=method_name, minimum=0, maximum=100)
|
||||
elif search_final not in ["sort_by", "limit"]:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute not supported")
|
||||
if len(new_dictionary) > 0:
|
||||
raise Failed(f"Collection Error: {method_name} must have at least one valid search option")
|
||||
for search_method, search_data in dict_data.items():
|
||||
search_attr, modifier, search_final = self._split(search_method)
|
||||
if search_data is None:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute is blank")
|
||||
elif search_final not in anilist.searches:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute not supported")
|
||||
elif search_attr == "season":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, parent=method_name, default=current_season, options=util.seasons)
|
||||
if "year" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: {method_name} year attribute not found using this year: {self.current_year} by default")
|
||||
new_dictionary["year"] = self.current_year
|
||||
elif search_attr == "year":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="int", parent=method_name, default=self.current_year, minimum=1917, maximum=self.current_year + 1)
|
||||
if "season" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: {method_name} season attribute not found using this season: {current_season} by default")
|
||||
new_dictionary["season"] = current_season
|
||||
elif search_attr == "adult":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="bool", parent=method_name)
|
||||
elif search_attr in ["episodes", "duration", "score", "popularity"]:
|
||||
new_dictionary[search_final] = util.parse(search_final, search_data, datatype="int", parent=method_name)
|
||||
elif search_attr in ["format", "status", "genre", "tag", "tag_category"]:
|
||||
new_dictionary[search_final] = self.config.AniList.validate(search_attr.replace("_", " ").title(), util.parse(search_final, search_data))
|
||||
elif search_attr in ["start", "end"]:
|
||||
new_dictionary[search_final] = util.validate_date(search_data, f"{method_name} {search_final} attribute", return_as="%m/%d/%Y")
|
||||
elif search_attr == "min_tag_percent":
|
||||
new_dictionary[search_attr] = util.parse(search_attr, search_data, datatype="int", parent=method_name, minimum=0, maximum=100)
|
||||
elif search_attr == "search":
|
||||
new_dictionary[search_attr] = str(search_data)
|
||||
elif search_final not in ["sort_by", "limit"]:
|
||||
raise Failed(f"Collection Error: {method_name} {search_final} attribute not supported")
|
||||
if len(new_dictionary) > 0:
|
||||
raise Failed(f"Collection Error: {method_name} must have at least one valid search option")
|
||||
new_dictionary["sort_by"] = util.parse("sort_by", dict_data, methods=dict_methods, parent=method_name, default="score", options=["score", "popular"])
|
||||
new_dictionary["limit"] = util.parse("limit", dict_data, datatype="int", methods=dict_methods, default=0, parent=method_name, maximum=500)
|
||||
new_dictionary["limit"] = util.parse("limit", dict_data, datatype="int", methods=dict_methods, default=0, parent=method_name)
|
||||
self.builders.append((method_name, new_dictionary))
|
||||
|
||||
def _icheckmovies(self, method_name, method_data):
|
||||
|
@ -1029,7 +1024,7 @@ class CollectionBuilder:
|
|||
else:
|
||||
logger.error(message)
|
||||
|
||||
def find_rating_keys(self, no_missing):
|
||||
def find_rating_keys(self):
|
||||
for method, value in self.builders:
|
||||
ids = []
|
||||
rating_keys = []
|
||||
|
@ -1094,9 +1089,7 @@ class CollectionBuilder:
|
|||
if input_id in self.library.imdb_map:
|
||||
rating_keys.append(self.library.imdb_map[input_id][0])
|
||||
else:
|
||||
if (self.details["show_missing"] or self.details["save_missing"]
|
||||
or (self.library.Radarr and self.add_to_radarr)
|
||||
or (self.library.Sonarr and self.add_to_sonarr)) and not no_missing:
|
||||
if self.do_missing:
|
||||
try:
|
||||
tmdb_id, tmdb_type = self.config.Convert.imdb_to_tmdb(input_id)
|
||||
if tmdb_type == "movie":
|
||||
|
@ -1553,7 +1546,7 @@ class CollectionBuilder:
|
|||
logger.error(e)
|
||||
continue
|
||||
current_title = f"{movie.title} ({util.validate_date(movie.release_date, 'test').year})" if movie.release_date else movie.title
|
||||
if self.check_tmdb_filter(missing_id, True, item=movie, check_released=self.details["released_missing_only"]):
|
||||
if self.check_tmdb_filter(missing_id, True, item=movie, check_released=self.details["missing_only_released"]):
|
||||
missing_movies_with_names.append((current_title, missing_id))
|
||||
if self.details["show_missing"] is True:
|
||||
logger.info(f"{self.name} Collection | ? | {current_title} (TMDb: {missing_id})")
|
||||
|
@ -1565,12 +1558,12 @@ class CollectionBuilder:
|
|||
if len(missing_movies_with_names) > 0:
|
||||
if self.details["save_missing"] is True:
|
||||
self.library.add_missing(self.name, missing_movies_with_names, True)
|
||||
if self.run_again or (self.library.Radarr and (self.add_to_radarr or "item_radarr_tag" in self.item_details)):
|
||||
if self.run_again or (self.library.Radarr and (self.radarr_details["add"] or "item_radarr_tag" in self.item_details)):
|
||||
missing_tmdb_ids = [missing_id for title, missing_id in missing_movies_with_names]
|
||||
if self.library.Radarr:
|
||||
if self.add_to_radarr:
|
||||
if self.radarr_details["add"]:
|
||||
try:
|
||||
self.library.Radarr.add_tmdb(missing_tmdb_ids, **self.radarr_options)
|
||||
self.library.Radarr.add_tmdb(missing_tmdb_ids, **self.radarr_details)
|
||||
except Failed as e:
|
||||
logger.error(e)
|
||||
if "item_radarr_tag" in self.item_details:
|
||||
|
@ -1589,7 +1582,7 @@ class CollectionBuilder:
|
|||
logger.error(e)
|
||||
continue
|
||||
current_title = str(show.title.encode("ascii", "replace").decode())
|
||||
if self.check_tmdb_filter(missing_id, False, check_released=self.details["released_missing_only"]):
|
||||
if self.check_tmdb_filter(missing_id, False, check_released=self.details["missing_only_released"]):
|
||||
missing_shows_with_names.append((current_title, missing_id))
|
||||
if self.details["show_missing"] is True:
|
||||
logger.info(f"{self.name} Collection | ? | {current_title} (TVDB: {missing_id})")
|
||||
|
@ -1601,12 +1594,12 @@ class CollectionBuilder:
|
|||
if len(missing_shows_with_names) > 0:
|
||||
if self.details["save_missing"] is True:
|
||||
self.library.add_missing(self.name, missing_shows_with_names, False)
|
||||
if self.run_again or (self.library.Sonarr and (self.add_to_sonarr or "item_sonarr_tag" in self.item_details)):
|
||||
if self.run_again or (self.library.Sonarr and (self.sonarr_details["add"] or "item_sonarr_tag" in self.item_details)):
|
||||
missing_tvdb_ids = [missing_id for title, missing_id in missing_shows_with_names]
|
||||
if self.library.Sonarr:
|
||||
if self.add_to_sonarr:
|
||||
if self.sonarr_details["add"]:
|
||||
try:
|
||||
self.library.Sonarr.add_tvdb(missing_tvdb_ids, **self.sonarr_options)
|
||||
self.library.Sonarr.add_tvdb(missing_tvdb_ids, **self.sonarr_details)
|
||||
except Failed as e:
|
||||
logger.error(e)
|
||||
if "item_sonarr_tag" in self.item_details:
|
||||
|
@ -1693,9 +1686,9 @@ class CollectionBuilder:
|
|||
except Failed as e:
|
||||
logger.error(e)
|
||||
self.library.edit_tags("label", item, add_tags=add_tags, remove_tags=remove_tags, sync_tags=sync_tags)
|
||||
if "item_radarr_tag" in self.item_details and item.ratingKey in self.library.movie_rating_key_map:
|
||||
if item.ratingKey in self.library.movie_rating_key_map:
|
||||
tmdb_ids.append(self.library.movie_rating_key_map[item.ratingKey])
|
||||
if "item_sonarr_tag" in self.item_details and item.ratingKey in self.library.show_rating_key_map:
|
||||
if item.ratingKey in self.library.show_rating_key_map:
|
||||
tvdb_ids.append(self.library.show_rating_key_map[item.ratingKey])
|
||||
advance_edits = {}
|
||||
for method_name, method_data in self.item_details.items():
|
||||
|
@ -1706,10 +1699,16 @@ class CollectionBuilder:
|
|||
self.library.edit_item(item, item.title, "Movie" if self.library.is_movie else "Show", advance_edits, advanced=True)
|
||||
|
||||
if len(tmdb_ids) > 0:
|
||||
self.library.Radarr.edit_tags(tmdb_ids, self.item_details["item_radarr_tag"], self.item_details["apply_tags"])
|
||||
if "item_radarr_tag" in self.item_details:
|
||||
self.library.Radarr.edit_tags(tmdb_ids, self.item_details["item_radarr_tag"], self.item_details["apply_tags"])
|
||||
if self.radarr_details["add_existing"]:
|
||||
self.library.Radarr.add_tmdb(tmdb_ids, **self.radarr_details)
|
||||
|
||||
if len(tvdb_ids) > 0:
|
||||
self.library.Sonarr.edit_tags(tvdb_ids, self.item_details["item_sonarr_tag"], self.item_details["apply_tags"])
|
||||
if "item_sonarr_tag" in self.item_details:
|
||||
self.library.Sonarr.edit_tags(tvdb_ids, self.item_details["item_sonarr_tag"], self.item_details["apply_tags"])
|
||||
if self.sonarr_details["add_existing"]:
|
||||
self.library.Sonarr.add_tvdb(tvdb_ids, **self.sonarr_details)
|
||||
|
||||
for rating_key in rating_keys:
|
||||
try:
|
||||
|
|
|
@ -183,7 +183,7 @@ class Config:
|
|||
"show_filtered": check_for_attribute(self.data, "show_filtered", parent="settings", var_type="bool", default=False),
|
||||
"show_missing": check_for_attribute(self.data, "show_missing", parent="settings", var_type="bool", default=True),
|
||||
"save_missing": check_for_attribute(self.data, "save_missing", parent="settings", var_type="bool", default=True),
|
||||
"released_missing_only": check_for_attribute(self.data, "released_missing_only", parent="settings", var_type="bool", default=False),
|
||||
"missing_only_released": check_for_attribute(self.data, "missing_only_released", parent="settings", var_type="bool", default=False),
|
||||
"create_asset_folders": check_for_attribute(self.data, "create_asset_folders", parent="settings", var_type="bool", default=False)
|
||||
}
|
||||
if self.general["cache"]:
|
||||
|
@ -295,6 +295,7 @@ class Config:
|
|||
"url": check_for_attribute(self.data, "url", parent="radarr", var_type="url", default_is_none=True),
|
||||
"token": check_for_attribute(self.data, "token", parent="radarr", default_is_none=True),
|
||||
"add": check_for_attribute(self.data, "add", parent="radarr", var_type="bool", default=False),
|
||||
"add_existing": check_for_attribute(self.data, "add_existing", parent="radarr", var_type="bool", default=False),
|
||||
"root_folder_path": check_for_attribute(self.data, "root_folder_path", parent="radarr", default_is_none=True),
|
||||
"monitor": check_for_attribute(self.data, "monitor", parent="radarr", var_type="bool", default=True),
|
||||
"availability": check_for_attribute(self.data, "availability", parent="radarr", test_list=radarr.availability_descriptions, default="announced"),
|
||||
|
@ -306,6 +307,7 @@ class Config:
|
|||
"url": check_for_attribute(self.data, "url", parent="sonarr", var_type="url", default_is_none=True),
|
||||
"token": check_for_attribute(self.data, "token", parent="sonarr", default_is_none=True),
|
||||
"add": check_for_attribute(self.data, "add", parent="sonarr", var_type="bool", default=False),
|
||||
"add_existing": check_for_attribute(self.data, "add_existing", parent="sonarr", var_type="bool", default=False),
|
||||
"root_folder_path": check_for_attribute(self.data, "root_folder_path", parent="sonarr", default_is_none=True),
|
||||
"monitor": check_for_attribute(self.data, "monitor", parent="sonarr", test_list=sonarr.monitor_descriptions, default="all"),
|
||||
"quality_profile": check_for_attribute(self.data, "quality_profile", parent="sonarr", default_is_none=True),
|
||||
|
@ -349,7 +351,7 @@ class Config:
|
|||
params["show_filtered"] = check_for_attribute(lib, "show_filtered", parent="settings", var_type="bool", default=self.general["show_filtered"], do_print=False, save=False)
|
||||
params["show_missing"] = check_for_attribute(lib, "show_missing", parent="settings", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
|
||||
params["save_missing"] = check_for_attribute(lib, "save_missing", parent="settings", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
|
||||
params["released_missing_only"] = check_for_attribute(lib, "released_missing_only", parent="settings", var_type="bool", default=self.general["released_missing_only"], do_print=False, save=False)
|
||||
params["missing_only_released"] = check_for_attribute(lib, "missing_only_released", parent="settings", var_type="bool", default=self.general["missing_only_released"], do_print=False, save=False)
|
||||
params["create_asset_folders"] = check_for_attribute(lib, "create_asset_folders", parent="settings", var_type="bool", default=self.general["create_asset_folders"], do_print=False, save=False)
|
||||
|
||||
params["mass_genre_update"] = check_for_attribute(lib, "mass_genre_update", test_list=mass_update_options, default_is_none=True, save=False, do_print=lib and "mass_genre_update" in lib)
|
||||
|
@ -427,6 +429,7 @@ class Config:
|
|||
"url": check_for_attribute(lib, "url", parent="radarr", var_type="url", default=self.general["radarr"]["url"], req_default=True, save=False),
|
||||
"token": check_for_attribute(lib, "token", parent="radarr", default=self.general["radarr"]["token"], req_default=True, save=False),
|
||||
"add": check_for_attribute(lib, "add", parent="radarr", var_type="bool", default=self.general["radarr"]["add"], save=False),
|
||||
"add_existing": check_for_attribute(lib, "add_existing", parent="radarr", var_type="bool", default=self.general["radarr"]["add_existing"], save=False),
|
||||
"root_folder_path": check_for_attribute(lib, "root_folder_path", parent="radarr", default=self.general["radarr"]["root_folder_path"], req_default=True, save=False),
|
||||
"monitor": check_for_attribute(lib, "monitor", parent="radarr", var_type="bool", default=self.general["radarr"]["monitor"], save=False),
|
||||
"availability": check_for_attribute(lib, "availability", parent="radarr", test_list=radarr.availability_descriptions, default=self.general["radarr"]["availability"], save=False),
|
||||
|
@ -451,6 +454,7 @@ class Config:
|
|||
"url": check_for_attribute(lib, "url", parent="sonarr", var_type="url", default=self.general["sonarr"]["url"], req_default=True, save=False),
|
||||
"token": check_for_attribute(lib, "token", parent="sonarr", default=self.general["sonarr"]["token"], req_default=True, save=False),
|
||||
"add": check_for_attribute(lib, "add", parent="sonarr", var_type="bool", default=self.general["sonarr"]["add"], save=False),
|
||||
"add_existing": check_for_attribute(lib, "add_existing", parent="sonarr", var_type="bool", default=self.general["sonarr"]["add_existing"], save=False),
|
||||
"root_folder_path": check_for_attribute(lib, "root_folder_path", parent="sonarr", default=self.general["sonarr"]["root_folder_path"], req_default=True, save=False),
|
||||
"monitor": check_for_attribute(lib, "monitor", parent="sonarr", test_list=sonarr.monitor_descriptions, default=self.general["sonarr"]["monitor"], save=False),
|
||||
"quality_profile": check_for_attribute(lib, "quality_profile", parent="sonarr", default=self.general["sonarr"]["quality_profile"], req_default=True, save=False),
|
||||
|
|
|
@ -85,7 +85,7 @@ class Convert:
|
|||
if tvdb_id:
|
||||
ids.append((tvdb_id, "tvdb"))
|
||||
if tmdb_ids:
|
||||
ids.extend((tmdb_ids, "tmdb"))
|
||||
ids.extend([(t, "tmdb") for t in tmdb_ids])
|
||||
except Failed as e:
|
||||
logger.error(e)
|
||||
return ids
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import logging, re, secrets, time, webbrowser
|
||||
import logging, math, re, secrets, time, webbrowser
|
||||
from modules import util
|
||||
from modules.util import Failed, TimeoutExpired
|
||||
from ruamel import yaml
|
||||
|
@ -169,12 +169,26 @@ class MyAnimeList:
|
|||
if total_items < limit or limit <= 0:
|
||||
limit = total_items
|
||||
mal_ids = []
|
||||
for i in range(1, int(((total_items - 1) / 100) + 2)):
|
||||
if i > 1:
|
||||
data = self._jiken_request(f"/genre/anime/{genre_id}/{i}")
|
||||
mal_ids.extend([anime["mal_id"] for anime in data["anime"]])
|
||||
if len(mal_ids) > limit:
|
||||
return mal_ids[:limit]
|
||||
num_of_pages = math.ceil(int(limit) / 100)
|
||||
current_page = 1
|
||||
chances = 0
|
||||
while current_page <= num_of_pages:
|
||||
if chances > 6:
|
||||
logger.debug(data)
|
||||
raise Failed("AniList Error: Connection Failed")
|
||||
start_num = (current_page - 1) * 100 + 1
|
||||
util.print_return(f"Parsing Page {current_page}/{num_of_pages} {start_num}-{limit if current_page == num_of_pages else current_page * 100}")
|
||||
if current_page > 1:
|
||||
data = self._jiken_request(f"/genre/anime/{genre_id}/{current_page}")
|
||||
if "anime" in data:
|
||||
chances = 0
|
||||
mal_ids.extend([anime["mal_id"] for anime in data["anime"]])
|
||||
if len(mal_ids) > limit:
|
||||
return mal_ids[:limit]
|
||||
current_page += 1
|
||||
else:
|
||||
chances += 1
|
||||
util.print_end()
|
||||
return mal_ids
|
||||
|
||||
def _producer(self, producer_id, limit):
|
||||
|
|
|
@ -288,7 +288,7 @@ class Plex:
|
|||
self.show_filtered = params["show_filtered"]
|
||||
self.show_missing = params["show_missing"]
|
||||
self.save_missing = params["save_missing"]
|
||||
self.released_missing_only = params["released_missing_only"]
|
||||
self.missing_only_released = params["missing_only_released"]
|
||||
self.create_asset_folders = params["create_asset_folders"]
|
||||
self.mass_genre_update = params["mass_genre_update"]
|
||||
self.mass_audience_rating_update = params["mass_audience_rating_update"]
|
||||
|
|
|
@ -20,6 +20,7 @@ class Radarr:
|
|||
except ArrException as e:
|
||||
raise Failed(e)
|
||||
self.add = params["add"]
|
||||
self.add_existing = params["add_existing"]
|
||||
self.root_folder_path = params["root_folder_path"]
|
||||
self.monitor = params["monitor"]
|
||||
self.availability = params["availability"]
|
||||
|
|
|
@ -38,6 +38,7 @@ class Sonarr:
|
|||
except ArrException as e:
|
||||
raise Failed(e)
|
||||
self.add = params["add"]
|
||||
self.add_existing = params["add_existing"]
|
||||
self.root_folder_path = params["root_folder_path"]
|
||||
self.monitor = params["monitor"]
|
||||
self.quality_profile = params["quality_profile"]
|
||||
|
|
|
@ -108,7 +108,7 @@ def start(config_path, is_test=False, time_scheduled=None, requested_collections
|
|||
logger.info(util.centered("| __/| | __/> < | | | | __/ || (_| | | | | | (_| | | | | (_| | (_| | __/ | "))
|
||||
logger.info(util.centered("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| "))
|
||||
logger.info(util.centered(" |___/ "))
|
||||
logger.info(util.centered(" Version: 1.11.3-beta5 "))
|
||||
logger.info(util.centered(" Version: 1.12.0 "))
|
||||
if time_scheduled: start_type = f"{time_scheduled} "
|
||||
elif is_test: start_type = "Test "
|
||||
elif requested_collections: start_type = "Collections "
|
||||
|
@ -474,7 +474,7 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
|
||||
util.separator(f"Validating {mapping_name} Attributes", space=False, border=False)
|
||||
|
||||
builder = CollectionBuilder(config, library, metadata, mapping_name, collection_attrs)
|
||||
builder = CollectionBuilder(config, library, metadata, mapping_name, no_missing, collection_attrs)
|
||||
logger.info("")
|
||||
|
||||
util.separator(f"Building {mapping_name} Collection", space=False, border=False)
|
||||
|
@ -495,16 +495,14 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
for filter_key, filter_value in builder.filters:
|
||||
logger.info(f"Collection Filter {filter_key}: {filter_value}")
|
||||
|
||||
builder.find_rating_keys(no_missing)
|
||||
builder.find_rating_keys()
|
||||
|
||||
if len(builder.rating_keys) > 0 and builder.build_collection:
|
||||
logger.info("")
|
||||
util.separator(f"Adding to {mapping_name} Collection", space=False, border=False)
|
||||
logger.info("")
|
||||
builder.add_to_collection()
|
||||
if (builder.details["show_missing"] or builder.details["save_missing"]
|
||||
or (library.Radarr and builder.add_to_radarr) or (library.Sonarr and builder.add_to_sonarr)) \
|
||||
and (len(builder.missing_movies) > 0 or len(builder.missing_shows) > 0) and not no_missing:
|
||||
if builder.do_missing and (len(builder.missing_movies) > 0 or len(builder.missing_shows) > 0):
|
||||
if builder.details["show_missing"] is True:
|
||||
logger.info("")
|
||||
util.separator(f"Missing from Library", space=False, border=False)
|
||||
|
|
|
@ -7,5 +7,4 @@ ruamel.yaml==0.17.10
|
|||
schedule==1.1.0
|
||||
retrying==1.3.3
|
||||
pathvalidate==2.4.1
|
||||
pillow==8.3.1
|
||||
python-slugify==5.0.2
|
||||
pillow==8.3.1
|
Loading…
Reference in a new issue