Skip to content

Commit

Permalink
Refact avalon context lib
Browse files Browse the repository at this point in the history
  • Loading branch information
BenoitConnan authored and ClementHector committed Feb 8, 2022
1 parent 28450cc commit aff4b01
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 221 deletions.
2 changes: 2 additions & 0 deletions openpype/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@
get_hierarchy,
get_linked_assets,
get_latest_version,
get_loaders_by_name,
collect_last_version_repres,

get_workfile_template_key,
get_workfile_template_key_from_context,
Expand Down
120 changes: 4 additions & 116 deletions openpype/lib/abstract_load_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,120 +2,8 @@
import re
import avalon
from openpype.settings import get_project_settings
from openpype.lib import Anatomy
from openpype.lib import get_linked_assets

# Copy from BuildWorkfile in avalon_context.py
# TODO : Move those function into a lib


def _collect_last_version_repres(asset_entities):
"""Collect subsets, versions and representations for asset_entities.
Args:
asset_entities (list): Asset entities for which want to find data
Returns:
(dict): collected entities
Example output:
```
{
{Asset ID}: {
"asset_entity": <AssetEntity>,
"subsets": {
{Subset ID}: {
"subset_entity": <SubsetEntity>,
"version": {
"version_entity": <VersionEntity>,
"repres": [
<RepreEntity1>, <RepreEntity2>, ...
]
}
},
...
}
},
...
}
output[asset_id]["subsets"][subset_id]["version"]["repres"]
```
"""

if not asset_entities:
return {}

asset_entity_by_ids = {asset["_id"]: asset for asset in asset_entities}

subsets = list(avalon.io.find({
"type": "subset",
"parent": {"$in": asset_entity_by_ids.keys()}
}))
subset_entity_by_ids = {subset["_id"]: subset for subset in subsets}

sorted_versions = list(avalon.io.find({
"type": "version",
"parent": {"$in": subset_entity_by_ids.keys()}
}).sort("name", -1))

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

repres = avalon.io.find({
"type": "representation",
"parent": {"$in": last_versions_by_id.keys()}
})

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]

if asset_id not in output:
output[asset_id] = {
"asset_entity": asset,
"subsets": {}
}

if subset_id not in output[asset_id]["subsets"]:
output[asset_id]["subsets"][subset_id] = {
"subset_entity": subset,
"version": {
"version_entity": version,
"repres": []
}
}

output[asset_id]["subsets"][subset_id]["version"]["repres"].append(
repre
)

return output


def get_loader_by_name():

loaders_by_name = {}
for loader in avalon.api.discover(avalon.api.Loader):
loader_name = loader.__name__
if loader_name in loaders_by_name:
raise KeyError(
"Duplicated loader name {0}!".format(loader_name)
)
loaders_by_name[loader_name] = loader
return loaders_by_name
from openpype.lib import Anatomy, get_linked_assets, get_loaders_by_name,\
collect_last_version_repres


class AbstractTemplateLoader(object):
Expand Down Expand Up @@ -192,7 +80,7 @@ def __init__(self, placeholder_class):

self.import_template(self.template_path)

loaders_by_name = get_loader_by_name()
loaders_by_name = get_loaders_by_name()

# Skip if there is no loader
if not loaders_by_name:
Expand All @@ -206,7 +94,7 @@ def __init__(self, placeholder_class):
})

linked_asset_entities = get_linked_assets(current_asset_entity)
version_repres = _collect_last_version_repres(
version_repres = collect_last_version_repres(
[current_asset_entity] + linked_asset_entities)

linked_representations_by_id = {representation['_id']: representation
Expand Down
217 changes: 112 additions & 105 deletions openpype/lib/avalon_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,116 @@ def save_workfile_data_to_doc(workfile_doc, data, dbcon=None):
)


@with_avalon
def collect_last_version_repres(asset_entities):
"""Collect subsets, versions and representations for asset_entities.
Args:
asset_entities (list): Asset entities for which want to find data
Returns:
(dict): collected entities
Example output:
```
{
{Asset ID}: {
"asset_entity": <AssetEntity>,
"subsets": {
{Subset ID}: {
"subset_entity": <SubsetEntity>,
"version": {
"version_entity": <VersionEntity>,
"repres": [
<RepreEntity1>, <RepreEntity2>, ...
]
}
},
...
}
},
...
}
output[asset_id]["subsets"][subset_id]["version"]["repres"]
```
"""

if not asset_entities:
return {}

asset_entity_by_ids = {asset["_id"]: asset for asset in asset_entities}

subsets = list(avalon.io.find({
"type": "subset",
"parent": {"$in": asset_entity_by_ids.keys()}
}))
subset_entity_by_ids = {subset["_id"]: subset for subset in subsets}

sorted_versions = list(avalon.io.find({
"type": "version",
"parent": {"$in": subset_entity_by_ids.keys()}
}).sort("name", -1))

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

repres = avalon.io.find({
"type": "representation",
"parent": {"$in": last_versions_by_id.keys()}
})

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]

if asset_id not in output:
output[asset_id] = {
"asset_entity": asset,
"subsets": {}
}

if subset_id not in output[asset_id]["subsets"]:
output[asset_id]["subsets"][subset_id] = {
"subset_entity": subset,
"version": {
"version_entity": version,
"repres": []
}
}

output[asset_id]["subsets"][subset_id]["version"]["repres"].append(
repre
)

return output


def get_loaders_by_name():

loaders_by_name = {}
for loader in avalon.api.discover(avalon.api.Loader):
loader_name = loader.__name__
if loader_name in loaders_by_name:
raise KeyError(
"Duplicated loader name {0}!".format(loader_name)
)
loaders_by_name[loader_name] = loader
return loaders_by_name


class BuildWorkfile:
"""Wrapper for build workfile process.
Expand Down Expand Up @@ -816,14 +926,7 @@ def build_workfile(self):
return

# Prepare available loaders
loaders_by_name = {}
for loader in avalon.api.discover(avalon.api.Loader):
loader_name = loader.__name__
if loader_name in loaders_by_name:
raise KeyError(
"Duplicated loader name {0}!".format(loader_name)
)
loaders_by_name[loader_name] = loader
loaders_by_name = get_loaders_by_name()

# Skip if there are any loaders
if not loaders_by_name:
Expand Down Expand Up @@ -895,7 +998,7 @@ def build_workfile(self):
return

# Prepare entities from database for assets
prepared_entities = self._collect_last_version_repres(assets)
prepared_entities = collect_last_version_repres(assets)

# Load containers by prepared entities and presets
loaded_containers = []
Expand Down Expand Up @@ -1306,102 +1409,6 @@ def _load_containers(

return loaded_containers

@with_avalon
def _collect_last_version_repres(self, asset_entities):
"""Collect subsets, versions and representations for asset_entities.
Args:
asset_entities (list): Asset entities for which want to find data
Returns:
(dict): collected entities
Example output:
```
{
{Asset ID}: {
"asset_entity": <AssetEntity>,
"subsets": {
{Subset ID}: {
"subset_entity": <SubsetEntity>,
"version": {
"version_entity": <VersionEntity>,
"repres": [
<RepreEntity1>, <RepreEntity2>, ...
]
}
},
...
}
},
...
}
output[asset_id]["subsets"][subset_id]["version"]["repres"]
```
"""

if not asset_entities:
return {}

asset_entity_by_ids = {asset["_id"]: asset for asset in asset_entities}

subsets = list(avalon.io.find({
"type": "subset",
"parent": {"$in": asset_entity_by_ids.keys()}
}))
subset_entity_by_ids = {subset["_id"]: subset for subset in subsets}

sorted_versions = list(avalon.io.find({
"type": "version",
"parent": {"$in": subset_entity_by_ids.keys()}
}).sort("name", -1))

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

repres = avalon.io.find({
"type": "representation",
"parent": {"$in": last_versions_by_id.keys()}
})

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]

if asset_id not in output:
output[asset_id] = {
"asset_entity": asset,
"subsets": {}
}

if subset_id not in output[asset_id]["subsets"]:
output[asset_id]["subsets"][subset_id] = {
"subset_entity": subset,
"version": {
"version_entity": version,
"repres": []
}
}

output[asset_id]["subsets"][subset_id]["version"]["repres"].append(
repre
)

return output


@with_avalon
def get_creator_by_name(creator_name, case_sensitive=False):
Expand Down

0 comments on commit aff4b01

Please sign in to comment.