mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-10 06:54:21 +00:00
changed dictionary operations
This commit is contained in:
parent
1b59adf541
commit
eeb2320f62
3 changed files with 322 additions and 321 deletions
|
@ -86,9 +86,9 @@ class CollectionBuilder:
|
|||
else:
|
||||
raise Failed("Collection Error: template sub-attribute optional is blank")
|
||||
|
||||
for m in template:
|
||||
if m not in self.data and m not in ["default", "optional"]:
|
||||
if template[m]:
|
||||
for method_name, attr_data in template:
|
||||
if method_name not in self.data and method_name not in ["default", "optional"]:
|
||||
if attr_data:
|
||||
def replace_txt(txt):
|
||||
txt = str(txt)
|
||||
for option in optional:
|
||||
|
@ -108,33 +108,33 @@ class CollectionBuilder:
|
|||
try: return int(txt)
|
||||
except ValueError: return txt
|
||||
try:
|
||||
if isinstance(template[m], dict):
|
||||
a = {}
|
||||
for sm in template[m]:
|
||||
if isinstance(template[m][sm], list):
|
||||
if isinstance(attr_data, dict):
|
||||
discover_name = {}
|
||||
for sm in attr_data:
|
||||
if isinstance(attr_data[sm], list):
|
||||
temp_list = []
|
||||
for li in template[m][sm]:
|
||||
for li in attr_data[sm]:
|
||||
temp_list.append(replace_txt(li))
|
||||
a[sm] = temp_list
|
||||
discover_name[sm] = temp_list
|
||||
else:
|
||||
a[sm] = replace_txt(template[m][sm])
|
||||
elif isinstance(template[m], list):
|
||||
a = []
|
||||
for li in template[m]:
|
||||
discover_name[sm] = replace_txt(attr_data[sm])
|
||||
elif isinstance(attr_data, list):
|
||||
discover_name = []
|
||||
for li in attr_data:
|
||||
if isinstance(li, dict):
|
||||
temp_dict = {}
|
||||
for sm in li:
|
||||
temp_dict[sm] = replace_txt(li[sm])
|
||||
a.append(temp_dict)
|
||||
discover_name.append(temp_dict)
|
||||
else:
|
||||
a.append(replace_txt(li))
|
||||
discover_name.append(replace_txt(li))
|
||||
else:
|
||||
a = replace_txt(template[m])
|
||||
discover_name = replace_txt(attr_data)
|
||||
except Failed:
|
||||
continue
|
||||
self.data[m] = a
|
||||
self.data[method_name] = discover_name
|
||||
else:
|
||||
raise Failed(f"Collection Error: template attribute {m} is blank")
|
||||
raise Failed(f"Collection Error: template attribute {method_name} is blank")
|
||||
|
||||
skip_collection = True
|
||||
if "schedule" not in methods:
|
||||
|
@ -211,21 +211,21 @@ class CollectionBuilder:
|
|||
else:
|
||||
raise Failed("Collection Error: tmdb_person attribute is blank")
|
||||
|
||||
for m in self.data:
|
||||
if "tmdb" in m.lower() and not config.TMDb: raise Failed(f"Collection Error: {m} requires TMDb to be configured")
|
||||
elif "trakt" in m.lower() and not config.Trakt: raise Failed(f"Collection Error: {m} requires Trakt todo be configured")
|
||||
elif "imdb" in m.lower() and not config.IMDb: raise Failed(f"Collection Error: {m} requires TMDb or Trakt to be configured")
|
||||
elif "tautulli" in m.lower() and not self.library.Tautulli: raise Failed(f"Collection Error: {m} requires Tautulli to be configured")
|
||||
elif "mal" in m.lower() and not config.MyAnimeList: raise Failed(f"Collection Error: {m} requires MyAnimeList to be configured")
|
||||
elif self.data[m] is not None:
|
||||
for method_name, method_data in self.data.items():
|
||||
if "tmdb" in method_name.lower() and not config.TMDb: raise Failed(f"Collection Error: {method_name} requires TMDb to be configured")
|
||||
elif "trakt" in method_name.lower() and not config.Trakt: raise Failed(f"Collection Error: {method_name} requires Trakt todo be configured")
|
||||
elif "imdb" in method_name.lower() and not config.IMDb: raise Failed(f"Collection Error: {method_name} requires TMDb or Trakt to be configured")
|
||||
elif "tautulli" in method_name.lower() and not self.library.Tautulli: raise Failed(f"Collection Error: {method_name} requires Tautulli to be configured")
|
||||
elif "mal" in method_name.lower() and not config.MyAnimeList: raise Failed(f"Collection Error: {method_name} requires MyAnimeList to be configured")
|
||||
elif method_data is not None:
|
||||
logger.debug("")
|
||||
logger.debug(f"Method: {m}")
|
||||
logger.debug(f"Value: {self.data[m]}")
|
||||
if m.lower() in util.method_alias:
|
||||
method_name = util.method_alias[m.lower()]
|
||||
logger.warning(f"Collection Warning: {m} attribute will run as {method_name}")
|
||||
logger.debug(f"Method: {method_name}")
|
||||
logger.debug(f"Value: {method_data}")
|
||||
if method_name.lower() in util.method_alias:
|
||||
method_name = util.method_alias[method_name.lower()]
|
||||
logger.warning(f"Collection Warning: {method_name} attribute will run as {method_name}")
|
||||
else:
|
||||
method_name = m.lower()
|
||||
method_name = method_name.lower()
|
||||
if method_name in util.show_only_lists and self.library.is_movie:
|
||||
raise Failed(f"Collection Error: {method_name} attribute only works for show libraries")
|
||||
elif method_name in util.movie_only_lists and self.library.is_show:
|
||||
|
@ -235,76 +235,76 @@ class CollectionBuilder:
|
|||
elif method_name not in util.collectionless_lists and self.collectionless:
|
||||
raise Failed(f"Collection Error: {method_name} attribute does not work for Collectionless collection")
|
||||
elif method_name == "summary":
|
||||
self.summaries[method_name] = self.data[m]
|
||||
self.summaries[method_name] = method_data
|
||||
elif method_name == "tmdb_summary":
|
||||
self.summaries[method_name] = config.TMDb.get_movie_show_or_collection(util.regex_first_int(self.data[m], "TMDb ID"), self.library.is_movie).overview
|
||||
self.summaries[method_name] = config.TMDb.get_movie_show_or_collection(util.regex_first_int(method_data, "TMDb ID"), self.library.is_movie).overview
|
||||
elif method_name == "tmdb_description":
|
||||
self.summaries[method_name] = config.TMDb.get_list(util.regex_first_int(self.data[m], "TMDb List ID")).description
|
||||
self.summaries[method_name] = config.TMDb.get_list(util.regex_first_int(method_data, "TMDb List ID")).description
|
||||
elif method_name == "tmdb_biography":
|
||||
self.summaries[method_name] = config.TMDb.get_person(util.regex_first_int(self.data[m], "TMDb Person ID")).biography
|
||||
self.summaries[method_name] = config.TMDb.get_person(util.regex_first_int(method_data, "TMDb Person ID")).biography
|
||||
elif method_name == "tvdb_summary":
|
||||
self.summaries[method_name] = config.TVDb.get_movie_or_show(self.data[m], self.library.Plex.language, self.library.is_movie).summary
|
||||
self.summaries[method_name] = config.TVDb.get_movie_or_show(method_data, self.library.Plex.language, self.library.is_movie).summary
|
||||
elif method_name == "tvdb_description":
|
||||
self.summaries[method_name] = config.TVDb.get_list_description(self.data[m], self.library.Plex.language)
|
||||
self.summaries[method_name] = config.TVDb.get_list_description(method_data, self.library.Plex.language)
|
||||
elif method_name == "trakt_description":
|
||||
self.summaries[method_name] = config.Trakt.standard_list(config.Trakt.validate_trakt_list(util.get_list(self.data[m]))[0]).description
|
||||
self.summaries[method_name] = config.Trakt.standard_list(config.Trakt.validate_trakt_list(util.get_list(method_data))[0]).description
|
||||
elif method_name == "letterboxd_description":
|
||||
self.summaries[method_name] = config.Letterboxd.get_list_description(self.data[m], self.library.Plex.language)
|
||||
self.summaries[method_name] = config.Letterboxd.get_list_description(method_data, self.library.Plex.language)
|
||||
elif method_name == "collection_mode":
|
||||
if str(self.data[m]).lower() == "default":
|
||||
if str(method_data).lower() == "default":
|
||||
self.details[method_name] = "default"
|
||||
elif str(self.data[m]).lower() == "hide":
|
||||
elif str(method_data).lower() == "hide":
|
||||
self.details[method_name] = "hide"
|
||||
elif str(self.data[m]).lower() in ["hide_items", "hideitems"]:
|
||||
elif str(method_data).lower() in ["hide_items", "hideitems"]:
|
||||
self.details[method_name] = "hideItems"
|
||||
elif str(self.data[m]).lower() in ["show_items", "showitems"]:
|
||||
elif str(method_data).lower() in ["show_items", "showitems"]:
|
||||
self.details[method_name] = "showItems"
|
||||
else:
|
||||
raise Failed(f"Collection Error: {self.data[m]} collection_mode invalid\n\tdefault (Library default)\n\thide (Hide Collection)\n\thide_items (Hide Items in this Collection)\n\tshow_items (Show this Collection and its Items)")
|
||||
raise Failed(f"Collection Error: {method_data} collection_mode invalid\n\tdefault (Library default)\n\thide (Hide Collection)\n\thide_items (Hide Items in this Collection)\n\tshow_items (Show this Collection and its Items)")
|
||||
elif method_name == "collection_order":
|
||||
if str(self.data[m]).lower() == "release":
|
||||
if str(method_data).lower() == "release":
|
||||
self.details[method_name] = "release"
|
||||
elif str(self.data[m]).lower() == "alpha":
|
||||
elif str(method_data).lower() == "alpha":
|
||||
self.details[method_name] = "release"
|
||||
else:
|
||||
raise Failed(f"Collection Error: {self.data[m]} collection_order invalid\n\trelease (Order Collection by release dates)\n\talpha (Order Collection Alphabetically)")
|
||||
raise Failed(f"Collection Error: {method_data} collection_order invalid\n\trelease (Order Collection by release dates)\n\talpha (Order Collection Alphabetically)")
|
||||
elif method_name == "url_poster":
|
||||
self.posters[method_name] = self.data[m]
|
||||
self.posters[method_name] = method_data
|
||||
elif method_name == "tmdb_poster":
|
||||
self.posters[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_movie_show_or_collection(util.regex_first_int(self.data[m], 'TMDb ID'), self.library.is_movie).poster_path}"
|
||||
self.posters[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_movie_show_or_collection(util.regex_first_int(method_data, 'TMDb ID'), self.library.is_movie).poster_path}"
|
||||
elif method_name == "tmdb_profile":
|
||||
self.posters[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_person(util.regex_first_int(self.data[m], 'TMDb Person ID')).profile_path}"
|
||||
self.posters[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_person(util.regex_first_int(method_data, 'TMDb Person ID')).profile_path}"
|
||||
elif method_name == "tvdb_poster":
|
||||
self.posters[method_name] = f"{config.TVDb.get_movie_or_series(self.data[m], self.library.Plex.language, self.library.is_movie).poster_path}"
|
||||
self.posters[method_name] = f"{config.TVDb.get_movie_or_series(method_data, self.library.Plex.language, self.library.is_movie).poster_path}"
|
||||
elif method_name == "file_poster":
|
||||
if os.path.exists(self.data[m]):
|
||||
self.posters[method_name] = os.path.abspath(self.data[m])
|
||||
if os.path.exists(method_data):
|
||||
self.posters[method_name] = os.path.abspath(method_data)
|
||||
else:
|
||||
raise Failed(f"Collection Error: Poster Path Does Not Exist: {os.path.abspath(self.data[m])}")
|
||||
raise Failed(f"Collection Error: Poster Path Does Not Exist: {os.path.abspath(method_data)}")
|
||||
elif method_name == "url_background":
|
||||
self.backgrounds[method_name] = self.data[m]
|
||||
self.backgrounds[method_name] = method_data
|
||||
elif method_name == "tmdb_background":
|
||||
self.backgrounds[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_movie_show_or_collection(util.regex_first_int(self.data[m], 'TMDb ID'), self.library.is_movie).poster_path}"
|
||||
self.backgrounds[method_name] = f"{config.TMDb.image_url}{config.TMDb.get_movie_show_or_collection(util.regex_first_int(method_data, 'TMDb ID'), self.library.is_movie).poster_path}"
|
||||
elif method_name == "tvdb_background":
|
||||
self.posters[method_name] = f"{config.TVDb.get_movie_or_series(self.data[m], self.library.Plex.language, self.library.is_movie).background_path}"
|
||||
self.posters[method_name] = f"{config.TVDb.get_movie_or_series(method_data, self.library.Plex.language, self.library.is_movie).background_path}"
|
||||
elif method_name == "file_background":
|
||||
if os.path.exists(self.data[m]): self.backgrounds[method_name] = os.path.abspath(self.data[m])
|
||||
else: raise Failed(f"Collection Error: Background Path Does Not Exist: {os.path.abspath(self.data[m])}")
|
||||
if os.path.exists(method_data): self.backgrounds[method_name] = os.path.abspath(method_data)
|
||||
else: raise Failed(f"Collection Error: Background Path Does Not Exist: {os.path.abspath(method_data)}")
|
||||
elif method_name == "label_sync_mode":
|
||||
if self.data[m].lower() in ["append", "sync"]: self.details[method_name] = self.data[m].lower()
|
||||
if str(method_data).lower() in ["append", "sync"]: self.details[method_name] = method_data.lower()
|
||||
else: raise Failed("Collection Error: label_sync_mode attribute must be either 'append' or 'sync'")
|
||||
elif method_name == "sync_mode":
|
||||
if self.data[m].lower() in ["append", "sync"]: self.details[method_name] = self.data[m].lower()
|
||||
if str(method_data).lower() in ["append", "sync"]: self.details[method_name] = method_data.lower()
|
||||
else: raise Failed("Collection Error: sync_mode attribute must be either 'append' or 'sync'")
|
||||
elif method_name in ["arr_tag", "label"]:
|
||||
self.details[method_name] = util.get_list(self.data[m])
|
||||
self.details[method_name] = util.get_list(method_data)
|
||||
elif method_name in util.boolean_details:
|
||||
if isinstance(self.data[m], bool): self.details[method_name] = self.data[m]
|
||||
elif str(self.data[m]).lower() in ["t", "true"]: self.details[method_name] = True
|
||||
elif str(self.data[m]).lower() in ["f", "false"]: self.details[method_name] = False
|
||||
if isinstance(method_data, bool): self.details[method_name] = method_data
|
||||
elif str(method_data).lower() in ["t", "true"]: self.details[method_name] = True
|
||||
elif str(method_data).lower() in ["f", "false"]: self.details[method_name] = False
|
||||
else: raise Failed(f"Collection Error: {method_name} attribute must be either true or false")
|
||||
elif method_name in util.all_details:
|
||||
self.details[method_name] = self.data[m]
|
||||
self.details[method_name] = method_data
|
||||
elif method_name in ["year", "year.not"]:
|
||||
self.methods.append(("plex_search", [[(method_name, util.get_year_list(self.data[m], method_name))]]))
|
||||
elif method_name in ["decade", "decade.not"]:
|
||||
|
@ -325,33 +325,33 @@ class CollectionBuilder:
|
|||
elif method_name == "plex_all":
|
||||
self.methods.append((method_name, [""]))
|
||||
elif method_name == "plex_collection":
|
||||
self.methods.append((method_name, self.library.validate_collections(self.data[m] if isinstance(self.data[m], list) else [self.data[m]])))
|
||||
self.methods.append((method_name, self.library.validate_collections(method_data if isinstance(method_data, list) else [method_data])))
|
||||
elif method_name == "anidb_popular":
|
||||
list_count = util.regex_first_int(self.data[m], "List Size", default=40)
|
||||
list_count = util.regex_first_int(method_data, "List Size", default=40)
|
||||
if 1 <= list_count <= 30:
|
||||
self.methods.append((method_name, [list_count]))
|
||||
else:
|
||||
logger.warning("Collection Error: anidb_popular must be an integer between 1 and 30 defaulting to 30")
|
||||
self.methods.append((method_name, [30]))
|
||||
elif method_name == "mal_id":
|
||||
self.methods.append((method_name, util.get_int_list(self.data[m], "MyAnimeList ID")))
|
||||
self.methods.append((method_name, util.get_int_list(method_data, "MyAnimeList ID")))
|
||||
elif method_name in ["anidb_id", "anidb_relation"]:
|
||||
self.methods.append((method_name, config.AniDB.validate_anidb_list(util.get_int_list(self.data[m], "AniDB ID"), self.library.Plex.language)))
|
||||
self.methods.append((method_name, config.AniDB.validate_anidb_list(util.get_int_list(method_data, "AniDB ID"), self.library.Plex.language)))
|
||||
elif method_name in ["anilist_id", "anilist_relations", "anilist_studio"]:
|
||||
self.methods.append((method_name, config.AniList.validate_anilist_ids(util.get_int_list(self.data[m], "AniList ID"), studio=method_name == "anilist_studio")))
|
||||
self.methods.append((method_name, config.AniList.validate_anilist_ids(util.get_int_list(method_data, "AniList ID"), studio=method_name == "anilist_studio")))
|
||||
elif method_name == "trakt_list":
|
||||
self.methods.append((method_name, config.Trakt.validate_trakt_list(util.get_list(self.data[m]))))
|
||||
self.methods.append((method_name, config.Trakt.validate_trakt_list(util.get_list(method_data))))
|
||||
elif method_name == "trakt_list_details":
|
||||
valid_list = config.Trakt.validate_trakt_list(util.get_list(self.data[m]))
|
||||
valid_list = config.Trakt.validate_trakt_list(util.get_list(method_data))
|
||||
item = config.Trakt.standard_list(valid_list[0])
|
||||
if hasattr(item, "description") and item.description:
|
||||
self.summaries[method_name] = item.description
|
||||
self.methods.append((method_name[:-8], valid_list))
|
||||
elif method_name == "trakt_watchlist":
|
||||
self.methods.append((method_name, config.Trakt.validate_trakt_watchlist(util.get_list(self.data[m]), self.library.is_movie)))
|
||||
self.methods.append((method_name, config.Trakt.validate_trakt_watchlist(util.get_list(method_data), self.library.is_movie)))
|
||||
elif method_name == "imdb_list":
|
||||
new_list = []
|
||||
for imdb_list in util.get_list(self.data[m], split=False):
|
||||
for imdb_list in util.get_list(method_data, split=False):
|
||||
if isinstance(imdb_list, dict):
|
||||
dict_methods = {dm.lower(): dm for dm in imdb_list}
|
||||
if "url" in dict_methods and imdb_list[dict_methods["url"]]:
|
||||
|
@ -365,13 +365,13 @@ class CollectionBuilder:
|
|||
new_list.append({"url": imdb_url, "limit": list_count})
|
||||
self.methods.append((method_name, new_list))
|
||||
elif method_name == "letterboxd_list":
|
||||
self.methods.append((method_name, util.get_list(self.data[m], split=False)))
|
||||
self.methods.append((method_name, util.get_list(method_data, split=False)))
|
||||
elif method_name == "letterboxd_list_details":
|
||||
values = util.get_list(self.data[m], split=False)
|
||||
values = util.get_list(method_data, split=False)
|
||||
self.summaries[method_name] = config.Letterboxd.get_list_description(values[0], self.library.Plex.language)
|
||||
self.methods.append((method_name[:-8], values))
|
||||
elif method_name in util.dictionary_lists:
|
||||
if isinstance(self.data[m], dict):
|
||||
if isinstance(method_data, dict):
|
||||
def get_int(parent, method, data_in, methods_in, default_in, minimum=1, maximum=None):
|
||||
if method not in methods_in:
|
||||
logger.warning(f"Collection Warning: {parent} {methods_in[method]} attribute not found using {default_in} as default")
|
||||
|
@ -386,50 +386,50 @@ class CollectionBuilder:
|
|||
logger.warning(f"Collection Warning: {parent} {methods_in[method]} attribute {data_in[methods_in[method]]} invalid must an integer >= {minimum} using {default_in} as default")
|
||||
return default_in
|
||||
if method_name == "filters":
|
||||
for f in self.data[m]:
|
||||
if f.lower() in util.method_alias or (f.lower().endswith(".not") and f.lower()[:-4] in util.method_alias):
|
||||
filter_method = (util.method_alias[f.lower()[:-4]] + f.lower()[-4:]) if f.lower().endswith(".not") else util.method_alias[f.lower()]
|
||||
logger.warning(f"Collection Warning: {f} filter will run as {filter_method}")
|
||||
for filter_name, filter_data in method_data.items():
|
||||
if filter_name.lower() in util.method_alias or (filter_name.lower().endswith(".not") and filter_name.lower()[:-4] in util.method_alias):
|
||||
filter_method = (util.method_alias[filter_name.lower()[:-4]] + filter_name.lower()[-4:]) if filter_name.lower().endswith(".not") else util.method_alias[filter_name.lower()]
|
||||
logger.warning(f"Collection Warning: {filter_name} filter will run as {filter_method}")
|
||||
else:
|
||||
filter_method = f.lower()
|
||||
filter_method = filter_name.lower()
|
||||
if filter_method in util.movie_only_filters and self.library.is_show:
|
||||
raise Failed(f"Collection Error: {filter_method} filter only works for movie libraries")
|
||||
elif self.data[m][f] is None:
|
||||
elif filter_data is None:
|
||||
raise Failed(f"Collection Error: {filter_method} filter is blank")
|
||||
elif filter_method == "year":
|
||||
filter_data = util.get_year_list(self.data[m][f], f"{filter_method} filter")
|
||||
valid_data = util.get_year_list(filter_data, current_year, f"{filter_method} filter")
|
||||
elif filter_method in ["max_age", "duration.gte", "duration.lte", "tmdb_vote_count.gte", "tmdb_vote_count.lte"]:
|
||||
filter_data = util.check_number(self.data[m][f], f"{filter_method} filter", minimum=1)
|
||||
valid_data = util.check_number(filter_data, f"{filter_method} filter", minimum=1)
|
||||
elif filter_method in ["year.gte", "year.lte"]:
|
||||
filter_data = util.check_number(self.data[m][f], f"{filter_method} filter", minimum=1800, maximum=current_year)
|
||||
valid_data = util.check_year(filter_data, current_year, f"{filter_method} filter")
|
||||
elif filter_method in ["rating.gte", "rating.lte"]:
|
||||
filter_data = util.check_number(self.data[m][f], f"{filter_method} filter", number_type="float", minimum=0.1, maximum=10)
|
||||
valid_data = util.check_number(filter_data, f"{filter_method} filter", number_type="float", minimum=0.1, maximum=10)
|
||||
elif filter_method in ["originally_available.gte", "originally_available.lte"]:
|
||||
filter_data = util.check_date(self.data[m][f], f"{filter_method} filter")
|
||||
valid_data = util.check_date(filter_data, f"{filter_method} filter")
|
||||
elif filter_method == "original_language":
|
||||
filter_data = util.get_list(self.data[m][f], lower=True)
|
||||
valid_data = util.get_list(filter_data, lower=True)
|
||||
elif filter_method == "collection":
|
||||
filter_data = self.data[m][f] if isinstance(self.data[m][f], list) else [self.data[m][f]]
|
||||
valid_data = filter_data if isinstance(filter_data, list) else [filter_data]
|
||||
elif filter_method in util.all_filters:
|
||||
filter_data = util.get_list(self.data[m][f])
|
||||
valid_data = util.get_list(filter_data)
|
||||
else:
|
||||
raise Failed(f"Collection Error: {filter_method} filter not supported")
|
||||
self.filters.append((filter_method, filter_data))
|
||||
self.filters.append((filter_method, valid_data))
|
||||
elif method_name == "plex_collectionless":
|
||||
new_dictionary = {}
|
||||
dict_methods = {dm.lower(): dm for dm in self.data[m]}
|
||||
dict_methods = {dm.lower(): dm for dm in method_data}
|
||||
prefix_list = []
|
||||
if "exclude_prefix" in dict_methods and self.data[m][dict_methods["exclude_prefix"]]:
|
||||
if isinstance(self.data[m][dict_methods["exclude_prefix"]], list):
|
||||
prefix_list.extend(self.data[m][dict_methods["exclude_prefix"]])
|
||||
if "exclude_prefix" in dict_methods and method_data[dict_methods["exclude_prefix"]]:
|
||||
if isinstance(method_data[dict_methods["exclude_prefix"]], list):
|
||||
prefix_list.extend(method_data[dict_methods["exclude_prefix"]])
|
||||
else:
|
||||
prefix_list.append(str(self.data[m][dict_methods["exclude_prefix"]]))
|
||||
prefix_list.append(str(method_data[dict_methods["exclude_prefix"]]))
|
||||
exact_list = []
|
||||
if "exclude" in dict_methods and self.data[m][dict_methods["exclude"]]:
|
||||
if isinstance(self.data[m][dict_methods["exclude"]], list):
|
||||
exact_list.extend(self.data[m][dict_methods["exclude"]])
|
||||
if "exclude" in dict_methods and method_data[dict_methods["exclude"]]:
|
||||
if isinstance(method_data[dict_methods["exclude"]], list):
|
||||
exact_list.extend(method_data[dict_methods["exclude"]])
|
||||
else:
|
||||
exact_list.append(str(self.data[m][dict_methods["exclude"]]))
|
||||
exact_list.append(str(method_data[dict_methods["exclude"]]))
|
||||
if len(prefix_list) == 0 and len(exact_list) == 0:
|
||||
raise Failed("Collection Error: you must have at least one exclusion")
|
||||
new_dictionary["exclude_prefix"] = prefix_list
|
||||
|
@ -464,61 +464,61 @@ class CollectionBuilder:
|
|||
self.methods.append((method_name, [searches]))
|
||||
elif method_name == "tmdb_discover":
|
||||
new_dictionary = {"limit": 100}
|
||||
for a in self.data[m]:
|
||||
a_name = a.lower()
|
||||
if self.data[m][a]:
|
||||
if (self.library.is_movie and a_name in util.discover_movie) or (self.library.is_show and a_name in util.discover_tv):
|
||||
if a_name == "language":
|
||||
if re.compile("([a-z]{2})-([A-Z]{2})").match(str(self.data[m][a])):
|
||||
new_dictionary[a_name] = str(self.data[m][a])
|
||||
for discover_name, discover_data in method_data:
|
||||
discover_final = discover_name.lower()
|
||||
if discover_data:
|
||||
if (self.library.is_movie and discover_final in util.discover_movie) or (self.library.is_show and discover_final in util.discover_tv):
|
||||
if discover_final == "language":
|
||||
if re.compile("([a-z]{2})-([A-Z]{2})").match(str(discover_data)):
|
||||
new_dictionary[discover_final] = str(discover_data)
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: {self.data[m][a]} must match pattern ([a-z]{{2}})-([A-Z]{{2}}) e.g. en-US")
|
||||
elif a_name == "region":
|
||||
if re.compile("^[A-Z]{2}$").match(str(self.data[m][a])):
|
||||
new_dictionary[a_name] = str(self.data[m][a])
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: {discover_data} must match pattern ([a-z]{{2}})-([A-Z]{{2}}) e.g. en-US")
|
||||
elif discover_final == "region":
|
||||
if re.compile("^[A-Z]{2}$").match(str(discover_data)):
|
||||
new_dictionary[discover_final] = str(discover_data)
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: {self.data[m][a]} must match pattern ^[A-Z]{{2}}$ e.g. US")
|
||||
elif a_name == "sort_by":
|
||||
if (self.library.is_movie and self.data[m][a] in util.discover_movie_sort) or (self.library.is_show and self.data[m][a] in util.discover_tv_sort):
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: {discover_data} must match pattern ^[A-Z]{{2}}$ e.g. US")
|
||||
elif discover_final == "sort_by":
|
||||
if (self.library.is_movie and discover_data in util.discover_movie_sort) or (self.library.is_show and discover_data in util.discover_tv_sort):
|
||||
new_dictionary[discover_final] = discover_data
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: {self.data[m][a]} is invalid")
|
||||
elif a_name == "certification_country":
|
||||
if "certification" in self.data[m] or "certification.lte" in self.data[m] or "certification.gte" in self.data[m]:
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: {discover_data} is invalid")
|
||||
elif discover_final == "certification_country":
|
||||
if "certification" in method_data or "certification.lte" in method_data or "certification.gte" in method_data:
|
||||
new_dictionary[discover_final] = discover_data
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: must be used with either certification, certification.lte, or certification.gte")
|
||||
elif a_name in ["certification", "certification.lte", "certification.gte"]:
|
||||
if "certification_country" in self.data[m]:
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: must be used with either certification, certification.lte, or certification.gte")
|
||||
elif discover_final in ["certification", "certification.lte", "certification.gte"]:
|
||||
if "certification_country" in method_data:
|
||||
new_dictionary[discover_final] = discover_data
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: must be used with certification_country")
|
||||
elif a_name in ["include_adult", "include_null_first_air_dates", "screened_theatrically"]:
|
||||
if self.data[m][a] is True:
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
elif a_name in util.discover_dates:
|
||||
new_dictionary[a_name] = util.check_date(self.data[m][a], f"{m} attribute {a_name}", return_string=True)
|
||||
elif a_name in ["primary_release_year", "year", "first_air_date_year"]:
|
||||
new_dictionary[a_name] = util.check_number(self.data[m][a], f"{m} attribute {a_name}", minimum=1800, maximum=current_year + 1)
|
||||
elif a_name in ["vote_count.gte", "vote_count.lte", "vote_average.gte", "vote_average.lte", "with_runtime.gte", "with_runtime.lte"]:
|
||||
new_dictionary[a_name] = util.check_number(self.data[m][a], f"{m} attribute {a_name}", minimum=1)
|
||||
elif a_name in ["with_cast", "with_crew", "with_people", "with_companies", "with_networks", "with_genres", "without_genres", "with_keywords", "without_keywords", "with_original_language", "timezone"]:
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: must be used with certification_country")
|
||||
elif discover_final in ["include_adult", "include_null_first_air_dates", "screened_theatrically"]:
|
||||
if discover_data is True:
|
||||
new_dictionary[discover_final] = discover_data
|
||||
elif discover_final in util.discover_dates:
|
||||
new_dictionary[discover_final] = util.check_date(discover_data, f"{method_name} attribute {discover_final}", return_string=True)
|
||||
elif discover_final in ["primary_release_year", "year", "first_air_date_year"]:
|
||||
new_dictionary[discover_final] = util.check_number(discover_data, f"{method_name} attribute {discover_final}", minimum=1800, maximum=current_year + 1)
|
||||
elif discover_final in ["vote_count.gte", "vote_count.lte", "vote_average.gte", "vote_average.lte", "with_runtime.gte", "with_runtime.lte"]:
|
||||
new_dictionary[discover_final] = util.check_number(discover_data, f"{method_name} attribute {discover_final}", minimum=1)
|
||||
elif discover_final in ["with_cast", "with_crew", "with_people", "with_companies", "with_networks", "with_genres", "without_genres", "with_keywords", "without_keywords", "with_original_language", "timezone"]:
|
||||
new_dictionary[discover_final] = discover_data
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name} not supported")
|
||||
elif a_name == "limit":
|
||||
if isinstance(self.data[m][a], int) and self.data[m][a] > 0:
|
||||
new_dictionary[a_name] = self.data[m][a]
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final} not supported")
|
||||
elif discover_final == "limit":
|
||||
if isinstance(discover_data, int) and discover_data > 0:
|
||||
new_dictionary[discover_final] = discover_data
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name}: must be a valid number greater then 0")
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final}: must be a valid number greater then 0")
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute {a_name} not supported")
|
||||
raise Failed(f"Collection Error: {method_name} attribute {discover_final} not supported")
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} parameter {a_name} is blank")
|
||||
raise Failed(f"Collection Error: {method_name} parameter {discover_final} is blank")
|
||||
if len(new_dictionary) > 1:
|
||||
self.methods.append((method_name, [new_dictionary]))
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} had no valid fields")
|
||||
raise Failed(f"Collection Error: {method_name} had no valid fields")
|
||||
elif "tautulli" in method_name:
|
||||
new_dictionary = {}
|
||||
if method_name == "tautulli_popular":
|
||||
|
@ -527,22 +527,22 @@ class CollectionBuilder:
|
|||
new_dictionary["list_type"] = "watched"
|
||||
else:
|
||||
raise Failed(f"Collection Error: {method_name} attribute not supported")
|
||||
dict_methods = {dm.lower(): dm for dm in self.data[m]}
|
||||
new_dictionary["list_days"] = get_int(method_name, "list_days", self.data[m], dict_methods, 30)
|
||||
new_dictionary["list_size"] = get_int(method_name, "list_size", self.data[m], dict_methods, 10)
|
||||
new_dictionary["list_buffer"] = get_int(method_name, "list_buffer", self.data[m], dict_methods, 20)
|
||||
dict_methods = {dm.lower(): dm for dm in method_data}
|
||||
new_dictionary["list_days"] = get_int(method_name, "list_days", method_data, dict_methods, 30)
|
||||
new_dictionary["list_size"] = get_int(method_name, "list_size", method_data, dict_methods, 10)
|
||||
new_dictionary["list_buffer"] = get_int(method_name, "list_buffer", method_data, dict_methods, 20)
|
||||
self.methods.append((method_name, [new_dictionary]))
|
||||
elif method_name == "mal_season":
|
||||
new_dictionary = {"sort_by": "anime_num_list_users"}
|
||||
dict_methods = {dm.lower(): dm for dm in self.data[m]}
|
||||
dict_methods = {dm.lower(): dm for dm in method_data}
|
||||
if "sort_by" not in dict_methods:
|
||||
logger.warning("Collection Warning: mal_season sort_by attribute not found using members as default")
|
||||
elif not self.data[m][dict_methods["sort_by"]]:
|
||||
elif not method_data[dict_methods["sort_by"]]:
|
||||
logger.warning("Collection Warning: mal_season sort_by attribute is blank using members as default")
|
||||
elif self.data[m][dict_methods["sort_by"]] not in util.mal_season_sort:
|
||||
logger.warning(f"Collection Warning: mal_season sort_by attribute {self.data[m][dict_methods['sort_by']]} invalid must be either 'members' or 'score' using members as default")
|
||||
elif method_data[dict_methods["sort_by"]] not in util.mal_season_sort:
|
||||
logger.warning(f"Collection Warning: mal_season sort_by attribute {method_data[dict_methods['sort_by']]} invalid must be either 'members' or 'score' using members as default")
|
||||
else:
|
||||
new_dictionary["sort_by"] = util.mal_season_sort[self.data[m][dict_methods["sort_by"]]]
|
||||
new_dictionary["sort_by"] = util.mal_season_sort[method_data[dict_methods["sort_by"]]]
|
||||
|
||||
if current_time.month in [1, 2, 3]: new_dictionary["season"] = "winter"
|
||||
elif current_time.month in [4, 5, 6]: new_dictionary["season"] = "spring"
|
||||
|
@ -551,49 +551,49 @@ class CollectionBuilder:
|
|||
|
||||
if "season" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: mal_season season attribute not found using the current season: {new_dictionary['season']} as default")
|
||||
elif not self.data[m][dict_methods["season"]]:
|
||||
elif not method_data[dict_methods["season"]]:
|
||||
logger.warning(f"Collection Warning: mal_season season attribute is blank using the current season: {new_dictionary['season']} as default")
|
||||
elif self.data[m][dict_methods["season"]] not in util.pretty_seasons:
|
||||
logger.warning(f"Collection Warning: mal_season season attribute {self.data[m][dict_methods['season']]} invalid must be either 'winter', 'spring', 'summer' or 'fall' using the current season: {new_dictionary['season']} as default")
|
||||
elif method_data[dict_methods["season"]] not in util.pretty_seasons:
|
||||
logger.warning(f"Collection Warning: mal_season season attribute {method_data[dict_methods['season']]} invalid must be either 'winter', 'spring', 'summer' or 'fall' using the current season: {new_dictionary['season']} as default")
|
||||
else:
|
||||
new_dictionary["season"] = self.data[m][dict_methods["season"]]
|
||||
new_dictionary["season"] = method_data[dict_methods["season"]]
|
||||
|
||||
new_dictionary["year"] = get_int(method_name, "year", self.data[m], dict_methods, current_time.year, minimum=1917, maximum=current_time.year + 1)
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", self.data[m], dict_methods, 100, maximum=500)
|
||||
new_dictionary["year"] = get_int(method_name, "year", method_data, dict_methods, current_time.year, minimum=1917, maximum=current_time.year + 1)
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", method_data, dict_methods, 100, maximum=500)
|
||||
self.methods.append((method_name, [new_dictionary]))
|
||||
elif method_name == "mal_userlist":
|
||||
new_dictionary = {"status": "all", "sort_by": "list_score"}
|
||||
dict_methods = {dm.lower(): dm for dm in self.data[m]}
|
||||
dict_methods = {dm.lower(): dm for dm in method_data}
|
||||
if "username" not in dict_methods:
|
||||
raise Failed("Collection Error: mal_userlist username attribute is required")
|
||||
elif not self.data[m][dict_methods["username"]]:
|
||||
elif not method_data[dict_methods["username"]]:
|
||||
raise Failed("Collection Error: mal_userlist username attribute is blank")
|
||||
else:
|
||||
new_dictionary["username"] = self.data[m][dict_methods["username"]]
|
||||
new_dictionary["username"] = method_data[dict_methods["username"]]
|
||||
|
||||
if "status" not in dict_methods:
|
||||
logger.warning("Collection Warning: mal_season status attribute not found using all as default")
|
||||
elif not self.data[m][dict_methods["status"]]:
|
||||
elif not method_data[dict_methods["status"]]:
|
||||
logger.warning("Collection Warning: mal_season status attribute is blank using all as default")
|
||||
elif self.data[m][dict_methods["status"]] not in util.mal_userlist_status:
|
||||
logger.warning(f"Collection Warning: mal_season status attribute {self.data[m][dict_methods['status']]} invalid must be either 'all', 'watching', 'completed', 'on_hold', 'dropped' or 'plan_to_watch' using all as default")
|
||||
elif method_data[dict_methods["status"]] not in util.mal_userlist_status:
|
||||
logger.warning(f"Collection Warning: mal_season status attribute {method_data[dict_methods['status']]} invalid must be either 'all', 'watching', 'completed', 'on_hold', 'dropped' or 'plan_to_watch' using all as default")
|
||||
else:
|
||||
new_dictionary["status"] = util.mal_userlist_status[self.data[m][dict_methods["status"]]]
|
||||
new_dictionary["status"] = util.mal_userlist_status[method_data[dict_methods["status"]]]
|
||||
|
||||
if "sort_by" not in dict_methods:
|
||||
logger.warning("Collection Warning: mal_season sort_by attribute not found using score as default")
|
||||
elif not self.data[m][dict_methods["sort_by"]]:
|
||||
elif not method_data[dict_methods["sort_by"]]:
|
||||
logger.warning("Collection Warning: mal_season sort_by attribute is blank using score as default")
|
||||
elif self.data[m][dict_methods["sort_by"]] not in util.mal_userlist_sort:
|
||||
logger.warning(f"Collection Warning: mal_season sort_by attribute {self.data[m][dict_methods['sort_by']]} invalid must be either 'score', 'last_updated', 'title' or 'start_date' using score as default")
|
||||
elif method_data[dict_methods["sort_by"]] not in util.mal_userlist_sort:
|
||||
logger.warning(f"Collection Warning: mal_season sort_by attribute {method_data[dict_methods['sort_by']]} invalid must be either 'score', 'last_updated', 'title' or 'start_date' using score as default")
|
||||
else:
|
||||
new_dictionary["sort_by"] = util.mal_userlist_sort[self.data[m][dict_methods["sort_by"]]]
|
||||
new_dictionary["sort_by"] = util.mal_userlist_sort[method_data[dict_methods["sort_by"]]]
|
||||
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", self.data[m], dict_methods, 100, maximum=1000)
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", method_data, dict_methods, 100, maximum=1000)
|
||||
self.methods.append((method_name, [new_dictionary]))
|
||||
elif "anilist" in method_name:
|
||||
new_dictionary = {"sort_by": "score"}
|
||||
dict_methods = {dm.lower(): dm for dm in self.data[m]}
|
||||
dict_methods = {dm.lower(): dm for dm in method_data}
|
||||
if method_name == "anilist_season":
|
||||
if current_time.month in [12, 1, 2]: new_dictionary["season"] = "winter"
|
||||
elif current_time.month in [3, 4, 5]: new_dictionary["season"] = "spring"
|
||||
|
@ -602,51 +602,51 @@ class CollectionBuilder:
|
|||
|
||||
if "season" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: anilist_season season attribute not found using the current season: {new_dictionary['season']} as default")
|
||||
elif not self.data[m][dict_methods["season"]]:
|
||||
elif not method_data[dict_methods["season"]]:
|
||||
logger.warning(f"Collection Warning: anilist_season season attribute is blank using the current season: {new_dictionary['season']} as default")
|
||||
elif self.data[m][dict_methods["season"]] not in util.pretty_seasons:
|
||||
logger.warning(f"Collection Warning: anilist_season season attribute {self.data[m][dict_methods['season']]} invalid must be either 'winter', 'spring', 'summer' or 'fall' using the current season: {new_dictionary['season']} as default")
|
||||
elif method_data[dict_methods["season"]] not in util.pretty_seasons:
|
||||
logger.warning(f"Collection Warning: anilist_season season attribute {method_data[dict_methods['season']]} invalid must be either 'winter', 'spring', 'summer' or 'fall' using the current season: {new_dictionary['season']} as default")
|
||||
else:
|
||||
new_dictionary["season"] = self.data[m][dict_methods["season"]]
|
||||
new_dictionary["season"] = method_data[dict_methods["season"]]
|
||||
|
||||
new_dictionary["year"] = get_int(method_name, "year", self.data[m], dict_methods, current_time.year, minimum=1917, maximum=current_time.year + 1)
|
||||
new_dictionary["year"] = get_int(method_name, "year", method_data, dict_methods, current_time.year, minimum=1917, maximum=current_time.year + 1)
|
||||
elif method_name == "anilist_genre":
|
||||
if "genre" not in dict_methods:
|
||||
raise Failed(f"Collection Warning: anilist_genre genre attribute not found")
|
||||
elif not self.data[m][dict_methods["genre"]]:
|
||||
elif not method_data[dict_methods["genre"]]:
|
||||
raise Failed(f"Collection Warning: anilist_genre genre attribute is blank")
|
||||
else:
|
||||
new_dictionary["genre"] = self.config.AniList.validate_genre(self.data[m][dict_methods["genre"]])
|
||||
new_dictionary["genre"] = self.config.AniList.validate_genre(method_data[dict_methods["genre"]])
|
||||
elif method_name == "anilist_tag":
|
||||
if "tag" not in dict_methods:
|
||||
raise Failed(f"Collection Warning: anilist_tag tag attribute not found")
|
||||
elif not self.data[m][dict_methods["tag"]]:
|
||||
elif not method_data[dict_methods["tag"]]:
|
||||
raise Failed(f"Collection Warning: anilist_tag tag attribute is blank")
|
||||
else:
|
||||
new_dictionary["tag"] = self.config.AniList.validate_tag(self.data[m][dict_methods["tag"]])
|
||||
new_dictionary["tag"] = self.config.AniList.validate_tag(method_data[dict_methods["tag"]])
|
||||
|
||||
if "sort_by" not in dict_methods:
|
||||
logger.warning(f"Collection Warning: {method_name} sort_by attribute not found using score as default")
|
||||
elif not self.data[m][dict_methods["sort_by"]]:
|
||||
elif not method_data[dict_methods["sort_by"]]:
|
||||
logger.warning(f"Collection Warning: {method_name} sort_by attribute is blank using score as default")
|
||||
elif str(self.data[m][dict_methods["sort_by"]]).lower() not in ["score", "popular"]:
|
||||
logger.warning(f"Collection Warning: {method_name} sort_by attribute {self.data[m][dict_methods['sort_by']]} invalid must be either 'score' or 'popular' using score as default")
|
||||
elif str(method_data[dict_methods["sort_by"]]).lower() not in ["score", "popular"]:
|
||||
logger.warning(f"Collection Warning: {method_name} sort_by attribute {method_data[dict_methods['sort_by']]} invalid must be either 'score' or 'popular' using score as default")
|
||||
else:
|
||||
new_dictionary["sort_by"] = self.data[m][dict_methods["sort_by"]]
|
||||
new_dictionary["sort_by"] = method_data[dict_methods["sort_by"]]
|
||||
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", self.data[m], dict_methods, 0, maximum=500)
|
||||
new_dictionary["limit"] = get_int(method_name, "limit", method_data, dict_methods, 0, maximum=500)
|
||||
|
||||
self.methods.append((method_name, [new_dictionary]))
|
||||
else:
|
||||
raise Failed(f"Collection Error: {m} attribute is not a dictionary: {self.data[m]}")
|
||||
raise Failed(f"Collection Error: {method_name} attribute is not a dictionary: {method_data}")
|
||||
elif method_name in util.count_lists:
|
||||
list_count = util.regex_first_int(self.data[m], "List Size", default=10)
|
||||
list_count = util.regex_first_int(method_data, "List Size", default=10)
|
||||
if list_count < 1:
|
||||
logger.warning(f"Collection Warning: {method_name} must be an integer greater then 0 defaulting to 10")
|
||||
list_count = 10
|
||||
self.methods.append((method_name, [list_count]))
|
||||
elif "tvdb" in method_name:
|
||||
values = util.get_list(self.data[m])
|
||||
values = util.get_list(method_data)
|
||||
if method_name[-8:] == "_details":
|
||||
if method_name == "tvdb_movie_details":
|
||||
item = config.TVDb.get_movie(self.library.Plex.language, values[0])
|
||||
|
@ -670,7 +670,7 @@ class CollectionBuilder:
|
|||
else:
|
||||
self.methods.append((method_name, values))
|
||||
elif method_name in util.tmdb_lists:
|
||||
values = config.TMDb.validate_tmdb_list(util.get_int_list(self.data[m], f"TMDb {util.tmdb_type[method_name]} ID"), util.tmdb_type[method_name])
|
||||
values = config.TMDb.validate_tmdb_list(util.get_int_list(method_data, f"TMDb {util.tmdb_type[method_name]} ID"), util.tmdb_type[method_name])
|
||||
if method_name[-8:] == "_details":
|
||||
if method_name in ["tmdb_collection_details", "tmdb_movie_details", "tmdb_show_details"]:
|
||||
item = config.TMDb.get_movie_show_or_collection(values[0], self.library.is_movie)
|
||||
|
@ -694,13 +694,13 @@ class CollectionBuilder:
|
|||
else:
|
||||
self.methods.append((method_name, values))
|
||||
elif method_name in util.all_lists:
|
||||
self.methods.append((method_name, util.get_list(self.data[m])))
|
||||
self.methods.append((method_name, util.get_list(method_data)))
|
||||
elif method_name not in util.other_attributes:
|
||||
raise Failed(f"Collection Error: {method_name} attribute not supported")
|
||||
elif m in util.all_lists or m in util.method_alias or m in util.plex_searches:
|
||||
raise Failed(f"Collection Error: {m} attribute is blank")
|
||||
elif method_name in util.all_lists or method_name in util.method_alias or method_name in util.plex_searches:
|
||||
raise Failed(f"Collection Error: {method_name} attribute is blank")
|
||||
else:
|
||||
logger.warning(f"Collection Warning: {m} attribute is blank")
|
||||
logger.warning(f"Collection Warning: {method_name} attribute is blank")
|
||||
|
||||
self.sync = self.library.sync_mode == "sync"
|
||||
if "sync_mode" in methods:
|
||||
|
|
|
@ -267,47 +267,47 @@ class Config:
|
|||
self.libraries = []
|
||||
try: libs = check_for_attribute(self.data, "libraries", throw=True)
|
||||
except Failed as e: raise Failed(e)
|
||||
for lib in libs:
|
||||
for library_name, lib in libs.items():
|
||||
util.separator()
|
||||
params = {}
|
||||
if "library_name" in libs[lib] and libs[lib]["library_name"]:
|
||||
params["name"] = str(libs[lib]["library_name"])
|
||||
logger.info(f"Connecting to {params['name']} ({lib}) Library...")
|
||||
if "library_name" in lib and lib["library_name"]:
|
||||
params["name"] = str(lib["library_name"])
|
||||
logger.info(f"Connecting to {params['name']} ({library_name}) Library...")
|
||||
else:
|
||||
params["name"] = str(lib)
|
||||
params["name"] = str(library_name)
|
||||
logger.info(f"Connecting to {params['name']} Library...")
|
||||
|
||||
params["asset_directory"] = check_for_attribute(libs[lib], "asset_directory", parent="settings", var_type="list_path", default=self.general["asset_directory"], default_is_none=True, save=False)
|
||||
params["asset_directory"] = check_for_attribute(lib, "asset_directory", parent="settings", var_type="list_path", 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")
|
||||
|
||||
if "settings" in libs[lib] and libs[lib]["settings"] and "sync_mode" in libs[lib]["settings"]:
|
||||
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"], do_print=False, save=False)
|
||||
if "settings" in lib and lib["settings"] and "sync_mode" in lib["settings"]:
|
||||
params["sync_mode"] = check_for_attribute(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"], do_print=False, save=False)
|
||||
else:
|
||||
params["sync_mode"] = check_for_attribute(libs[lib], "sync_mode", 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"], do_print=False, save=False)
|
||||
params["sync_mode"] = check_for_attribute(lib, "sync_mode", 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"], do_print=False, save=False)
|
||||
|
||||
if "settings" in libs[lib] and libs[lib]["settings"] and "show_unmanaged" in libs[lib]["settings"]:
|
||||
params["show_unmanaged"] = check_for_attribute(libs[lib], "show_unmanaged", parent="settings", var_type="bool", default=self.general["show_unmanaged"], do_print=False, save=False)
|
||||
if "settings" in lib and lib["settings"] and "show_unmanaged" in lib["settings"]:
|
||||
params["show_unmanaged"] = check_for_attribute(lib, "show_unmanaged", parent="settings", var_type="bool", default=self.general["show_unmanaged"], do_print=False, save=False)
|
||||
else:
|
||||
params["show_unmanaged"] = check_for_attribute(libs[lib], "show_unmanaged", var_type="bool", default=self.general["show_unmanaged"], do_print=False, save=False)
|
||||
params["show_unmanaged"] = check_for_attribute(lib, "show_unmanaged", var_type="bool", default=self.general["show_unmanaged"], do_print=False, save=False)
|
||||
|
||||
if "settings" in libs[lib] and libs[lib]["settings"] and "show_filtered" in libs[lib]["settings"]:
|
||||
params["show_filtered"] = check_for_attribute(libs[lib], "show_filtered", parent="settings", var_type="bool", default=self.general["show_filtered"], do_print=False, save=False)
|
||||
if "settings" in lib and lib["settings"] and "show_filtered" in lib["settings"]:
|
||||
params["show_filtered"] = check_for_attribute(lib, "show_filtered", parent="settings", var_type="bool", default=self.general["show_filtered"], do_print=False, save=False)
|
||||
else:
|
||||
params["show_filtered"] = check_for_attribute(libs[lib], "show_filtered", var_type="bool", default=self.general["show_filtered"], do_print=False, save=False)
|
||||
params["show_filtered"] = check_for_attribute(lib, "show_filtered", var_type="bool", default=self.general["show_filtered"], do_print=False, save=False)
|
||||
|
||||
if "settings" in libs[lib] and libs[lib]["settings"] and "show_missing" in libs[lib]["settings"]:
|
||||
params["show_missing"] = check_for_attribute(libs[lib], "show_missing", parent="settings", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
|
||||
if "settings" in lib and lib["settings"] and "show_missing" in lib["settings"]:
|
||||
params["show_missing"] = check_for_attribute(lib, "show_missing", parent="settings", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
|
||||
else:
|
||||
params["show_missing"] = check_for_attribute(libs[lib], "show_missing", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
|
||||
params["show_missing"] = check_for_attribute(lib, "show_missing", var_type="bool", default=self.general["show_missing"], do_print=False, save=False)
|
||||
|
||||
if "settings" in libs[lib] and libs[lib]["settings"] and "save_missing" in libs[lib]["settings"]:
|
||||
params["save_missing"] = check_for_attribute(libs[lib], "save_missing", parent="settings", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
|
||||
if "settings" in lib and lib["settings"] and "save_missing" in lib["settings"]:
|
||||
params["save_missing"] = check_for_attribute(lib, "save_missing", parent="settings", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
|
||||
else:
|
||||
params["save_missing"] = check_for_attribute(libs[lib], "save_missing", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
|
||||
params["save_missing"] = check_for_attribute(lib, "save_missing", var_type="bool", default=self.general["save_missing"], do_print=False, save=False)
|
||||
|
||||
if "mass_genre_update" in libs[lib] and libs[lib]["mass_genre_update"]:
|
||||
params["mass_genre_update"] = check_for_attribute(libs[lib], "mass_genre_update", test_list=["tmdb", "omdb"], options=" tmdb (Use TMDb Metadata)\n omdb (Use IMDb Metadata through OMDb)", default_is_none=True, save=False)
|
||||
if "mass_genre_update" in lib and lib["mass_genre_update"]:
|
||||
params["mass_genre_update"] = check_for_attribute(lib, "mass_genre_update", test_list=["tmdb", "omdb"], options=" tmdb (Use TMDb Metadata)\n omdb (Use IMDb Metadata through OMDb)", default_is_none=True, save=False)
|
||||
else:
|
||||
params["mass_genre_update"] = None
|
||||
|
||||
|
@ -316,12 +316,12 @@ class Config:
|
|||
logger.error("Config Error: mass_genre_update cannot be omdb without a successful OMDb Connection")
|
||||
|
||||
try:
|
||||
params["metadata_path"] = check_for_attribute(libs[lib], "metadata_path", var_type="path", default=os.path.join(default_dir, f"{lib}.yml"), 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["metadata_path"] = check_for_attribute(lib, "metadata_path", var_type="path", default=os.path.join(default_dir, f"{library_name}.yml"), throw=True)
|
||||
params["library_type"] = check_for_attribute(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)
|
||||
params["plex"]["url"] = check_for_attribute(lib, "url", parent="plex", default=self.general["plex"]["url"], req_default=True, save=False)
|
||||
params["plex"]["token"] = check_for_attribute(lib, "token", parent="plex", default=self.general["plex"]["token"], req_default=True, save=False)
|
||||
params["plex"]["timeout"] = check_for_attribute(lib, "timeout", parent="plex", var_type="int", default=self.general["plex"]["timeout"], save=False)
|
||||
library = PlexAPI(params, self.TMDb, self.TVDb)
|
||||
logger.info(f"{params['name']} Library Connection Successful")
|
||||
except Failed as e:
|
||||
|
@ -329,47 +329,47 @@ class Config:
|
|||
logger.info(f"{params['name']} Library Connection Failed")
|
||||
continue
|
||||
|
||||
if self.general["radarr"]["url"] or "radarr" in libs[lib]:
|
||||
if self.general["radarr"]["url"] or "radarr" in lib:
|
||||
logger.info(f"Connecting to {params['name']} library's Radarr...")
|
||||
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="lower_list", default=self.general["radarr"]["tag"], default_is_none=True, save=False)
|
||||
radarr_params["url"] = check_for_attribute(lib, "url", parent="radarr", default=self.general["radarr"]["url"], req_default=True, save=False)
|
||||
radarr_params["token"] = check_for_attribute(lib, "token", parent="radarr", default=self.general["radarr"]["token"], req_default=True, save=False)
|
||||
radarr_params["version"] = check_for_attribute(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(lib, "quality_profile", parent="radarr", default=self.general["radarr"]["quality_profile"], req_default=True, save=False)
|
||||
radarr_params["root_folder_path"] = check_for_attribute(lib, "root_folder_path", parent="radarr", default=self.general["radarr"]["root_folder_path"], req_default=True, save=False)
|
||||
radarr_params["add"] = check_for_attribute(lib, "add", parent="radarr", var_type="bool", default=self.general["radarr"]["add"], save=False)
|
||||
radarr_params["search"] = check_for_attribute(lib, "search", parent="radarr", var_type="bool", default=self.general["radarr"]["search"], save=False)
|
||||
radarr_params["tag"] = check_for_attribute(lib, "search", parent="radarr", var_type="lower_list", default=self.general["radarr"]["tag"], default_is_none=True, save=False)
|
||||
library.Radarr = RadarrAPI(self.TMDb, radarr_params)
|
||||
except Failed as e:
|
||||
util.print_multiline(e)
|
||||
logger.info(f"{params['name']} library's Radarr Connection {'Failed' if library.Radarr is None else 'Successful'}")
|
||||
|
||||
if self.general["sonarr"]["url"] or "sonarr" in libs[lib]:
|
||||
if self.general["sonarr"]["url"] or "sonarr" in lib:
|
||||
logger.info(f"Connecting to {params['name']} library's Sonarr...")
|
||||
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["season_folder"] = check_for_attribute(libs[lib], "season_folder", parent="sonarr", var_type="bool", default=self.general["sonarr"]["season_folder"], save=False)
|
||||
sonarr_params["tag"] = check_for_attribute(libs[lib], "search", parent="sonarr", var_type="lower_list", default=self.general["sonarr"]["tag"], default_is_none=True, save=False)
|
||||
sonarr_params["url"] = check_for_attribute(lib, "url", parent="sonarr", default=self.general["sonarr"]["url"], req_default=True, save=False)
|
||||
sonarr_params["token"] = check_for_attribute(lib, "token", parent="sonarr", default=self.general["sonarr"]["token"], req_default=True, save=False)
|
||||
sonarr_params["version"] = check_for_attribute(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(lib, "quality_profile", parent="sonarr", default=self.general["sonarr"]["quality_profile"], req_default=True, save=False)
|
||||
sonarr_params["root_folder_path"] = check_for_attribute(lib, "root_folder_path", parent="sonarr", default=self.general["sonarr"]["root_folder_path"], req_default=True, save=False)
|
||||
sonarr_params["add"] = check_for_attribute(lib, "add", parent="sonarr", var_type="bool", default=self.general["sonarr"]["add"], save=False)
|
||||
sonarr_params["search"] = check_for_attribute(lib, "search", parent="sonarr", var_type="bool", default=self.general["sonarr"]["search"], save=False)
|
||||
sonarr_params["season_folder"] = check_for_attribute(lib, "season_folder", parent="sonarr", var_type="bool", default=self.general["sonarr"]["season_folder"], save=False)
|
||||
sonarr_params["tag"] = check_for_attribute(lib, "search", parent="sonarr", var_type="lower_list", default=self.general["sonarr"]["tag"], default_is_none=True, save=False)
|
||||
library.Sonarr = SonarrAPI(self.TVDb, sonarr_params, library.Plex.language)
|
||||
except Failed as e:
|
||||
util.print_multiline(e)
|
||||
logger.info(f"{params['name']} library's Sonarr Connection {'Failed' if library.Sonarr is None else 'Successful'}")
|
||||
|
||||
if self.general["tautulli"]["url"] or "tautulli" in libs[lib]:
|
||||
if self.general["tautulli"]["url"] or "tautulli" in lib:
|
||||
logger.info(f"Connecting to {params['name']} library's Tautulli...")
|
||||
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)
|
||||
tautulli_params["url"] = check_for_attribute(lib, "url", parent="tautulli", default=self.general["tautulli"]["url"], req_default=True, save=False)
|
||||
tautulli_params["apikey"] = check_for_attribute(lib, "apikey", parent="tautulli", default=self.general["tautulli"]["apikey"], req_default=True, save=False)
|
||||
library.Tautulli = TautulliAPI(tautulli_params)
|
||||
except Failed as e:
|
||||
util.print_multiline(e)
|
||||
|
@ -404,11 +404,11 @@ class Config:
|
|||
util.separator(f"{library.name} Library {'Test ' if test else ''}Collections")
|
||||
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:
|
||||
for c in collections:
|
||||
if test and ("test" not in collections[c] or collections[c]["test"] is not True):
|
||||
for mapping_name, collection_attrs in collections.items():
|
||||
if test and ("test" not in collection_attrs or collection_attrs["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 "template" in collection_attrs and collection_attrs["template"]:
|
||||
for data_template in util.get_list(collection_attrs["template"], split=False):
|
||||
if "name" in data_template \
|
||||
and data_template["name"] \
|
||||
and library.templates \
|
||||
|
@ -421,13 +421,14 @@ class Config:
|
|||
continue
|
||||
try:
|
||||
logger.info("")
|
||||
util.separator(f"{c} Collection")
|
||||
util.separator(f"{mapping_name} Collection")
|
||||
logger.info("")
|
||||
|
||||
rating_key_map = {}
|
||||
try:
|
||||
builder = CollectionBuilder(self, library, c, collections[c])
|
||||
builder = CollectionBuilder(self, library, mapping_name, collection_attrs)
|
||||
except Failed as ef:
|
||||
util.print_stacktrace()
|
||||
util.print_multiline(ef, error=True)
|
||||
continue
|
||||
except Exception as ee:
|
||||
|
@ -436,11 +437,11 @@ class Config:
|
|||
continue
|
||||
|
||||
try:
|
||||
collection_obj = library.get_collection(c)
|
||||
collection_obj = library.get_collection(mapping_name)
|
||||
collection_name = collection_obj.title
|
||||
except Failed:
|
||||
collection_obj = None
|
||||
collection_name = c
|
||||
collection_name = mapping_name
|
||||
|
||||
if len(builder.schedule) > 0:
|
||||
util.print_multiline(builder.schedule, info=True)
|
||||
|
|
136
modules/plex.py
136
modules/plex.py
|
@ -230,21 +230,21 @@ class PlexAPI:
|
|||
logger.info("")
|
||||
if not self.metadata:
|
||||
raise Failed("No metadata to edit")
|
||||
for m in self.metadata:
|
||||
methods = {mm.lower(): mm for mm in self.metadata[m]}
|
||||
if test and ("test" not in methods or self.metadata[m][methods["test"]] is not True):
|
||||
for mapping_name, meta in self.metadata.items():
|
||||
methods = {mm.lower(): mm for mm in meta}
|
||||
if test and ("test" not in methods or meta[methods["test"]] is not True):
|
||||
continue
|
||||
logger.info("")
|
||||
util.separator()
|
||||
logger.info("")
|
||||
year = None
|
||||
if "year" in methods:
|
||||
year = util.check_number(self.metadata[m][methods["year"]], "year", minimum=1800, maximum=datetime.now().year + 1)
|
||||
year = util.check_number(meta[methods["year"]], "year", minimum=1800, maximum=datetime.now().year + 1)
|
||||
|
||||
title = m
|
||||
title = mapping_name
|
||||
if "title" in methods:
|
||||
if self.metadata[m][methods["title"]] is None: logger.error("Metadata Error: title attribute is blank")
|
||||
else: title = self.metadata[m][methods["title"]]
|
||||
if meta[methods["title"]] is None: logger.error("Metadata Error: title attribute is blank")
|
||||
else: title = meta[methods["title"]]
|
||||
|
||||
item = self.search_item(title, year=year)
|
||||
|
||||
|
@ -252,15 +252,15 @@ class PlexAPI:
|
|||
item = self.search_item(f"{title} (SUB)", year=year)
|
||||
|
||||
if item is None and "alt_title" in methods:
|
||||
if self.metadata[m][methods["alt_title"]] is None:
|
||||
if meta[methods["alt_title"]] is None:
|
||||
logger.error("Metadata Error: alt_title attribute is blank")
|
||||
else:
|
||||
alt_title = self.metadata[m]["alt_title"]
|
||||
alt_title = meta["alt_title"]
|
||||
item = self.search_item(alt_title, year=year)
|
||||
|
||||
if item is None:
|
||||
logger.error(f"Plex Error: Item {m} not found")
|
||||
logger.error(f"Skipping {m}")
|
||||
logger.error(f"Plex Error: Item {mapping_name} not found")
|
||||
logger.error(f"Skipping {mapping_name}")
|
||||
continue
|
||||
|
||||
item_type = "Movie" if self.is_movie else "Show"
|
||||
|
@ -269,9 +269,9 @@ class PlexAPI:
|
|||
tmdb_item = None
|
||||
try:
|
||||
if "tmdb_id" in methods:
|
||||
if self.metadata[m][methods["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][methods["tmdb_id"]], "Show"))
|
||||
if meta[methods["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(meta[methods["tmdb_id"]], "Show"))
|
||||
except Failed as e:
|
||||
logger.error(e)
|
||||
|
||||
|
@ -294,33 +294,33 @@ class PlexAPI:
|
|||
logger.info(f"Detail: {name} updated to {value}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {name} attribute is blank")
|
||||
add_edit("title", item.title, self.metadata[m], methods, value=title)
|
||||
add_edit("sort_title", item.titleSort, self.metadata[m], methods, key="titleSort")
|
||||
add_edit("originally_available", str(item.originallyAvailableAt)[:-9], self.metadata[m], methods, key="originallyAvailableAt", value=originally_available)
|
||||
add_edit("rating", item.rating, self.metadata[m], methods, value=rating)
|
||||
add_edit("content_rating", item.contentRating, self.metadata[m], methods, key="contentRating")
|
||||
add_edit("original_title", item.originalTitle, self.metadata[m], methods, key="originalTitle", value=original_title)
|
||||
add_edit("studio", item.studio, self.metadata[m], methods, value=studio)
|
||||
add_edit("tagline", item.tagline, self.metadata[m], methods, value=tagline)
|
||||
add_edit("summary", item.summary, self.metadata[m], methods, value=summary)
|
||||
add_edit("title", item.title, meta, methods, value=title)
|
||||
add_edit("sort_title", item.titleSort, meta, methods, key="titleSort")
|
||||
add_edit("originally_available", str(item.originallyAvailableAt)[:-9], meta, methods, key="originallyAvailableAt", value=originally_available)
|
||||
add_edit("rating", item.rating, meta, methods, value=rating)
|
||||
add_edit("content_rating", item.contentRating, meta, methods, key="contentRating")
|
||||
add_edit("original_title", item.originalTitle, meta, methods, key="originalTitle", value=original_title)
|
||||
add_edit("studio", item.studio, meta, methods, value=studio)
|
||||
add_edit("tagline", item.tagline, meta, methods, value=tagline)
|
||||
add_edit("summary", item.summary, meta, methods, value=summary)
|
||||
if len(edits) > 0:
|
||||
logger.debug(f"Details Update: {edits}")
|
||||
try:
|
||||
item.edit(**edits)
|
||||
item.reload()
|
||||
logger.info(f"{item_type}: {m} Details Update Successful")
|
||||
logger.info(f"{item_type}: {mapping_name} Details Update Successful")
|
||||
except BadRequest:
|
||||
util.print_stacktrace()
|
||||
logger.error(f"{item_type}: {m} Details Update Failed")
|
||||
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
|
||||
else:
|
||||
logger.info(f"{item_type}: {m} Details Update Not Needed")
|
||||
logger.info(f"{item_type}: {mapping_name} Details Update Not Needed")
|
||||
|
||||
advance_edits = {}
|
||||
if self.is_show:
|
||||
|
||||
if "episode_sorting" in methods:
|
||||
if self.metadata[m][methods["episode_sorting"]]:
|
||||
method_data = str(self.metadata[m][methods["episode_sorting"]]).lower()
|
||||
if meta[methods["episode_sorting"]]:
|
||||
method_data = str(meta[methods["episode_sorting"]]).lower()
|
||||
if method_data in ["default", "oldest", "newest"]:
|
||||
if method_data == "default" and item.episodeSort != "-1":
|
||||
advance_edits["episodeSort"] = "-1"
|
||||
|
@ -331,13 +331,13 @@ class PlexAPI:
|
|||
if "episodeSort" in advance_edits:
|
||||
logger.info(f"Detail: episode_sorting updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['episode_sorting']]} episode_sorting attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['episode_sorting']]} episode_sorting attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: episode_sorting attribute is blank")
|
||||
|
||||
if "keep_episodes" in methods:
|
||||
if self.metadata[m][methods["keep_episodes"]]:
|
||||
method_data = str(self.metadata[m][methods["keep_episodes"]]).lower()
|
||||
if meta[methods["keep_episodes"]]:
|
||||
method_data = str(meta[methods["keep_episodes"]]).lower()
|
||||
if method_data in ["all", "5_latest", "3_latest", "latest", "past_3", "past_7", "past_30"]:
|
||||
if method_data == "all" and item.autoDeletionItemPolicyUnwatchedLibrary != 0:
|
||||
advance_edits["autoDeletionItemPolicyUnwatchedLibrary"] = 0
|
||||
|
@ -356,13 +356,13 @@ class PlexAPI:
|
|||
if "autoDeletionItemPolicyUnwatchedLibrary" in advance_edits:
|
||||
logger.info(f"Detail: keep_episodes updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['keep_episodes']]} keep_episodes attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['keep_episodes']]} keep_episodes attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: keep_episodes attribute is blank")
|
||||
|
||||
if "delete_episodes" in methods:
|
||||
if self.metadata[m][methods["delete_episodes"]]:
|
||||
method_data = str(self.metadata[m][methods["delete_episodes"]]).lower()
|
||||
if meta[methods["delete_episodes"]]:
|
||||
method_data = str(meta[methods["delete_episodes"]]).lower()
|
||||
if method_data in ["never", "day", "week", "refresh"]:
|
||||
if method_data == "never" and item.autoDeletionItemPolicyWatchedLibrary != 0:
|
||||
advance_edits["autoDeletionItemPolicyWatchedLibrary"] = 0
|
||||
|
@ -375,13 +375,13 @@ class PlexAPI:
|
|||
if "autoDeletionItemPolicyWatchedLibrary" in advance_edits:
|
||||
logger.info(f"Detail: delete_episodes updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['delete_episodes']]} delete_episodes attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['delete_episodes']]} delete_episodes attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: delete_episodes attribute is blank")
|
||||
|
||||
if "season_display" in methods:
|
||||
if self.metadata[m][methods["season_display"]]:
|
||||
method_data = str(self.metadata[m][methods["season_display"]]).lower()
|
||||
if meta[methods["season_display"]]:
|
||||
method_data = str(meta[methods["season_display"]]).lower()
|
||||
if method_data in ["default", "hide", "show"]:
|
||||
if method_data == "default" and item.flattenSeasons != -1:
|
||||
advance_edits["flattenSeasons"] = -1
|
||||
|
@ -392,13 +392,13 @@ class PlexAPI:
|
|||
if "flattenSeasons" in advance_edits:
|
||||
logger.info(f"Detail: season_display updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['season_display']]} season_display attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['season_display']]} season_display attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: season_display attribute is blank")
|
||||
|
||||
if "episode_ordering" in methods:
|
||||
if self.metadata[m][methods["episode_ordering"]]:
|
||||
method_data = str(self.metadata[m][methods["episode_ordering"]]).lower()
|
||||
if meta[methods["episode_ordering"]]:
|
||||
method_data = str(meta[methods["episode_ordering"]]).lower()
|
||||
if method_data in ["default", "tmdb_aired", "tvdb_aired", "tvdb_dvd", "tvdb_absolute"]:
|
||||
if method_data == "default" and item.showOrdering is not None:
|
||||
advance_edits["showOrdering"] = None
|
||||
|
@ -413,13 +413,13 @@ class PlexAPI:
|
|||
if "showOrdering" in advance_edits:
|
||||
logger.info(f"Detail: episode_ordering updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['episode_ordering']]} episode_ordering attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['episode_ordering']]} episode_ordering attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: episode_ordering attribute is blank")
|
||||
|
||||
if "metadata_language" in methods:
|
||||
if self.metadata[m][methods["metadata_language"]]:
|
||||
method_data = str(self.metadata[m][methods["metadata_language"]]).lower()
|
||||
if meta[methods["metadata_language"]]:
|
||||
method_data = str(meta[methods["metadata_language"]]).lower()
|
||||
lower_languages = {la.lower(): la for la in util.plex_languages}
|
||||
if method_data in lower_languages:
|
||||
if method_data == "default" and item.languageOverride is None:
|
||||
|
@ -429,13 +429,13 @@ class PlexAPI:
|
|||
if "languageOverride" in advance_edits:
|
||||
logger.info(f"Detail: metadata_language updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['metadata_language']]} metadata_language attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['metadata_language']]} metadata_language attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: metadata_language attribute is blank")
|
||||
|
||||
if "use_original_title" in methods:
|
||||
if self.metadata[m][methods["use_original_title"]]:
|
||||
method_data = str(self.metadata[m][methods["use_original_title"]]).lower()
|
||||
if meta[methods["use_original_title"]]:
|
||||
method_data = str(meta[methods["use_original_title"]]).lower()
|
||||
if method_data in ["default", "no", "yes"]:
|
||||
if method_data == "default" and item.useOriginalTitle != -1:
|
||||
advance_edits["useOriginalTitle"] = -1
|
||||
|
@ -446,7 +446,7 @@ class PlexAPI:
|
|||
if "useOriginalTitle" in advance_edits:
|
||||
logger.info(f"Detail: use_original_title updated to {method_data}")
|
||||
else:
|
||||
logger.error(f"Metadata Error: {self.metadata[m][methods['use_original_title']]} use_original_title attribute invalid")
|
||||
logger.error(f"Metadata Error: {meta[methods['use_original_title']]} use_original_title attribute invalid")
|
||||
else:
|
||||
logger.error(f"Metadata Error: use_original_title attribute is blank")
|
||||
|
||||
|
@ -457,29 +457,29 @@ class PlexAPI:
|
|||
logger.info(check_dict)
|
||||
item.editAdvanced(**advance_edits)
|
||||
item.reload()
|
||||
logger.info(f"{item_type}: {m} Advanced Details Update Successful")
|
||||
logger.info(f"{item_type}: {mapping_name} Advanced Details Update Successful")
|
||||
except BadRequest:
|
||||
util.print_stacktrace()
|
||||
logger.error(f"{item_type}: {m} Details Update Failed")
|
||||
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
|
||||
else:
|
||||
logger.info(f"{item_type}: {m} Details Update Not Needed")
|
||||
logger.info(f"{item_type}: {mapping_name} Details Update Not Needed")
|
||||
|
||||
genres = []
|
||||
if tmdb_item:
|
||||
genres.extend([genre.name for genre in tmdb_item.genres])
|
||||
if "genre" in methods:
|
||||
if self.metadata[m][methods["genre"]]:
|
||||
genres.extend(util.get_list(self.metadata[m][methods["genre"]]))
|
||||
if meta[methods["genre"]]:
|
||||
genres.extend(util.get_list(meta[methods["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 methods:
|
||||
if self.metadata[m][methods["genre_sync_mode"]] is None:
|
||||
if meta[methods["genre_sync_mode"]] is None:
|
||||
logger.error("Metadata Error: genre_sync_mode attribute is blank defaulting to append")
|
||||
elif str(self.metadata[m][methods["genre_sync_mode"]]).lower() not in ["append", "sync"]:
|
||||
elif str(meta[methods["genre_sync_mode"]]).lower() not in ["append", "sync"]:
|
||||
logger.error("Metadata Error: genre_sync_mode attribute must be either 'append' or 'sync' defaulting to append")
|
||||
elif str(self.metadata[m]["genre_sync_mode"]).lower() == "sync":
|
||||
elif str(meta["genre_sync_mode"]).lower() == "sync":
|
||||
for genre in (g for g in item_genres if g not in genres):
|
||||
item.removeGenre(genre)
|
||||
logger.info(f"Detail: Genre {genre} removed")
|
||||
|
@ -488,15 +488,15 @@ class PlexAPI:
|
|||
logger.info(f"Detail: Genre {genre} added")
|
||||
|
||||
if "label" in methods:
|
||||
if self.metadata[m][methods["label"]]:
|
||||
if meta[methods["label"]]:
|
||||
item_labels = [label.tag for label in item.labels]
|
||||
labels = util.get_list(self.metadata[m][methods["label"]])
|
||||
labels = util.get_list(meta[methods["label"]])
|
||||
if "label_sync_mode" in methods:
|
||||
if self.metadata[m][methods["label_sync_mode"]] is None:
|
||||
if meta[methods["label_sync_mode"]] is None:
|
||||
logger.error("Metadata Error: label_sync_mode attribute is blank defaulting to append")
|
||||
elif str(self.metadata[m][methods["label_sync_mode"]]).lower() not in ["append", "sync"]:
|
||||
elif str(meta[methods["label_sync_mode"]]).lower() not in ["append", "sync"]:
|
||||
logger.error("Metadata Error: label_sync_mode attribute must be either 'append' or 'sync' defaulting to append")
|
||||
elif str(self.metadata[m][methods["label_sync_mode"]]).lower() == "sync":
|
||||
elif str(meta[methods["label_sync_mode"]]).lower() == "sync":
|
||||
for label in (la for la in item_labels if la not in labels):
|
||||
item.removeLabel(label)
|
||||
logger.info(f"Detail: Label {label} removed")
|
||||
|
@ -507,15 +507,15 @@ class PlexAPI:
|
|||
logger.error("Metadata Error: label attribute is blank")
|
||||
|
||||
if "seasons" in methods and self.is_show:
|
||||
if self.metadata[m][methods["seasons"]]:
|
||||
for season_id in self.metadata[m][methods["seasons"]]:
|
||||
if meta[methods["seasons"]]:
|
||||
for season_id in meta[methods["seasons"]]:
|
||||
logger.info("")
|
||||
logger.info(f"Updating season {season_id} of {m}...")
|
||||
logger.info(f"Updating season {season_id} of {mapping_name}...")
|
||||
if isinstance(season_id, int):
|
||||
try: season = item.season(season_id)
|
||||
except NotFound: logger.error(f"Metadata Error: Season: {season_id} not found")
|
||||
else:
|
||||
season_dict = self.metadata[m][methods["seasons"]][season_id]
|
||||
season_dict = meta[methods["seasons"]][season_id]
|
||||
season_methods = {sm.lower(): sm for sm in season_dict}
|
||||
|
||||
if "title" in season_methods and season_dict[season_methods["title"]]:
|
||||
|
@ -552,19 +552,19 @@ class PlexAPI:
|
|||
logger.error("Metadata Error: seasons attribute is blank")
|
||||
|
||||
if "episodes" in methods and self.is_show:
|
||||
if self.metadata[m][methods["episodes"]]:
|
||||
for episode_str in self.metadata[m][methods["episodes"]]:
|
||||
if meta[methods["episodes"]]:
|
||||
for episode_str in meta[methods["episodes"]]:
|
||||
logger.info("")
|
||||
match = re.search("[Ss]\\d+[Ee]\\d+", episode_str)
|
||||
if match:
|
||||
output = match.group(0)[1:].split("E" if "E" in match.group(0) else "e")
|
||||
episode_id = int(output[0])
|
||||
season_id = int(output[1])
|
||||
logger.info(f"Updating episode S{episode_id}E{season_id} of {m}...")
|
||||
logger.info(f"Updating episode S{episode_id}E{season_id} of {mapping_name}...")
|
||||
try: episode = item.episode(season=season_id, episode=episode_id)
|
||||
except NotFound: logger.error(f"Metadata Error: episode {episode_id} of season {season_id} not found")
|
||||
else:
|
||||
episode_dict = self.metadata[m][methods["episodes"]][episode_str]
|
||||
episode_dict = meta[methods["episodes"]][episode_str]
|
||||
episode_methods = {em.lower(): em for em in episode_dict}
|
||||
|
||||
if "title" in episode_methods and episode_dict[episode_methods["title"]]:
|
||||
|
|
Loading…
Reference in a new issue