Added tmdb_collection library operation

This commit is contained in:
meisnate12 2021-12-06 02:52:08 -05:00
parent e3b77b15e1
commit 78dce17cb9
5 changed files with 113 additions and 34 deletions

View file

@ -125,7 +125,7 @@ class Config:
else: endline = ""
yaml.round_trip_dump(loaded_config, open(self.config_path, "w"), indent=None, block_seq_indent=2)
elif data[attribute] is None:
if default_is_none and var_type == "list": return []
if default_is_none and var_type in ["list", "int_list"]: return []
elif default_is_none: return None
else: message = f"{text} is blank"
elif var_type == "url":
@ -141,6 +141,7 @@ class Config:
if os.path.exists(os.path.abspath(data[attribute])): return data[attribute]
else: message = f"Path {os.path.abspath(data[attribute])} does not exist"
elif var_type == "list": return util.get_list(data[attribute], split=False)
elif var_type == "int_list": return util.get_list(data[attribute], int_list=True)
elif var_type == "list_path":
temp_list = []
warning_message = ""
@ -437,6 +438,7 @@ class Config:
params["split_duplicates"] = check_for_attribute(lib, "split_duplicates", var_type="bool", default=False, save=False, do_print=False)
params["radarr_add_all"] = check_for_attribute(lib, "radarr_add_all", var_type="bool", default=False, save=False, do_print=False)
params["sonarr_add_all"] = check_for_attribute(lib, "sonarr_add_all", var_type="bool", default=False, save=False, do_print=False)
params["tmdb_collections"] = None
if lib and "operations" in lib and lib["operations"]:
if isinstance(lib["operations"], dict):
@ -460,6 +462,17 @@ class Config:
params["radarr_add_all"] = check_for_attribute(lib["operations"], "radarr_add_all", var_type="bool", default=False, save=False)
if "sonarr_add_all" in lib["operations"]:
params["sonarr_add_all"] = check_for_attribute(lib["operations"], "sonarr_add_all", var_type="bool", default=False, save=False)
if "tmdb_collections" in lib["operations"]:
params["tmdb_collections"] = {"exclude_ids": [], "remove_collection": False, "template": {"tmdb_collection_details": "<<collection_id>>"}}
if lib["operations"]["tmdb_collections"] and isinstance(lib["operations"]["tmdb_collections"], dict):
params["tmdb_collections"]["exclude_ids"] = check_for_attribute(lib["operations"]["tmdb_collections"], "exclude_ids", var_type="int_list", default_is_none=True, save=False)
params["tmdb_collections"]["remove_collection"] = check_for_attribute(lib["operations"]["tmdb_collections"], "remove_collection", var_type="bool", default=False, save=False)
if "template" in lib["operations"]["tmdb_collections"] and lib["operations"]["tmdb_collections"]["template"] and isinstance(lib["operations"]["tmdb_collections"]["template"], dict):
params["tmdb_collections"]["template"] = lib["operations"]["tmdb_collections"]["template"]
else:
logger.warning("Config Warning: Using default template for tmdb_collections")
else:
logger.error("Config Error: tmdb_collections blank using default settings")
else:
logger.error("Config Error: operations must be a dictionary")
@ -512,7 +525,6 @@ class Config:
"optimize": check_for_attribute(lib, "optimize", parent="plex", var_type="bool", default=self.general["plex"]["optimize"], save=False)
}
library = Plex(self, params)
logger.info("")
logger.info(f"{display_name} Library Connection Successful")
except Failed as e:
self.errors.append(e)

View file

@ -38,17 +38,19 @@ class Library(ABC):
self.default_dir = params["default_dir"]
self.mapping_name, output = util.validate_filename(self.original_mapping_name)
self.image_table_name = self.config.Cache.get_image_table_name(self.original_mapping_name) if self.config.Cache else None
self.missing_path = os.path.join(self.default_dir, f"{self.original_mapping_name}_missing.yml")
self.missing_path = os.path.join(self.default_dir, f"{self.mapping_name}_missing.yml")
self.asset_folders = params["asset_folders"]
self.create_asset_folders = params["create_asset_folders"]
self.sync_mode = params["sync_mode"]
self.collection_minimum = params["collection_minimum"]
self.delete_below_minimum = params["delete_below_minimum"]
self.missing_only_released = params["missing_only_released"]
self.show_unmanaged = params["show_unmanaged"]
self.show_filtered = params["show_filtered"]
self.show_missing = params["show_missing"]
self.show_missing_assets = params["show_missing_assets"]
self.save_missing = params["save_missing"]
self.missing_only_released = params["missing_only_released"]
self.only_filter_missing = params["only_filter_missing"]
self.create_asset_folders = params["create_asset_folders"]
self.assets_for_all = params["assets_for_all"]
self.delete_unmanaged_collections = params["delete_unmanaged_collections"]
self.delete_collections_with_less = params["delete_collections_with_less"]
@ -56,10 +58,9 @@ class Library(ABC):
self.mass_audience_rating_update = params["mass_audience_rating_update"]
self.mass_critic_rating_update = params["mass_critic_rating_update"]
self.mass_trakt_rating_update = params["mass_trakt_rating_update"]
self.tmdb_collections = params["tmdb_collections"]
self.radarr_add_all = params["radarr_add_all"]
self.sonarr_add_all = params["sonarr_add_all"]
self.collection_minimum = params["collection_minimum"]
self.delete_below_minimum = params["delete_below_minimum"]
self.error_webhooks = params["error_webhooks"]
self.collection_creation_webhooks = params["collection_creation_webhooks"]
self.collection_addition_webhooks = params["collection_addition_webhooks"]

View file

@ -15,8 +15,6 @@ class Metadata:
self.library = library
self.type = file_type
self.path = path
logger.info("")
logger.info(f"Loading Metadata {file_type}: {path}")
def get_dict(attribute, attr_data, check_list=None):
if check_list is None:
check_list = []
@ -35,30 +33,37 @@ class Metadata:
else:
logger.warning(f"Config Warning: {attribute} attribute is blank")
return None
try:
if file_type in ["URL", "Git"]:
content_path = path if file_type == "URL" else f"{github_base}{path}.yml"
response = self.config.get(content_path)
if response.status_code >= 400:
raise Failed(f"URL Error: No file found at {content_path}")
content = response.content
elif os.path.exists(os.path.abspath(path)):
content = open(path, encoding="utf-8")
else:
raise Failed(f"File Error: File does not exist {path}")
data, ind, bsi = yaml.util.load_yaml_guess_indent(content)
self.metadata = get_dict("metadata", data, library.metadatas)
self.templates = get_dict("templates", data)
self.collections = get_dict("collections", data, library.collections)
if file_type == "Data":
self.metadata = None
self.collections = get_dict("collections", path, library.collections)
self.templates = get_dict("templates", path)
else:
try:
logger.info("")
logger.info(f"Loading Metadata {file_type}: {path}")
if file_type in ["URL", "Git"]:
content_path = path if file_type == "URL" else f"{github_base}{path}.yml"
response = self.config.get(content_path)
if response.status_code >= 400:
raise Failed(f"URL Error: No file found at {content_path}")
content = response.content
elif os.path.exists(os.path.abspath(path)):
content = open(path, encoding="utf-8")
else:
raise Failed(f"File Error: File does not exist {path}")
data, ind, bsi = yaml.util.load_yaml_guess_indent(content)
self.metadata = get_dict("metadata", data, library.metadatas)
self.templates = get_dict("templates", data)
self.collections = get_dict("collections", data, library.collections)
if self.metadata is None and self.collections is None:
raise Failed("YAML Error: metadata or collections attribute is required")
logger.info(f"Metadata File Loaded Successfully")
except yaml.scanner.ScannerError as ye:
raise Failed(f"YAML Error: {util.tab_new_lines(ye)}")
except Exception as e:
util.print_stacktrace()
raise Failed(f"YAML Error: {e}")
if self.metadata is None and self.collections is None:
raise Failed("YAML Error: metadata or collections attribute is required")
logger.info(f"Metadata File Loaded Successfully")
except yaml.scanner.ScannerError as ye:
raise Failed(f"YAML Error: {util.tab_new_lines(ye)}")
except Exception as e:
util.print_stacktrace()
raise Failed(f"YAML Error: {e}")
def get_collections(self, requested_collections):
if requested_collections:

View file

@ -260,6 +260,9 @@ class Plex(Library):
self.is_other = self.agent == "com.plexapp.agents.none"
if self.is_other:
self.type = "Video"
if self.tmdb_collections and self.is_show:
self.tmdb_collections = None
logger.error("Config Error: tmdb_collections only work with Movie Libraries.")
def get_all_collections(self):
return self.search(libtype="collection")

View file

@ -6,6 +6,7 @@ try:
from modules import util
from modules.builder import CollectionBuilder
from modules.config import Config
from modules.meta import Metadata
from modules.util import Failed, NotScheduled
except ModuleNotFoundError:
print("Requirements Error: Requirements are not installed")
@ -180,6 +181,42 @@ def update_libraries(config):
plexapi.server.TIMEOUT = library.timeout
logger.info("")
util.separator(f"{library.name} Library")
logger.debug("")
logger.debug(f"Mapping Name: {library.original_mapping_name}")
logger.debug(f"Folder Name: {library.mapping_name}")
logger.debug(f"Missing Path: {library.missing_path}")
for ad in library.asset_directory:
logger.debug(f"Asset Directory: {ad}")
logger.debug(f"Asset Folders: {library.asset_folders}")
logger.debug(f"Create Asset Folders: {library.create_asset_folders}")
logger.debug(f"Sync Mode: {library.sync_mode}")
logger.debug(f"Collection Minimum: {library.collection_minimum}")
logger.debug(f"Delete Below Minimum: {library.delete_below_minimum}")
logger.debug(f"Missing Only Released: {library.missing_only_released}")
logger.debug(f"Only Filter Missing: {library.only_filter_missing}")
logger.debug(f"Show Unmanaged: {library.show_unmanaged}")
logger.debug(f"Show Filtered: {library.show_filtered}")
logger.debug(f"Show Missing: {library.show_missing}")
logger.debug(f"Show Missing Assets: {library.show_missing_assets}")
logger.debug(f"Save Missing: {library.save_missing}")
logger.debug(f"Assets For All: {library.assets_for_all}")
logger.debug(f"Delete Collections With Less: {library.delete_collections_with_less}")
logger.debug(f"Delete Unmanaged Collections: {library.delete_unmanaged_collections}")
logger.debug(f"Mass Genre Update: {library.mass_genre_update}")
logger.debug(f"Mass Audience Rating Update: {library.mass_audience_rating_update}")
logger.debug(f"Mass Critic Rating Update: {library.mass_critic_rating_update}")
logger.debug(f"Mass Trakt Rating Update: {library.mass_trakt_rating_update}")
logger.debug(f"Split Duplicates: {library.split_duplicates}")
logger.debug(f"Split Duplicates: {library.split_duplicates}")
logger.debug(f"Radarr Add All: {library.radarr_add_all}")
logger.debug(f"Sonarr Add All: {library.sonarr_add_all}")
logger.debug(f"TMDb Collections: {library.tmdb_collections}")
logger.debug(f"Clean Bundles: {library.clean_bundles}")
logger.debug(f"Empty Trash: {library.empty_trash}")
logger.debug(f"Optimize: {library.optimize}")
logger.debug(f"Timeout: {library.timeout}")
items = None
if not library.is_other:
logger.info("")
@ -292,11 +329,13 @@ def library_operations(config, library, items=None):
logger.info(util.adjust_space(f"{item.title[:25]:<25} | Splitting"))
if library.assets_for_all or library.mass_genre_update or library.mass_audience_rating_update or \
library.mass_critic_rating_update or library.mass_trakt_rating_update or library.radarr_add_all or library.sonarr_add_all:
library.mass_critic_rating_update or library.mass_trakt_rating_update or library.tmdb_collections or \
library.radarr_add_all or library.sonarr_add_all:
if items is None:
items = library.get_all()
radarr_adds = []
sonarr_adds = []
tmdb_collections = {}
trakt_ratings = config.Trakt.user_ratings(library.is_movie) if library.mass_trakt_rating_update else []
for i, item in enumerate(items, 1):
@ -346,7 +385,7 @@ def library_operations(config, library, items=None):
sonarr_adds.append((tvdb_id, f"{path.replace(library.Sonarr.plex_path, library.Sonarr.sonarr_path)}/"))
tmdb_item = None
if library.mass_genre_update == "tmdb" or library.mass_audience_rating_update == "tmdb" or library.mass_critic_rating_update == "tmdb":
if library.tmdb_collections or library.mass_genre_update == "tmdb" or library.mass_audience_rating_update == "tmdb" or library.mass_critic_rating_update == "tmdb":
if tvdb_id and not tmdb_id:
tmdb_id = config.Convert.tvdb_to_tmdb(tvdb_id)
if tmdb_id:
@ -388,6 +427,9 @@ def library_operations(config, library, items=None):
if not tmdb_item and not omdb_item and not tvdb_item:
continue
if library.tmdb_collections and tmdb_item and tmdb_item.belongs_to_collection:
tmdb_collections[tmdb_item.belongs_to_collection.id] = tmdb_item.belongs_to_collection.name
if library.mass_genre_update:
try:
if tmdb_item and library.mass_genre_update == "tmdb":
@ -446,6 +488,22 @@ def library_operations(config, library, items=None):
except Failed as e:
logger.error(e)
if tmdb_collections:
logger.info("")
util.separator(f"Starting TMDb Collections")
logger.info("")
metadata = Metadata(config, library, "Data", {
"collections": {
_n.replace(" Collection", "") if library.tmdb_collections["remove_collection"] else _n:
{"template": {"name": "TMDb Collection", "collection_id": _i}}
for _i, _n in tmdb_collections.items() if int(_i) not in library.tmdb_collections["exclude_ids"]
},
"templates": {
"TMDb Collection": library.tmdb_collections["template"]
}
})
run_collection(config, library, metadata, metadata.get_collections(None))
if library.delete_collections_with_less is not None or library.delete_unmanaged_collections:
logger.info("")
suffix = ""