From a0bc06c62084f4116c3e0519522b15f7d4bcde0e Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 30 Jun 2022 16:18:12 +0200 Subject: [PATCH] use query functions for rest of avalon context functions --- openpype/lib/avalon_context.py | 232 +++++++++++++-------------------- 1 file changed, 90 insertions(+), 142 deletions(-) diff --git a/openpype/lib/avalon_context.py b/openpype/lib/avalon_context.py index 02b4cad6f2..7b00032027 100644 --- a/openpype/lib/avalon_context.py +++ b/openpype/lib/avalon_context.py @@ -13,8 +13,15 @@ import warnings from openpype.client import ( get_project, + get_assets, + get_asset_by_name, + get_subset_by_name, + get_subsets, get_version_by_id, + get_last_versions, get_last_version_by_subset_id, + get_representations, + get_representation_by_id, get_workfile_info, ) from openpype.settings import ( @@ -210,6 +217,7 @@ def any_outdated(): """Return whether the current scene has any outdated content""" from openpype.pipeline import registered_host + project_name = legacy_io.active_project() checked = set() host = registered_host() for container in host.ls(): @@ -217,12 +225,8 @@ def any_outdated(): if representation in checked: continue - representation_doc = legacy_io.find_one( - { - "_id": ObjectId(representation), - "type": "representation" - }, - projection={"parent": True} + representation_doc = get_representation_by_id( + project_name, representation, fields=["parent"] ) if representation_doc and not is_latest(representation_doc): return True @@ -240,22 +244,20 @@ def any_outdated(): def get_asset(asset_name=None): """ Returning asset document from database by its name. - Doesn't count with duplicities on asset names! + Doesn't count with duplicities on asset names! - Args: - asset_name (str) + Args: + asset_name (str) - Returns: - (MongoDB document) + Returns: + (MongoDB document) """ + + project_name = legacy_io.active_project() if not asset_name: asset_name = legacy_io.Session["AVALON_ASSET"] - asset_document = legacy_io.find_one({ - "name": asset_name, - "type": "asset" - }) - + asset_document = get_asset_by_name(project_name, asset_name) if not asset_document: raise TypeError("Entity \"{}\" was not found in DB".format(asset_name)) @@ -311,11 +313,13 @@ def get_linked_assets(asset_doc): Returns: (list) Asset documents of input links for passed asset doc. """ + link_ids = get_linked_asset_ids(asset_doc) if not link_ids: return [] - return list(legacy_io.find({"_id": {"$in": link_ids}})) + project_name = legacy_io.active_project() + return list(get_assets(project_name, link_ids)) @with_pipeline_io @@ -337,20 +341,14 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): dict: Last version document for entered . """ - if not dbcon: - log.debug("Using `legacy_io` for query.") - dbcon = legacy_io - # Make sure is installed - dbcon.install() + if not project_name: + if not dbcon: + log.debug("Using `legacy_io` for query.") + dbcon = legacy_io + # Make sure is installed + dbcon.install() - if project_name and project_name != dbcon.Session.get("AVALON_PROJECT"): - # `legacy_io` has only `_database` attribute - # but `AvalonMongoDB` has `database` - database = getattr(dbcon, "database", dbcon._database) - collection = database[project_name] - else: - project_name = dbcon.Session.get("AVALON_PROJECT") - collection = dbcon + project_name = dbcon.active_project() log.debug(( "Getting latest version for Project: \"{}\" Asset: \"{}\"" @@ -358,19 +356,15 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): ).format(project_name, asset_name, subset_name)) # Query asset document id by asset name - asset_doc = collection.find_one( - {"type": "asset", "name": asset_name}, - {"_id": True} - ) + asset_doc = get_asset_by_name(project_name, asset_name, fields=["_id"]) if not asset_doc: log.info( "Asset \"{}\" was not found in Database.".format(asset_name) ) return None - subset_doc = collection.find_one( - {"type": "subset", "name": subset_name, "parent": asset_doc["_id"]}, - {"_id": True} + subset_doc = get_subset_by_name( + project_name, subset_name, asset_doc["_id"] ) if not subset_doc: log.info( @@ -378,10 +372,7 @@ def get_latest_version(asset_name, subset_name, dbcon=None, project_name=None): ) return None - version_doc = collection.find_one( - {"type": "version", "parent": subset_doc["_id"]}, - sort=[("name", -1)], - ) + version_doc = get_last_version_by_subset_id(project_name, subset_doc["_id"]) if not version_doc: log.info( "Subset \"{}\" does not have any version yet.".format(subset_name) @@ -418,28 +409,17 @@ def get_workfile_template_key_from_context( ValueError: When both 'dbcon' and 'project_name' were not passed. """ - if not dbcon: - if not project_name: + if not project_name: + if not dbcon: raise ValueError(( "`get_workfile_template_key_from_context` requires to pass" " one of 'dbcon' or 'project_name' arguments." )) - from openpype.pipeline import AvalonMongoDB - dbcon = AvalonMongoDB() - dbcon.Session["AVALON_PROJECT"] = project_name + project_name = dbcon.active_project() - elif not project_name: - project_name = dbcon.Session["AVALON_PROJECT"] - - asset_doc = dbcon.find_one( - { - "type": "asset", - "name": asset_name - }, - { - "data.tasks": 1 - } + asset_doc = get_asset_by_name( + project_name, asset_name, fields=["data.tasks"] ) asset_tasks = asset_doc.get("data", {}).get("tasks") or {} task_info = asset_tasks.get(task_name) or {} @@ -632,6 +612,7 @@ def get_workdir( Returns: TemplateResult: Workdir path. """ + if not anatomy: anatomy = Anatomy(project_doc["name"]) @@ -659,15 +640,11 @@ def template_data_from_session(session=None): session = legacy_io.Session project_name = session["AVALON_PROJECT"] - project_doc = legacy_io.database[project_name].find_one({ - "type": "project" - }) - asset_doc = legacy_io.database[project_name].find_one({ - "type": "asset", - "name": session["AVALON_ASSET"] - }) + asset_name = session["AVALON_ASSET"] task_name = session["AVALON_TASK"] host_name = session["AVALON_APP"] + project_doc = get_project(project_name) + asset_doc = get_asset_by_name(project_name, asset_name) return get_workdir_data(project_doc, asset_doc, task_name, host_name) @@ -692,8 +669,8 @@ def compute_session_changes( Returns: dict: The required changes in the Session dictionary. - """ + changes = dict() # If no changes, return directly @@ -711,12 +688,9 @@ def compute_session_changes( if not asset_document or not asset_tasks: # Assume asset name - asset_document = legacy_io.find_one( - { - "name": asset, - "type": "asset" - }, - {"data.tasks": True} + project_name = session["AVALON_PROJECT"] + asset_document = get_asset_by_name( + project_name, asset, fields=["data.tasks"] ) assert asset_document, "Asset must exist" @@ -864,12 +838,13 @@ def create_workfile_doc(asset_doc, task_name, filename, workdir, dbcon=None): doc_data = copy.deepcopy(doc_filter) # Prepare project for workdir data - project_doc = dbcon.find_one({"type": "project"}) + project_name = dbcon.active_project() + project_doc = get_project(project_name) workdir_data = get_workdir_data( project_doc, asset_doc, task_name, dbcon.Session["AVALON_APP"] ) # Prepare anatomy - anatomy = Anatomy(project_doc["name"]) + anatomy = Anatomy(project_name) # Get workdir path (result is anatomy.TemplateResult) template_workdir = get_workdir_with_workdir_data( workdir_data, anatomy @@ -984,12 +959,9 @@ class BuildWorkfile: from openpype.pipeline import discover_loader_plugins # Get current asset name and entity + project_name = legacy_io.active_project() current_asset_name = legacy_io.Session["AVALON_ASSET"] - current_asset_entity = legacy_io.find_one({ - "type": "asset", - "name": current_asset_name - }) - + current_asset_entity = get_asset_by_name(project_name, current_asset_name) # Skip if asset was not found if not current_asset_entity: print("Asset entity with name `{}` was not found".format( @@ -1494,7 +1466,7 @@ class BuildWorkfile: return loaded_containers @with_pipeline_io - def _collect_last_version_repres(self, asset_entities): + def _collect_last_version_repres(self, asset_docs): """Collect subsets, versions and representations for asset_entities. Args: @@ -1527,64 +1499,56 @@ class BuildWorkfile: ``` """ - if not asset_entities: - return {} + output = {} + if not asset_docs: + return output - asset_entity_by_ids = {asset["_id"]: asset for asset in asset_entities} + asset_docs_by_ids = {asset["_id"]: asset for asset in asset_docs} - subsets = list(legacy_io.find({ - "type": "subset", - "parent": {"$in": list(asset_entity_by_ids.keys())} - })) + project_name = legacy_io.active_project() + subsets = list(get_subsets( + project_name, asset_ids=asset_docs_by_ids.keys() + )) subset_entity_by_ids = {subset["_id"]: subset for subset in subsets} - sorted_versions = list(legacy_io.find({ - "type": "version", - "parent": {"$in": list(subset_entity_by_ids.keys())} - }).sort("name", -1)) + last_version_by_subset_id = get_last_versions( + project_name, subset_entity_by_ids.keys() + ) + last_version_docs_by_id = { + version["_id"]: version + for version in last_version_by_subset_id.values() + } + repre_docs = get_representations( + project_name, version_ids=last_version_docs_by_id.keys() + ) - subset_id_with_latest_version = [] - last_versions_by_id = {} - for version in sorted_versions: - subset_id = version["parent"] - if subset_id in subset_id_with_latest_version: - continue - subset_id_with_latest_version.append(subset_id) - last_versions_by_id[version["_id"]] = version + for repre_doc in repre_docs: + version_id = repre_doc["parent"] + version_doc = last_version_docs_by_id[version_id] - repres = legacy_io.find({ - "type": "representation", - "parent": {"$in": list(last_versions_by_id.keys())} - }) + subset_id = version_doc["parent"] + subset_doc = subset_entity_by_ids[subset_id] - output = {} - for repre in repres: - version_id = repre["parent"] - version = last_versions_by_id[version_id] - - subset_id = version["parent"] - subset = subset_entity_by_ids[subset_id] - - asset_id = subset["parent"] - asset = asset_entity_by_ids[asset_id] + asset_id = subset_doc["parent"] + asset_doc = asset_docs_by_ids[asset_id] if asset_id not in output: output[asset_id] = { - "asset_entity": asset, + "asset_entity": asset_doc, "subsets": {} } if subset_id not in output[asset_id]["subsets"]: output[asset_id]["subsets"][subset_id] = { - "subset_entity": subset, + "subset_entity": subset_doc, "version": { - "version_entity": version, + "version_entity": version_doc, "repres": [] } } output[asset_id]["subsets"][subset_id]["version"]["repres"].append( - repre + repre_doc ) return output @@ -1790,35 +1754,19 @@ def get_custom_workfile_template_by_string_context( context. (Existence of formatted path is not validated.) """ - if dbcon is None: - from openpype.pipeline import AvalonMongoDB + project_name = None + if anatomy is not None: + project_name = anatomy.project_name - dbcon = AvalonMongoDB() + if not project_name and dbcon is not None: + project_name = dbcon.active_project() - dbcon.install() + if not project_name: + raise ValueError("Can't determina project") - if dbcon.Session["AVALON_PROJECT"] != project_name: - dbcon.Session["AVALON_PROJECT"] = project_name - - project_doc = dbcon.find_one( - {"type": "project"}, - # All we need is "name" and "data.code" keys - { - "name": 1, - "data.code": 1 - } - ) - asset_doc = dbcon.find_one( - { - "type": "asset", - "name": asset_name - }, - # All we need is "name" and "data.tasks" keys - { - "name": 1, - "data.tasks": 1 - } - ) + project_doc = get_project(project_name, fields=["name", "data.code"]) + asset_doc = get_asset_by_name( + project_name, asset_name, fields=["name", "data.tasks"]) return get_custom_workfile_template_by_context( template_profiles, project_doc, asset_doc, task_name, anatomy