Skip to content

Commit

Permalink
Merge pull request #149 from meisnate12/develop
Browse files Browse the repository at this point in the history
v1.6.4
  • Loading branch information
meisnate12 authored Mar 27, 2021
2 parents 8e4526d + 0e7b6c5 commit 4c8ae0e
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 47 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Plex Meta Manager
#### Version 1.6.2
#### Version 1.6.4

The original concept for Plex Meta Manager is [Plex Auto Collections](https://github.com/mza921/Plex-Auto-Collections), but this is rewritten from the ground up to be able to include a scheduler, metadata edits, multiple libraries, and logging. Plex Meta Manager is a Python 3 script that can be continuously run using YAML configuration files to update on a schedule the metadata of the movies, shows, and collections in your libraries as well as automatically build collections based on various methods all detailed in the wiki. Some collection examples that the script can automatically build and update daily include Plex Based Searches like actor, genre, or studio collections or Collections based on TMDb, IMDb, Trakt, TVDb, AniDB, or MyAnimeList lists and various other services.

Expand Down
24 changes: 12 additions & 12 deletions modules/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def replace_txt(txt):
elif method_name == "tvdb_description":
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(method_data))[0]).description
self.summaries[method_name] = config.Trakt.standard_list(config.Trakt.validate_trakt(util.get_list(method_data))[0]).description
elif method_name == "letterboxd_description":
self.summaries[method_name] = config.Letterboxd.get_list_description(method_data, self.library.Plex.language)
elif method_name == "collection_mode":
Expand All @@ -266,7 +266,7 @@ def replace_txt(txt):
if str(method_data).lower() == "release":
self.details[method_name] = "release"
elif str(method_data).lower() == "alpha":
self.details[method_name] = "release"
self.details[method_name] = "alpha"
else:
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":
Expand Down Expand Up @@ -309,11 +309,11 @@ def replace_txt(txt):
elif method_name in ["title", "title.and", "title.not", "title.begins", "title.ends"]:
self.methods.append(("plex_search", [{method_name: util.get_list(method_data, split=False)}]))
elif method_name in ["decade", "year.greater", "year.less"]:
self.methods.append(("plex_search", [{method_name: util.check_year(method_data, current_year, method_name)}]))
self.methods.append(("plex_search", [{method_name: [util.check_year(method_data, current_year, method_name)]}]))
elif method_name in ["added.before", "added.after", "originally_available.before", "originally_available.after"]:
self.methods.append(("plex_search", [{method_name: util.check_date(method_data, method_name, return_string=True, plex_date=True)}]))
self.methods.append(("plex_search", [{method_name: [util.check_date(method_data, method_name, return_string=True, plex_date=True)]}]))
elif method_name in ["duration.greater", "duration.less", "rating.greater", "rating.less"]:
self.methods.append(("plex_search", [{method_name: util.check_number(method_data, method_name, minimum=0)}]))
self.methods.append(("plex_search", [{method_name: [util.check_number(method_data, method_name, minimum=0)]}]))
elif method_name in ["year", "year.not"]:
self.methods.append(("plex_search", [{method_name: util.get_year_list(method_data, current_year, method_name)}]))
elif method_name in util.tmdb_searches:
Expand Down Expand Up @@ -355,15 +355,15 @@ def replace_txt(txt):
elif method_name in ["anilist_id", "anilist_relations", "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(method_data))))
self.methods.append((method_name, config.Trakt.validate_trakt(util.get_list(method_data))))
elif method_name == "trakt_list_details":
valid_list = config.Trakt.validate_trakt_list(util.get_list(method_data))
valid_list = config.Trakt.validate_trakt(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(method_data), self.library.is_movie)))
elif method_name in ["trakt_watchlist", "trakt_collection"]:
self.methods.append((method_name, config.Trakt.validate_trakt(method_name[6:], util.get_list(method_data), self.library.is_movie)))
elif method_name == "imdb_list":
new_list = []
for imdb_list in util.get_list(method_data, split=False):
Expand Down Expand Up @@ -492,11 +492,11 @@ def get_int(parent, method, data_in, methods_in, default_in, minimum=1, maximum=
searches[search_final] = self.library.validate_search_list(final_values, search)
elif (search == "decade" and modifier in [""]) \
or (search == "year" and modifier in [".greater", ".less"]):
searches[search_final] = util.check_year(search_data, current_year, search_final)
searches[search_final] = [util.check_year(search_data, current_year, search_final)]
elif search in ["added", "originally_available"] and modifier in [".before", ".after"]:
searches[search_final] = util.check_date(search_data, search_final, return_string=True, plex_date=True)
searches[search_final] = [util.check_date(search_data, search_final, return_string=True, plex_date=True)]
elif search in ["duration", "rating"] and modifier in [".greater", ".less"]:
searches[search_final] = util.check_number(search_data, search_final, minimum=0)
searches[search_final] = [util.check_number(search_data, search_final, minimum=0)]
elif search == "year" and modifier in ["", ".not"]:
searches[search_final] = util.get_year_list(search_data, current_year, search_final)
elif (search in ["title", "studio"] and modifier not in ["", ".and", ".not", ".begins", ".ends"]) \
Expand Down
10 changes: 5 additions & 5 deletions modules/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def check_for_attribute(data, attribute, parent=None, test_list=None, options=""
elif attribute not in loaded_config[parent]: loaded_config[parent][attribute] = default
else: endline = ""
yaml.round_trip_dump(loaded_config, open(self.config_path, "w"), indent=ind_in, block_seq_indent=bsi_in)
elif not data[attribute] and data[attribute] is not False:
elif data[attribute] is None:
if default_is_none is True: return None
else: message = f"{text} is blank"
elif var_type == "bool":
Expand Down Expand Up @@ -325,7 +325,7 @@ def check_for_attribute(data, attribute, parent=None, test_list=None, options=""
library = PlexAPI(params, self.TMDb, self.TVDb)
logger.info(f"{params['name']} Library Connection Successful")
except Failed as e:
logger.error(e)
util.print_multiline(e, error=True)
logger.info(f"{params['name']} Library Connection Failed")
continue

Expand All @@ -343,7 +343,7 @@ def check_for_attribute(data, attribute, parent=None, test_list=None, options=""
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)
util.print_multiline(e, error=True)
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 lib:
Expand All @@ -361,7 +361,7 @@ def check_for_attribute(data, attribute, parent=None, test_list=None, options=""
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)
util.print_multiline(e, error=True)
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 lib:
Expand All @@ -372,7 +372,7 @@ def check_for_attribute(data, attribute, parent=None, test_list=None, options=""
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)
util.print_multiline(e, error=True)
logger.info(f"{params['name']} library's Tautulli Connection {'Failed' if library.Tautulli is None else 'Successful'}")

self.libraries.append(library)
Expand Down
28 changes: 19 additions & 9 deletions modules/plex.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ def update_metadata(self, TMDb, test):
tagline = tmdb_item.tagline if tmdb_item and len(tmdb_item.tagline) > 0 else None
summary = tmdb_item.overview if tmdb_item else None

details_updated = False
advance_details_updated = False
genre_updated = False
label_updated = False
season_updated = False
episode_updated = False

edits = {}
def add_edit(name, current, group, alias, key=None, value=None):
if value or name in alias:
Expand All @@ -329,15 +336,14 @@ def add_edit(name, current, group, alias, key=None, value=None):
add_edit("summary", item.summary, meta, methods, value=summary)
if len(edits) > 0:
logger.debug(f"Details Update: {edits}")
details_updated = True
try:
item.edit(**edits)
item.reload()
logger.info(f"{item_type}: {mapping_name} Details Update Successful")
except BadRequest:
util.print_stacktrace()
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
else:
logger.info(f"{item_type}: {mapping_name} Details Update Not Needed")

advance_edits = {}
if self.is_show:
Expand Down Expand Up @@ -476,6 +482,7 @@ def add_edit(name, current, group, alias, key=None, value=None):

if len(advance_edits) > 0:
logger.debug(f"Details Update: {advance_edits}")
advance_details_updated = True
try:
check_dict = {pref.id: list(pref.enumValues.keys()) for pref in item.preferences()}
logger.info(check_dict)
Expand All @@ -484,9 +491,7 @@ def add_edit(name, current, group, alias, key=None, value=None):
logger.info(f"{item_type}: {mapping_name} Advanced Details Update Successful")
except BadRequest:
util.print_stacktrace()
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
else:
logger.info(f"{item_type}: {mapping_name} Details Update Not Needed")
logger.error(f"{item_type}: {mapping_name} Advanced Details Update Failed")

genres = []
if tmdb_item:
Expand All @@ -505,9 +510,11 @@ def add_edit(name, current, group, alias, key=None, value=None):
logger.error("Metadata Error: genre_sync_mode attribute must be either 'append' or 'sync' defaulting to append")
elif str(meta["genre_sync_mode"]).lower() == "sync":
for genre in (g for g in item_genres if g not in genres):
genre_updated = True
item.removeGenre(genre)
logger.info(f"Detail: Genre {genre} removed")
for genre in (g for g in genres if g not in item_genres):
genre_updated = True
item.addGenre(genre)
logger.info(f"Detail: Genre {genre} added")

Expand All @@ -522,9 +529,11 @@ def add_edit(name, current, group, alias, key=None, value=None):
logger.error("Metadata Error: label_sync_mode attribute must be either 'append' or 'sync' defaulting to append")
elif str(meta[methods["label_sync_mode"]]).lower() == "sync":
for label in (la for la in item_labels if la not in labels):
label_updated = True
item.removeLabel(label)
logger.info(f"Detail: Label {label} removed")
for label in (la for la in labels if la not in item_labels):
label_updated = True
item.addLabel(label)
logger.info(f"Detail: Label {label} added")
else:
Expand Down Expand Up @@ -561,15 +570,14 @@ def add_edit(name, current, group, alias, key=None, value=None):
add_edit("summary", season.summary, season_methods, season_dict)
if len(edits) > 0:
logger.debug(f"Season: {season_id} Details Update: {edits}")
season_updated = True
try:
season.edit(**edits)
season.reload()
logger.info(f"Season: {season_id} Details Update Successful")
except BadRequest:
util.print_stacktrace()
logger.error(f"Season: {season_id} Details Update Failed")
else:
logger.info(f"Season: {season_id} Details Update Not Needed")
else:
logger.error(f"Metadata Error: Season: {season_id} invalid, it must be an integer")
else:
Expand Down Expand Up @@ -612,6 +620,7 @@ def add_edit(name, current, group, alias, key=None, value=None):
add_edit("summary", episode.summary, episode_dict, episode_methods)
if len(edits) > 0:
logger.debug(f"Season: {season_id} Episode: {episode_id} Details Update: {edits}")
episode_updated = True
try:
episode.edit(**edits)
episode.reload()
Expand All @@ -620,9 +629,10 @@ def add_edit(name, current, group, alias, key=None, value=None):
except BadRequest:
util.print_stacktrace()
logger.error(f"Season: {season_id} Episode: {episode_id} Details Update Failed")
else:
logger.info(f"Season: {season_id} Episode: {episode_id} Details Update Not Needed")
else:
logger.error(f"Metadata Error: episode {episode_str} invalid must have S##E## format")
else:
logger.error("Metadata Error: episodes attribute is blank")

if not details_updated and not advance_details_updated and not genre_updated and not label_updated and not season_updated and not episode_updated:
logger.info(f"{item_type}: {mapping_name} Details Update Not Needed")
Loading

0 comments on commit 4c8ae0e

Please sign in to comment.