mirror of
https://github.com/meisnate12/Plex-Meta-Manager
synced 2024-11-10 06:54:21 +00:00
#238 Summary by Collection
This commit is contained in:
parent
9ee0bf829c
commit
ee2039039c
4 changed files with 119 additions and 23 deletions
|
@ -1660,6 +1660,7 @@ class CollectionBuilder:
|
|||
total = len(self.added_items)
|
||||
spacing = len(str(total)) * 2 + 1
|
||||
amount_added = 0
|
||||
amount_unchanged = 0
|
||||
playlist_adds = []
|
||||
for i, item in enumerate(self.added_items, 1):
|
||||
current_operation = "=" if item in collection_items else "+"
|
||||
|
@ -1667,6 +1668,7 @@ class CollectionBuilder:
|
|||
logger.info(util.adjust_space(f"{number_text:>{spacing}} | {name} {self.Type} | {current_operation} | {util.item_title(item)}"))
|
||||
if item in collection_items:
|
||||
self.plex_map[item.ratingKey] = None
|
||||
amount_unchanged += 1
|
||||
else:
|
||||
if self.playlist:
|
||||
playlist_adds.append(item)
|
||||
|
@ -1690,7 +1692,7 @@ class CollectionBuilder:
|
|||
util.print_end()
|
||||
logger.info("")
|
||||
logger.info(f"{total} {self.collection_level.capitalize()}{'s' if total > 1 else ''} Processed")
|
||||
return amount_added
|
||||
return amount_added, amount_unchanged
|
||||
|
||||
def sync_collection(self):
|
||||
amount_removed = 0
|
||||
|
@ -2326,6 +2328,7 @@ class CollectionBuilder:
|
|||
name, collection_items = self.library.get_collection_name_and_items(self.obj, self.smart_label_collection)
|
||||
self.created = False
|
||||
rating_keys = []
|
||||
amount_added = 0
|
||||
self.notification_additions = []
|
||||
for mm in self.run_again_movies:
|
||||
if mm in self.library.movie_map:
|
||||
|
@ -2345,6 +2348,7 @@ class CollectionBuilder:
|
|||
logger.info(f"{name} {self.Type} | = | {util.item_title(current)}")
|
||||
else:
|
||||
self.library.alter_collection(current, name, smart_label_collection=self.smart_label_collection)
|
||||
amount_added += 1
|
||||
logger.info(f"{name} {self.Type} | + | {util.item_title(current)}")
|
||||
if self.library.is_movie and current.ratingKey in self.library.movie_rating_key_map:
|
||||
add_id = self.library.movie_rating_key_map[current.ratingKey]
|
||||
|
@ -2383,3 +2387,5 @@ class CollectionBuilder:
|
|||
if self.details["show_missing"] is True:
|
||||
logger.info(f"{name} {self.Type} | ? | {title} (TVDb: {missing_id})")
|
||||
logger.info(f"{len(self.run_again_shows)} Show{'s' if len(self.run_again_shows) > 1 else ''} Missing")
|
||||
|
||||
return amount_added
|
|
@ -80,6 +80,8 @@ class Library(ABC):
|
|||
self.clean_bundles = params["plex"]["clean_bundles"] # TODO: Here or just in Plex?
|
||||
self.empty_trash = params["plex"]["empty_trash"] # TODO: Here or just in Plex?
|
||||
self.optimize = params["plex"]["optimize"] # TODO: Here or just in Plex?
|
||||
self.stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
self.status = {}
|
||||
|
||||
self.tmdb_library_operation = self.assets_for_all or self.mass_genre_update or self.mass_audience_rating_update \
|
||||
or self.mass_critic_rating_update or self.mass_trakt_rating_update \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import logging
|
||||
from json import JSONDecodeError
|
||||
|
||||
from modules import util
|
||||
from modules.util import Failed
|
||||
|
||||
logger = logging.getLogger("Plex Meta Manager")
|
||||
|
@ -16,6 +16,7 @@ class Webhooks:
|
|||
|
||||
def _request(self, webhooks, json):
|
||||
if self.config.trace_mode:
|
||||
util.separator("Webhooks", space=False, border=False)
|
||||
logger.debug("")
|
||||
logger.debug(f"JSON: {json}")
|
||||
for webhook in list(set(webhooks)):
|
||||
|
|
|
@ -72,7 +72,6 @@ divider = get_arg("PMM_DIVIDER", args.divider)
|
|||
screen_width = get_arg("PMM_WIDTH", args.width, arg_int=True)
|
||||
debug = get_arg("PMM_DEBUG", args.debug, arg_bool=True)
|
||||
trace = get_arg("PMM_TRACE", args.trace, arg_bool=True)
|
||||
stats = {}
|
||||
|
||||
util.separating_character = divider[0]
|
||||
|
||||
|
@ -163,8 +162,7 @@ def start(attrs):
|
|||
logger.debug("")
|
||||
util.separator(f"Starting {start_type}Run")
|
||||
config = None
|
||||
global stats
|
||||
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
try:
|
||||
config = ConfigFile(default_dir, attrs, read_only_config)
|
||||
except Exception as e:
|
||||
|
@ -172,7 +170,7 @@ def start(attrs):
|
|||
util.print_multiline(e, critical=True)
|
||||
else:
|
||||
try:
|
||||
update_libraries(config)
|
||||
stats = update_libraries(config)
|
||||
except Exception as e:
|
||||
config.notify(e)
|
||||
util.print_stacktrace()
|
||||
|
@ -190,7 +188,6 @@ def start(attrs):
|
|||
logger.removeHandler(file_handler)
|
||||
|
||||
def update_libraries(config):
|
||||
global stats
|
||||
for library in config.libraries:
|
||||
if library.skip_library:
|
||||
logger.info("")
|
||||
|
@ -278,6 +275,8 @@ def update_libraries(config):
|
|||
util.print_stacktrace()
|
||||
util.print_multiline(e, critical=True)
|
||||
|
||||
playlist_status = {}
|
||||
playlist_stats = {}
|
||||
if config.playlist_files:
|
||||
os.makedirs(os.path.join(default_dir, "logs", "playlists"), exist_ok=True)
|
||||
pf_file_logger = os.path.join(default_dir, "logs", "playlists", "playlists.log")
|
||||
|
@ -287,7 +286,7 @@ def update_libraries(config):
|
|||
if should_roll_over:
|
||||
playlists_handler.doRollover()
|
||||
logger.addHandler(playlists_handler)
|
||||
run_playlists(config)
|
||||
playlist_status, playlist_stats = run_playlists(config)
|
||||
logger.removeHandler(playlists_handler)
|
||||
|
||||
has_run_again = False
|
||||
|
@ -296,6 +295,7 @@ def update_libraries(config):
|
|||
has_run_again = True
|
||||
break
|
||||
|
||||
amount_added = 0
|
||||
if has_run_again and not library_only:
|
||||
logger.info("")
|
||||
util.separator("Run Again")
|
||||
|
@ -320,10 +320,10 @@ def update_libraries(config):
|
|||
library.map_guids()
|
||||
for builder in library.run_again:
|
||||
logger.info("")
|
||||
util.separator(f"{builder.name} Collection")
|
||||
util.separator(f"{builder.name} Collection in {library.name}")
|
||||
logger.info("")
|
||||
try:
|
||||
builder.run_collections_again()
|
||||
amount_added += builder.run_collections_again()
|
||||
except Failed as e:
|
||||
library.notify(e, collection=builder.name, critical=False)
|
||||
util.print_stacktrace()
|
||||
|
@ -345,6 +345,55 @@ def update_libraries(config):
|
|||
if library.optimize:
|
||||
library.query(library.PlexServer.library.optimize)
|
||||
|
||||
longest = 20
|
||||
for library in config.libraries:
|
||||
for title in library.status:
|
||||
if len(title) > longest:
|
||||
longest = len(title)
|
||||
if playlist_status:
|
||||
for title in playlist_status:
|
||||
if len(title) > longest:
|
||||
longest = len(title)
|
||||
def print_status(section, status):
|
||||
logger.info("")
|
||||
util.separator(f"{section} Summary", space=False, border=False)
|
||||
logger.info("")
|
||||
for name, data in status.items():
|
||||
logger.info(f"{name:<{longest}} | {data['status']:<13} | +{data['added']} ={data['unchanged']} -{data['removed']}")
|
||||
if data["errors"]:
|
||||
for error in data["errors"]:
|
||||
util.print_multiline(error, info=True)
|
||||
logger.info("")
|
||||
|
||||
util.separator("Summary")
|
||||
for library in config.libraries:
|
||||
print_status(library.name, library.status)
|
||||
if playlist_status:
|
||||
print_status("Playlists", playlist_status)
|
||||
|
||||
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
stats["added"] += amount_added
|
||||
for library in config.libraries:
|
||||
stats["created"] += library.stats["created"]
|
||||
stats["modified"] += library.stats["modified"]
|
||||
stats["deleted"] += library.stats["deleted"]
|
||||
stats["added"] += library.stats["added"]
|
||||
stats["unchanged"] += library.stats["unchanged"]
|
||||
stats["removed"] += library.stats["removed"]
|
||||
stats["radarr"] += library.stats["radarr"]
|
||||
stats["sonarr"] += library.stats["sonarr"]
|
||||
if playlist_stats:
|
||||
stats["created"] += playlist_stats["created"]
|
||||
stats["modified"] += playlist_stats["modified"]
|
||||
stats["deleted"] += playlist_stats["deleted"]
|
||||
stats["added"] += playlist_stats["added"]
|
||||
stats["unchanged"] += playlist_stats["unchanged"]
|
||||
stats["removed"] += playlist_stats["removed"]
|
||||
stats["radarr"] += playlist_stats["radarr"]
|
||||
stats["sonarr"] += playlist_stats["sonarr"]
|
||||
|
||||
return stats
|
||||
|
||||
def library_operations(config, library):
|
||||
logger.info("")
|
||||
util.separator(f"{library.name} Library Operations")
|
||||
|
@ -614,7 +663,6 @@ def library_operations(config, library):
|
|||
library.find_assets(col)
|
||||
|
||||
def run_collection(config, library, metadata, requested_collections):
|
||||
global stats
|
||||
logger.info("")
|
||||
for mapping_name, collection_attrs in requested_collections.items():
|
||||
collection_start = datetime.now()
|
||||
|
@ -653,6 +701,7 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
if should_roll_over:
|
||||
collection_handler.doRollover()
|
||||
logger.addHandler(collection_handler)
|
||||
library.status[mapping_name] = {"status": "", "errors": [], "created": False, "modified": False, "deleted": False, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
|
||||
try:
|
||||
util.separator(f"{mapping_name} Collection in {library.name}")
|
||||
|
@ -692,12 +741,16 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
builder.find_rating_keys()
|
||||
|
||||
if len(builder.added_items) >= builder.minimum and builder.build_collection:
|
||||
items_added = builder.add_to_collection()
|
||||
stats["added"] += items_added
|
||||
items_added, items_unchanged = builder.add_to_collection()
|
||||
library.stats["added"] += items_added
|
||||
library.status[mapping_name]["added"] = items_added
|
||||
library.stats["unchanged"] += items_unchanged
|
||||
library.status[mapping_name]["unchanged"] = items_unchanged
|
||||
items_removed = 0
|
||||
if builder.sync:
|
||||
items_removed = builder.sync_collection()
|
||||
stats["removed"] += items_removed
|
||||
library.stats["removed"] += items_removed
|
||||
library.status[mapping_name]["removed"] = items_removed
|
||||
elif len(builder.added_items) < builder.minimum and builder.build_collection:
|
||||
logger.info("")
|
||||
logger.info(f"Collection Minimum: {builder.minimum} not met for {mapping_name} Collection")
|
||||
|
@ -709,17 +762,21 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
|
||||
if builder.do_missing and (len(builder.missing_movies) > 0 or len(builder.missing_shows) > 0):
|
||||
radarr_add, sonarr_add = builder.run_missing()
|
||||
stats["radarr"] += radarr_add
|
||||
stats["sonarr"] += sonarr_add
|
||||
library.stats["radarr"] += radarr_add
|
||||
library.status[mapping_name]["radarr"] += radarr_add
|
||||
library.stats["sonarr"] += sonarr_add
|
||||
library.status[mapping_name]["sonarr"] += sonarr_add
|
||||
|
||||
run_item_details = True
|
||||
if valid and builder.build_collection and (builder.builders or builder.smart_url):
|
||||
try:
|
||||
builder.load_collection()
|
||||
if builder.created:
|
||||
stats["created"] += 1
|
||||
library.stats["created"] += 1
|
||||
library.status[mapping_name]["created"] = True
|
||||
elif items_added > 0 or items_removed > 0:
|
||||
stats["modified"] += 1
|
||||
library.stats["modified"] += 1
|
||||
library.status[mapping_name]["modified"] = True
|
||||
except Failed:
|
||||
util.print_stacktrace()
|
||||
run_item_details = False
|
||||
|
@ -729,7 +786,8 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
builder.update_details()
|
||||
|
||||
if builder.deleted:
|
||||
stats["deleted"] += 1
|
||||
library.stats["deleted"] += 1
|
||||
library.status[mapping_name]["deleted"] = True
|
||||
|
||||
if builder.server_preroll is not None:
|
||||
library.set_server_preroll(builder.server_preroll)
|
||||
|
@ -754,21 +812,36 @@ def run_collection(config, library, metadata, requested_collections):
|
|||
if builder.run_again and (len(builder.run_again_movies) > 0 or len(builder.run_again_shows) > 0):
|
||||
library.run_again.append(builder)
|
||||
|
||||
if library.status[mapping_name]["created"]:
|
||||
library.status[mapping_name]["status"] = "Created"
|
||||
elif library.status[mapping_name]["deleted"]:
|
||||
library.status[mapping_name]["status"] = "Deleted"
|
||||
elif library.status[mapping_name]["modified"]:
|
||||
library.status[mapping_name]["status"] = "Modified"
|
||||
else:
|
||||
library.status[mapping_name]["status"] = "Unchanged"
|
||||
except NotScheduled as e:
|
||||
util.print_multiline(e, info=True)
|
||||
library.status[mapping_name]["status"] = "Not Scheduled"
|
||||
except Failed as e:
|
||||
library.notify(e, collection=mapping_name)
|
||||
util.print_stacktrace()
|
||||
util.print_multiline(e, error=True)
|
||||
library.status[mapping_name]["status"] = "PMM Failure"
|
||||
library.status[mapping_name]["errors"].append(e)
|
||||
except Exception as e:
|
||||
library.notify(f"Unknown Error: {e}", collection=mapping_name)
|
||||
util.print_stacktrace()
|
||||
logger.error(f"Unknown Error: {e}")
|
||||
library.status[mapping_name]["status"] = "Unknown Error"
|
||||
library.status[mapping_name]["errors"].append(e)
|
||||
logger.info("")
|
||||
util.separator(f"Finished {mapping_name} Collection\nCollection Run Time: {str(datetime.now() - collection_start).split('.')[0]}")
|
||||
logger.removeHandler(collection_handler)
|
||||
|
||||
def run_playlists(config):
|
||||
stats = {"created": 0, "modified": 0, "deleted": 0, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
status = {}
|
||||
logger.info("")
|
||||
util.separator("Playlists")
|
||||
logger.info("")
|
||||
|
@ -805,6 +878,7 @@ def run_playlists(config):
|
|||
if should_roll_over:
|
||||
playlist_handler.doRollover()
|
||||
logger.addHandler(playlist_handler)
|
||||
status[mapping_name] = {"status": "", "errors": [], "created": False, "modified": False, "deleted": False, "added": 0, "unchanged": 0, "removed": 0, "radarr": 0, "sonarr": 0}
|
||||
server_name = None
|
||||
library_names = None
|
||||
try:
|
||||
|
@ -1004,12 +1078,16 @@ def run_playlists(config):
|
|||
builder.filter_and_save_items(items)
|
||||
|
||||
if len(builder.added_items) >= builder.minimum:
|
||||
items_added = builder.add_to_collection()
|
||||
items_added, items_unchanged = builder.add_to_collection()
|
||||
stats["added"] += items_added
|
||||
status[mapping_name]["added"] += items_added
|
||||
stats["unchanged"] += items_unchanged
|
||||
status[mapping_name]["unchanged"] += items_unchanged
|
||||
items_removed = 0
|
||||
if builder.sync:
|
||||
items_removed = builder.sync_collection()
|
||||
stats["removed"] += items_removed
|
||||
status[mapping_name]["removed"] += items_removed
|
||||
elif len(builder.added_items) < builder.minimum:
|
||||
logger.info("")
|
||||
logger.info(f"Playlist Minimum: {builder.minimum} not met for {mapping_name} Playlist")
|
||||
|
@ -1022,15 +1100,19 @@ def run_playlists(config):
|
|||
if builder.do_missing and (len(builder.missing_movies) > 0 or len(builder.missing_shows) > 0):
|
||||
radarr_add, sonarr_add = builder.run_missing()
|
||||
stats["radarr"] += radarr_add
|
||||
status[mapping_name]["radarr"] += radarr_add
|
||||
stats["sonarr"] += sonarr_add
|
||||
status[mapping_name]["sonarr"] += sonarr_add
|
||||
|
||||
run_item_details = True
|
||||
try:
|
||||
builder.load_collection()
|
||||
if builder.created:
|
||||
stats["created"] += 1
|
||||
status[mapping_name]["created"] = True
|
||||
elif items_added > 0 or items_removed > 0:
|
||||
stats["modified"] += 1
|
||||
status[mapping_name]["modified"] = True
|
||||
except Failed:
|
||||
util.print_stacktrace()
|
||||
run_item_details = False
|
||||
|
@ -1041,6 +1123,7 @@ def run_playlists(config):
|
|||
|
||||
if builder.deleted:
|
||||
stats["deleted"] += 1
|
||||
status[mapping_name]["deleted"] = True
|
||||
|
||||
if valid and run_item_details and builder.builders and (builder.item_details or builder.custom_sort):
|
||||
try:
|
||||
|
@ -1061,19 +1144,23 @@ def run_playlists(config):
|
|||
|
||||
except NotScheduled as e:
|
||||
util.print_multiline(e, info=True)
|
||||
status[mapping_name]["status"] = "Not Scheduled"
|
||||
except Failed as e:
|
||||
config.notify(e, server=server_name, library=library_names, playlist=mapping_name)
|
||||
util.print_stacktrace()
|
||||
util.print_multiline(e, error=True)
|
||||
status[mapping_name]["status"] = "PMM Failure"
|
||||
status[mapping_name]["errors"].append(e)
|
||||
except Exception as e:
|
||||
config.notify(f"Unknown Error: {e}", server=server_name, library=library_names, playlist=mapping_name)
|
||||
util.print_stacktrace()
|
||||
logger.error(f"Unknown Error: {e}")
|
||||
status[mapping_name]["status"] = "Unknown Error"
|
||||
status[mapping_name]["errors"].append(e)
|
||||
logger.info("")
|
||||
util.separator(
|
||||
f"Finished {mapping_name} Playlist\nPlaylist Run Time: {str(datetime.now() - playlist_start).split('.')[0]}")
|
||||
util.separator(f"Finished {mapping_name} Playlist\nPlaylist Run Time: {str(datetime.now() - playlist_start).split('.')[0]}")
|
||||
logger.removeHandler(playlist_handler)
|
||||
|
||||
return status, stats
|
||||
|
||||
try:
|
||||
if run or test or collections or libraries or resume:
|
||||
|
|
Loading…
Reference in a new issue