Added tmdb_collection library operation

pull/487/head
meisnate12 3 years ago
parent e3b77b15e1
commit 78dce17cb9

@ -125,7 +125,7 @@ class Config:
else: endline = "" else: endline = ""
yaml.round_trip_dump(loaded_config, open(self.config_path, "w"), indent=None, block_seq_indent=2) yaml.round_trip_dump(loaded_config, open(self.config_path, "w"), indent=None, block_seq_indent=2)
elif data[attribute] is None: 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 elif default_is_none: return None
else: message = f"{text} is blank" else: message = f"{text} is blank"
elif var_type == "url": elif var_type == "url":
@ -141,6 +141,7 @@ class Config:
if os.path.exists(os.path.abspath(data[attribute])): return data[attribute] if os.path.exists(os.path.abspath(data[attribute])): return data[attribute]
else: message = f"Path {os.path.abspath(data[attribute])} does not exist" 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 == "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": elif var_type == "list_path":
temp_list = [] temp_list = []
warning_message = "" 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["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["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["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 lib and "operations" in lib and lib["operations"]:
if isinstance(lib["operations"], dict): 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) 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"]: 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) 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: else:
logger.error("Config Error: operations must be a dictionary") 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) "optimize": check_for_attribute(lib, "optimize", parent="plex", var_type="bool", default=self.general["plex"]["optimize"], save=False)
} }
library = Plex(self, params) library = Plex(self, params)
logger.info("")
logger.info(f"{display_name} Library Connection Successful") logger.info(f"{display_name} Library Connection Successful")
except Failed as e: except Failed as e:
self.errors.append(e) self.errors.append(e)

@ -38,17 +38,19 @@ class Library(ABC):
self.default_dir = params["default_dir"] self.default_dir = params["default_dir"]
self.mapping_name, output = util.validate_filename(self.original_mapping_name) 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.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.asset_folders = params["asset_folders"]
self.create_asset_folders = params["create_asset_folders"]
self.sync_mode = params["sync_mode"] 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_unmanaged = params["show_unmanaged"]
self.show_filtered = params["show_filtered"] self.show_filtered = params["show_filtered"]
self.show_missing = params["show_missing"] self.show_missing = params["show_missing"]
self.show_missing_assets = params["show_missing_assets"] self.show_missing_assets = params["show_missing_assets"]
self.save_missing = params["save_missing"] self.save_missing = params["save_missing"]
self.missing_only_released = params["missing_only_released"]
self.only_filter_missing = params["only_filter_missing"] 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.assets_for_all = params["assets_for_all"]
self.delete_unmanaged_collections = params["delete_unmanaged_collections"] self.delete_unmanaged_collections = params["delete_unmanaged_collections"]
self.delete_collections_with_less = params["delete_collections_with_less"] 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_audience_rating_update = params["mass_audience_rating_update"]
self.mass_critic_rating_update = params["mass_critic_rating_update"] self.mass_critic_rating_update = params["mass_critic_rating_update"]
self.mass_trakt_rating_update = params["mass_trakt_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.radarr_add_all = params["radarr_add_all"]
self.sonarr_add_all = params["sonarr_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.error_webhooks = params["error_webhooks"]
self.collection_creation_webhooks = params["collection_creation_webhooks"] self.collection_creation_webhooks = params["collection_creation_webhooks"]
self.collection_addition_webhooks = params["collection_addition_webhooks"] self.collection_addition_webhooks = params["collection_addition_webhooks"]

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

@ -260,6 +260,9 @@ class Plex(Library):
self.is_other = self.agent == "com.plexapp.agents.none" self.is_other = self.agent == "com.plexapp.agents.none"
if self.is_other: if self.is_other:
self.type = "Video" 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): def get_all_collections(self):
return self.search(libtype="collection") return self.search(libtype="collection")

@ -6,6 +6,7 @@ try:
from modules import util from modules import util
from modules.builder import CollectionBuilder from modules.builder import CollectionBuilder
from modules.config import Config from modules.config import Config
from modules.meta import Metadata
from modules.util import Failed, NotScheduled from modules.util import Failed, NotScheduled
except ModuleNotFoundError: except ModuleNotFoundError:
print("Requirements Error: Requirements are not installed") print("Requirements Error: Requirements are not installed")
@ -180,6 +181,42 @@ def update_libraries(config):
plexapi.server.TIMEOUT = library.timeout plexapi.server.TIMEOUT = library.timeout
logger.info("") logger.info("")
util.separator(f"{library.name} Library") 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 items = None
if not library.is_other: if not library.is_other:
logger.info("") logger.info("")
@ -292,11 +329,13 @@ def library_operations(config, library, items=None):
logger.info(util.adjust_space(f"{item.title[:25]:<25} | Splitting")) 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 \ 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: if items is None:
items = library.get_all() items = library.get_all()
radarr_adds = [] radarr_adds = []
sonarr_adds = [] sonarr_adds = []
tmdb_collections = {}
trakt_ratings = config.Trakt.user_ratings(library.is_movie) if library.mass_trakt_rating_update else [] trakt_ratings = config.Trakt.user_ratings(library.is_movie) if library.mass_trakt_rating_update else []
for i, item in enumerate(items, 1): 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)}/")) sonarr_adds.append((tvdb_id, f"{path.replace(library.Sonarr.plex_path, library.Sonarr.sonarr_path)}/"))
tmdb_item = None 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: if tvdb_id and not tmdb_id:
tmdb_id = config.Convert.tvdb_to_tmdb(tvdb_id) tmdb_id = config.Convert.tvdb_to_tmdb(tvdb_id)
if tmdb_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: if not tmdb_item and not omdb_item and not tvdb_item:
continue 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: if library.mass_genre_update:
try: try:
if tmdb_item and library.mass_genre_update == "tmdb": if tmdb_item and library.mass_genre_update == "tmdb":
@ -446,6 +488,22 @@ def library_operations(config, library, items=None):
except Failed as e: except Failed as e:
logger.error(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: if library.delete_collections_with_less is not None or library.delete_unmanaged_collections:
logger.info("") logger.info("")
suffix = "" suffix = ""

Loading…
Cancel
Save