mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-22 20:43:07 +00:00
#193 be able to edit items inside a collection
This commit is contained in:
parent
d90419d2ed
commit
83822e53d0
3 changed files with 85 additions and 19 deletions
|
@ -8,6 +8,8 @@ from plexapi.exceptions import BadRequest, NotFound
|
||||||
logger = logging.getLogger("Plex Meta Manager")
|
logger = logging.getLogger("Plex Meta Manager")
|
||||||
|
|
||||||
image_file_details = ["file_poster", "file_background", "asset_directory"]
|
image_file_details = ["file_poster", "file_background", "asset_directory"]
|
||||||
|
advance_new_agent = ["item_metadata_language", "item_use_original_title"]
|
||||||
|
advance_show = ["item_episode_sorting", "item_keep_episodes", "item_delete_episodes", "item_season_display", "item_episode_sorting"]
|
||||||
method_alias = {
|
method_alias = {
|
||||||
"actors": "actor", "role": "actor", "roles": "actor",
|
"actors": "actor", "role": "actor", "roles": "actor",
|
||||||
"content_ratings": "content_rating", "contentRating": "content_rating", "contentRatings": "content_rating",
|
"content_ratings": "content_rating", "contentRating": "content_rating", "contentRatings": "content_rating",
|
||||||
|
@ -155,6 +157,7 @@ class CollectionBuilder:
|
||||||
"show_missing": library.show_missing,
|
"show_missing": library.show_missing,
|
||||||
"save_missing": library.save_missing
|
"save_missing": library.save_missing
|
||||||
}
|
}
|
||||||
|
self.item_details = {}
|
||||||
self.radarr_options = {}
|
self.radarr_options = {}
|
||||||
self.sonarr_options = {}
|
self.sonarr_options = {}
|
||||||
self.missing_movies = []
|
self.missing_movies = []
|
||||||
|
@ -454,6 +457,20 @@ class CollectionBuilder:
|
||||||
self.details["label.sync"] = util.get_list(method_data)
|
self.details["label.sync"] = util.get_list(method_data)
|
||||||
else:
|
else:
|
||||||
self.details[method_name] = util.get_list(method_data)
|
self.details[method_name] = util.get_list(method_data)
|
||||||
|
elif method_name in ["item_label", "item_label.sync"]:
|
||||||
|
if "item_label" in self.data and "item_label.sync" in self.data:
|
||||||
|
raise Failed(f"Collection Error: Cannot use item_label and item_label.sync together")
|
||||||
|
self.item_details[method_name] = util.get_list(method_data)
|
||||||
|
elif method_name in plex.item_advance_keys:
|
||||||
|
key, options = plex.item_advance_keys[method_name]
|
||||||
|
if method_name in advance_new_agent and self.library.agent not in plex.new_plex_agents:
|
||||||
|
logger.error(f"Metadata Error: {method_name} attribute only works for with the New Plex Movie Agent and New Plex TV Agent")
|
||||||
|
elif method_name in advance_show and not self.library.is_show:
|
||||||
|
logger.error(f"Metadata Error: {method_name} attribute only works for show libraries")
|
||||||
|
elif str(method_data).lower() not in options:
|
||||||
|
logger.error(f"Metadata Error: {method_data} {method_name} attribute invalid")
|
||||||
|
else:
|
||||||
|
self.item_details[method_name] = str(method_data).lower()
|
||||||
elif method_name in boolean_details:
|
elif method_name in boolean_details:
|
||||||
self.details[method_name] = util.get_bool(method_name, method_data)
|
self.details[method_name] = util.get_bool(method_name, method_data)
|
||||||
elif method_name in all_details:
|
elif method_name in all_details:
|
||||||
|
@ -1162,6 +1179,36 @@ class CollectionBuilder:
|
||||||
collection.addLabel(label)
|
collection.addLabel(label)
|
||||||
logger.info(f"Detail: Label {label} added")
|
logger.info(f"Detail: Label {label} added")
|
||||||
|
|
||||||
|
if len(self.item_details) > 0:
|
||||||
|
labels = None
|
||||||
|
if "item_label" in self.item_details or "item_label.sync" in self.item_details:
|
||||||
|
labels = util.get_list(self.item_details["item_label" if "item_label" in self.item_details else "item_label.sync"])
|
||||||
|
for item in collection.items():
|
||||||
|
if labels is not None:
|
||||||
|
item_labels = [label.tag for label in item.labels]
|
||||||
|
if "item_label.sync" in self.item_details:
|
||||||
|
for label in (la for la in item_labels if la not in labels):
|
||||||
|
item.removeLabel(label)
|
||||||
|
logger.info(f"Detail: Label {label} removed from {item.title}")
|
||||||
|
for label in (la for la in labels if la not in item_labels):
|
||||||
|
item.addLabel(label)
|
||||||
|
logger.info(f"Detail: Label {label} added to {item.title}")
|
||||||
|
advance_edits = {}
|
||||||
|
for method_name, method_data in self.item_details.items():
|
||||||
|
if method_name in plex.item_advance_keys:
|
||||||
|
key, options = plex.item_advance_keys[method_name]
|
||||||
|
if getattr(item, key) != options[method_data]:
|
||||||
|
advance_edits[key] = options[method_data]
|
||||||
|
if len(advance_edits) > 0:
|
||||||
|
logger.debug(f"Details Update: {advance_edits}")
|
||||||
|
try:
|
||||||
|
item.editAdvanced(**advance_edits)
|
||||||
|
item.reload()
|
||||||
|
logger.info(f"{'Movie' if self.library.is_movie else 'Show'}: {item.title} Advanced Details Update Successful")
|
||||||
|
except BadRequest:
|
||||||
|
util.print_stacktrace()
|
||||||
|
logger.error(f"{'Movie' if self.library.is_movie else 'Show'}: {item.title} Advanced Details Update Failed")
|
||||||
|
|
||||||
if len(edits) > 0:
|
if len(edits) > 0:
|
||||||
logger.debug(edits)
|
logger.debug(edits)
|
||||||
collection.edit(**edits)
|
collection.edit(**edits)
|
||||||
|
|
|
@ -35,6 +35,25 @@ plex_languages = ["default", "ar-SA", "ca-ES", "cs-CZ", "da-DK", "de-DE", "el-GR
|
||||||
metadata_language_options = {lang.lower(): lang for lang in plex_languages}
|
metadata_language_options = {lang.lower(): lang for lang in plex_languages}
|
||||||
metadata_language_options["default"] = None
|
metadata_language_options["default"] = None
|
||||||
use_original_title_options = {"default": -1, "no": 0, "yes": 1}
|
use_original_title_options = {"default": -1, "no": 0, "yes": 1}
|
||||||
|
advance_keys = {
|
||||||
|
"episode_sorting": ("episodeSort", episode_sorting_options),
|
||||||
|
"keep_episodes": ("autoDeletionItemPolicyUnwatchedLibrary", keep_episodes_options),
|
||||||
|
"delete_episodes": ("autoDeletionItemPolicyWatchedLibrary", delete_episodes_options),
|
||||||
|
"season_display": ("flattenSeasons", season_display_options),
|
||||||
|
"episode_ordering": ("showOrdering", episode_ordering_options),
|
||||||
|
"metadata_language": ("languageOverride", metadata_language_options),
|
||||||
|
"use_original_title": ("useOriginalTitle", use_original_title_options)
|
||||||
|
}
|
||||||
|
item_advance_keys = {
|
||||||
|
"item_episode_sorting": ("episodeSort", episode_sorting_options),
|
||||||
|
"item_keep_episodes": ("autoDeletionItemPolicyUnwatchedLibrary", keep_episodes_options),
|
||||||
|
"item_delete_episodes": ("autoDeletionItemPolicyWatchedLibrary", delete_episodes_options),
|
||||||
|
"item_season_display": ("flattenSeasons", season_display_options),
|
||||||
|
"item_episode_ordering": ("showOrdering", episode_ordering_options),
|
||||||
|
"item_metadata_language": ("languageOverride", metadata_language_options),
|
||||||
|
"item_use_original_title": ("useOriginalTitle", use_original_title_options)
|
||||||
|
}
|
||||||
|
new_plex_agents = ["tv.plex.agents.movie", "tv.plex.agents.series"]
|
||||||
filter_alias = {
|
filter_alias = {
|
||||||
"actor": "actors",
|
"actor": "actors",
|
||||||
"audience_rating": "audienceRating",
|
"audience_rating": "audienceRating",
|
||||||
|
@ -125,6 +144,7 @@ class PlexAPI:
|
||||||
if not self.Plex:
|
if not self.Plex:
|
||||||
raise Failed(f"Plex Error: Plex Library {params['name']} not found")
|
raise Failed(f"Plex Error: Plex Library {params['name']} not found")
|
||||||
|
|
||||||
|
self.agent = self.Plex.agent
|
||||||
self.is_movie = self.Plex.type == "movie"
|
self.is_movie = self.Plex.type == "movie"
|
||||||
self.is_show = self.Plex.type == "show"
|
self.is_show = self.Plex.type == "show"
|
||||||
|
|
||||||
|
@ -504,17 +524,18 @@ class PlexAPI:
|
||||||
else:
|
else:
|
||||||
logger.error(f"Metadata Error: {name} attribute is blank")
|
logger.error(f"Metadata Error: {name} attribute is blank")
|
||||||
|
|
||||||
def add_advanced_edit(attr, options, key=None, show_library=False):
|
def add_advanced_edit(attr, obj, group, alias, show_library=False, new_agent=False):
|
||||||
if key is None:
|
key, options = advance_keys[attr]
|
||||||
key = attr
|
if attr in alias:
|
||||||
if attr in methods:
|
if new_agent and self.agent not in new_plex_agents:
|
||||||
if show_library and not self.is_show:
|
logger.error(f"Metadata Error: {attr} attribute only works for with the New Plex Movie Agent and New Plex TV Agent")
|
||||||
|
elif show_library and not self.is_show:
|
||||||
logger.error(f"Metadata Error: {attr} attribute only works for show libraries")
|
logger.error(f"Metadata Error: {attr} attribute only works for show libraries")
|
||||||
elif meta[methods[attr]]:
|
elif group[alias[attr]]:
|
||||||
method_data = str(meta[methods[attr]]).lower()
|
method_data = str(group[alias[attr]]).lower()
|
||||||
if method_data not in options:
|
if method_data not in options:
|
||||||
logger.error(f"Metadata Error: {meta[methods[attr]]} {attr} attribute invalid")
|
logger.error(f"Metadata Error: {group[alias[attr]]} {attr} attribute invalid")
|
||||||
elif getattr(item, key) != options[method_data]:
|
elif getattr(obj, key) != options[method_data]:
|
||||||
advance_edits[key] = options[method_data]
|
advance_edits[key] = options[method_data]
|
||||||
logger.info(f"Detail: {attr} updated to {method_data}")
|
logger.info(f"Detail: {attr} updated to {method_data}")
|
||||||
else:
|
else:
|
||||||
|
@ -675,19 +696,17 @@ class PlexAPI:
|
||||||
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
|
logger.error(f"{item_type}: {mapping_name} Details Update Failed")
|
||||||
|
|
||||||
advance_edits = {}
|
advance_edits = {}
|
||||||
add_advanced_edit("episode_sorting", episode_sorting_options, key="episodeSort", show_library=True)
|
add_advanced_edit("episode_sorting", item, meta, methods, show_library=True)
|
||||||
add_advanced_edit("keep_episodes", keep_episodes_options, key="autoDeletionItemPolicyUnwatchedLibrary", show_library=True)
|
add_advanced_edit("keep_episodes", item, meta, methods, show_library=True)
|
||||||
add_advanced_edit("delete_episodes", delete_episodes_options, key="autoDeletionItemPolicyWatchedLibrary", show_library=True)
|
add_advanced_edit("delete_episodes", item, meta, methods, show_library=True)
|
||||||
add_advanced_edit("season_display", season_display_options, key="flattenSeasons", show_library=True)
|
add_advanced_edit("season_display", item, meta, methods, show_library=True)
|
||||||
add_advanced_edit("episode_ordering", episode_ordering_options, key="showOrdering", show_library=True)
|
add_advanced_edit("episode_ordering", item, meta, methods, show_library=True)
|
||||||
add_advanced_edit("metadata_language", metadata_language_options, key="languageOverride")
|
add_advanced_edit("metadata_language", item, meta, methods, new_agent=True)
|
||||||
add_advanced_edit("use_original_title", use_original_title_options, key="useOriginalTitle")
|
add_advanced_edit("use_original_title", item, meta, methods, new_agent=True)
|
||||||
if len(advance_edits) > 0:
|
if len(advance_edits) > 0:
|
||||||
logger.debug(f"Details Update: {advance_edits}")
|
logger.debug(f"Details Update: {advance_edits}")
|
||||||
updated = True
|
updated = True
|
||||||
try:
|
try:
|
||||||
check_dict = {pref.id: list(pref.enumValues.keys()) for pref in item.preferences()}
|
|
||||||
logger.info(check_dict)
|
|
||||||
item.editAdvanced(**advance_edits)
|
item.editAdvanced(**advance_edits)
|
||||||
item.reload()
|
item.reload()
|
||||||
logger.info(f"{item_type}: {mapping_name} Advanced Details Update Successful")
|
logger.info(f"{item_type}: {mapping_name} Advanced Details Update Successful")
|
||||||
|
|
|
@ -89,7 +89,7 @@ util.centered("| |_) | |/ _ \\ \\/ / | |\\/| |/ _ \\ __/ _` | | |\\/| |/ _` | '_
|
||||||
util.centered("| __/| | __/> < | | | | __/ || (_| | | | | | (_| | | | | (_| | (_| | __/ | ")
|
util.centered("| __/| | __/> < | | | | __/ || (_| | | | | | (_| | | | | (_| | (_| | __/ | ")
|
||||||
util.centered("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| ")
|
util.centered("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| ")
|
||||||
util.centered(" |___/ ")
|
util.centered(" |___/ ")
|
||||||
util.centered(" Version: 1.7.2-Beta3 ")
|
util.centered(" Version: 1.7.2-Beta4 ")
|
||||||
util.separator()
|
util.separator()
|
||||||
|
|
||||||
if my_tests:
|
if my_tests:
|
||||||
|
|
Loading…
Reference in a new issue