scene inventory is using representation entity

This commit is contained in:
Jakub Trllo 2024-03-08 12:36:25 +01:00
parent 3a5becbc98
commit 3467727f11
5 changed files with 533 additions and 602 deletions

View file

@ -1,9 +1,7 @@
import numbers
from ayon_core.client import (
get_versions,
get_hero_versions,
)
import ayon_api
from ayon_core.pipeline import HeroVersionType
from ayon_core.tools.utils.models import TreeModel
from ayon_core.tools.utils.lib import format_version
@ -27,7 +25,7 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
def displayText(self, value, locale):
if isinstance(value, HeroVersionType):
return format_version(value, True)
return format_version(value)
if not isinstance(value, numbers.Integral):
# For cases where no version is resolved like NOT FOUND cases
# where a representation might not exist in current database
@ -113,71 +111,35 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
# Current value of the index
item = index.data(TreeModel.ItemRole)
value = index.data(QtCore.Qt.DisplayRole)
if item["version_document"]["type"] != "hero_version":
assert isinstance(value, numbers.Integral), (
"Version is not integer"
)
project_name = self.get_project_name()
# Add all available versions to the editor
parent_id = item["version_document"]["parent"]
version_docs = [
version_doc
for version_doc in sorted(
get_versions(project_name, subset_ids=[parent_id]),
key=lambda item: item["name"]
)
if version_doc["data"].get("active", True)
]
hero_versions = list(
get_hero_versions(
project_name,
subset_ids=[parent_id],
fields=["name", "data.tags", "version_id"]
)
)
hero_version_doc = None
if hero_versions:
hero_version_doc = hero_versions[0]
doc_for_hero_version = None
product_id = item["version_entity"]["productId"]
version_entities = list(sorted(
ayon_api.get_versions(
project_name, product_ids={product_id}, active=True
),
key=lambda item: abs(item["version"])
))
selected = None
items = []
for version_doc in version_docs:
version_tags = version_doc["data"].get("tags") or []
if "deleted" in version_tags:
continue
is_hero_version = value < 0
for version_entity in version_entities:
version = version_entity["version"]
label = format_version(version)
item = QtGui.QStandardItem(label)
item.setData(version_entity, QtCore.Qt.UserRole)
items.append(item)
if (
hero_version_doc
and doc_for_hero_version is None
and hero_version_doc["version_id"] == version_doc["_id"]
version == value
or is_hero_version and version < 0
):
doc_for_hero_version = version_doc
label = format_version(version_doc["name"])
item = QtGui.QStandardItem(label)
item.setData(version_doc, QtCore.Qt.UserRole)
items.append(item)
if version_doc["name"] == value:
selected = item
if hero_version_doc and doc_for_hero_version:
version_name = doc_for_hero_version["name"]
label = format_version(version_name, True)
if isinstance(value, HeroVersionType):
index = len(version_docs)
hero_version_doc["name"] = HeroVersionType(version_name)
item = QtGui.QStandardItem(label)
item.setData(hero_version_doc, QtCore.Qt.UserRole)
items.append(item)
# Reverse items so latest versions be upper
items = list(reversed(items))
items.reverse()
for item in items:
editor.model().appendRow(item)

View file

@ -1,24 +1,15 @@
import collections
import re
import logging
import uuid
import copy
from collections import defaultdict
import ayon_api
from qtpy import QtCore, QtGui
import qtawesome
from ayon_core.client import (
get_assets,
get_subsets,
get_versions,
get_last_version_by_subset_id,
get_representations,
)
from ayon_core.pipeline import (
get_current_project_name,
schema,
HeroVersionType,
)
from ayon_core.style import get_default_entity_icon_color
@ -249,29 +240,29 @@ class InventoryModel(TreeModel):
not_found_ids.append(repre_id)
continue
version = versions_by_id.get(representation["parent"])
if not version:
version_entity = versions_by_id.get(representation["versionId"])
if not version_entity:
not_found["version"].extend(group_containers)
not_found_ids.append(repre_id)
continue
product = products_by_id.get(version["parent"])
if not product:
product_entity = products_by_id.get(version_entity["productId"])
if not product_entity:
not_found["product"].extend(group_containers)
not_found_ids.append(repre_id)
continue
folder = folders_by_id.get(product["parent"])
if not folder:
folder_entity = folders_by_id.get(product_entity["folderId"])
if not folder_entity:
not_found["folder"].extend(group_containers)
not_found_ids.append(repre_id)
continue
group_dict.update({
"representation": representation,
"version": version,
"subset": product,
"asset": folder
"version": version_entity,
"product": product_entity,
"folder": folder_entity
})
for _repre_id in not_found_ids:
@ -308,43 +299,34 @@ class InventoryModel(TreeModel):
for repre_id, group_dict in sorted(grouped.items()):
group_containers = group_dict["containers"]
representation = group_dict["representation"]
version = group_dict["version"]
subset = group_dict["subset"]
asset = group_dict["asset"]
repre_entity = group_dict["representation"]
version_entity = group_dict["version"]
folder_entity = group_dict["folder"]
product_entity = group_dict["product"]
# Get product type
maj_version, _ = schema.get_schema_version(subset["schema"])
if maj_version < 3:
src_doc = version
else:
src_doc = subset
product_type = src_doc["data"].get("family")
if not product_type:
families = src_doc["data"].get("families")
if families:
product_type = families[0]
product_type = product_entity["productType"]
# Store the highest available version so the model can know
# whether current version is currently up-to-date.
highest_version = get_last_version_by_subset_id(
project_name, version["parent"]
highest_version = ayon_api.get_last_version_by_product_id(
project_name, version_entity["productId"]
)
# create the group header
group_node = Item()
group_node["Name"] = "{}_{}: ({})".format(
asset["name"], subset["name"], representation["name"]
folder_entity["name"],
product_entity["name"],
repre_entity["name"]
)
group_node["representation"] = repre_id
group_node["version"] = version["name"]
group_node["highest_version"] = highest_version["name"]
group_node["version"] = version_entity["version"]
group_node["highest_version"] = highest_version["version"]
group_node["productType"] = product_type or ""
group_node["productTypeIcon"] = product_type_icon
group_node["count"] = len(group_containers)
group_node["isGroupNode"] = True
group_node["group"] = subset["data"].get("subsetGroup")
group_node["group"] = product_entity["attrib"].get("productGroup")
# Site sync specific data
progress = progress_by_id[repre_id]
@ -359,7 +341,8 @@ class InventoryModel(TreeModel):
item_node.update(container)
# store the current version on the item
item_node["version"] = version["name"]
item_node["version"] = version_entity["version"]
item_node["version_entity"] = version_entity
# Remapping namespace to item name.
# Noted that the name key is capital "N", by doing this, we
@ -404,73 +387,50 @@ class InventoryModel(TreeModel):
if not filtered_repre_ids:
return output
repre_docs = get_representations(project_name, repre_ids)
repre_entities = ayon_api.get_representations(project_name, repre_ids)
repres_by_id.update({
repre_doc["_id"]: repre_doc
for repre_doc in repre_docs
repre_entity["id"]: repre_entity
for repre_entity in repre_entities
})
version_ids = {
repre_doc["parent"] for repre_doc in repres_by_id.values()
repre_entity["versionId"]
for repre_entity in repres_by_id.values()
}
if not version_ids:
return output
version_docs = get_versions(project_name, version_ids, hero=True)
versions_by_id.update({
version_doc["_id"]: version_doc
for version_doc in version_docs
})
hero_versions_by_subversion_id = collections.defaultdict(list)
for version_doc in versions_by_id.values():
if version_doc["type"] != "hero_version":
continue
subversion = version_doc["version_id"]
hero_versions_by_subversion_id[subversion].append(version_doc)
if hero_versions_by_subversion_id:
subversion_ids = set(
hero_versions_by_subversion_id.keys()
version_entity["id"]: version_entity
for version_entity in ayon_api.get_versions(
project_name, version_ids=version_ids
)
subversion_docs = get_versions(project_name, subversion_ids)
for subversion_doc in subversion_docs:
subversion_id = subversion_doc["_id"]
subversion_ids.discard(subversion_id)
h_version_docs = hero_versions_by_subversion_id[subversion_id]
for version_doc in h_version_docs:
version_doc["name"] = HeroVersionType(
subversion_doc["name"]
)
version_doc["data"] = copy.deepcopy(
subversion_doc["data"]
)
for subversion_id in subversion_ids:
h_version_docs = hero_versions_by_subversion_id[subversion_id]
for version_doc in h_version_docs:
versions_by_id.pop(version_doc["_id"])
})
product_ids = {
version_doc["parent"]
for version_doc in versions_by_id.values()
version_entity["productId"]
for version_entity in versions_by_id.values()
}
if not product_ids:
return output
product_docs = get_subsets(project_name, product_ids)
products_by_id.update({
product_doc["_id"]: product_doc
for product_doc in product_docs
product_entity["id"]: product_entity
for product_entity in ayon_api.get_products(
project_name, product_ids=product_ids
)
})
folder_ids = {
product_doc["parent"]
for product_doc in products_by_id.values()
product_entity["folderId"]
for product_entity in products_by_id.values()
}
if not folder_ids:
return output
folder_docs = get_assets(project_name, folder_ids)
folders_by_id.update({
folder_doc["_id"]: folder_doc
for folder_doc in folder_docs
folder_entity["id"]: folder_entity
for folder_entity in ayon_api.get_folders(
project_name, folder_ids=folder_ids
)
})
return output

View file

@ -1,4 +1,5 @@
from ayon_core.client import get_representations
import ayon_api
from ayon_core.addon import AddonsManager
NOT_SET = object()
@ -69,14 +70,16 @@ class SiteSyncModel:
project_name = self._controller.get_current_project_name()
site_sync = self._get_sync_server_module()
repre_docs = get_representations(project_name, representation_ids)
repre_entities = ayon_api.get_representations(
project_name, representation_ids
)
active_site = self._get_active_site()
remote_site = self._get_remote_site()
for repre_doc in repre_docs:
repre_output = output[repre_doc["_id"]]
for repre_entity in repre_entities:
repre_output = output[repre_entity["id"]]
result = site_sync.get_progress_for_repre(
repre_doc, active_site, remote_site
repre_entity, active_site, remote_site
)
repre_output["active_site"] = result[active_site]
repre_output["remote_site"] = result[remote_site]

File diff suppressed because it is too large Load diff

View file

@ -4,16 +4,10 @@ import logging
import itertools
from functools import partial
import ayon_api
from qtpy import QtWidgets, QtCore
import qtawesome
from ayon_core.client import (
get_version_by_id,
get_versions,
get_hero_versions,
get_representation_by_id,
get_representations,
)
from ayon_core import style
from ayon_core.pipeline import (
HeroVersionType,
@ -97,50 +91,54 @@ class SceneInventoryView(QtWidgets.QTreeView):
pass
project_name = self._controller.get_current_project_name()
repre_docs = get_representations(
project_name, representation_ids=repre_ids, fields=["parent"]
repre_entities = ayon_api.get_representations(
project_name,
representation_ids=repre_ids,
fields={"versionId"}
)
version_ids = {
repre_doc["parent"]
for repre_doc in repre_docs
repre_entity["versionId"]
for repre_entity in repre_entities
}
loaded_versions = get_versions(
project_name, version_ids=version_ids, hero=True
loaded_versions = ayon_api.get_versions(
project_name, version_ids=version_ids
)
loaded_hero_versions = []
versions_by_parent_id = collections.defaultdict(list)
versions_by_product_id = collections.defaultdict(list)
product_ids = set()
for version in loaded_versions:
if version["type"] == "hero_version":
loaded_hero_versions.append(version)
for version_entity in loaded_versions:
version = version_entity["version"]
if version < 0:
loaded_hero_versions.append(version_entity)
else:
parent_id = version["parent"]
versions_by_parent_id[parent_id].append(version)
product_ids.add(parent_id)
product_id = version_entity["productId"]
versions_by_product_id[product_id].append(version_entity)
product_ids.add(product_id)
all_versions = get_versions(
project_name, subset_ids=product_ids, hero=True
all_versions = ayon_api.get_versions(
project_name, product_ids=product_ids
)
hero_versions = []
versions = []
for version in all_versions:
if version["type"] == "hero_version":
hero_versions.append(version)
version_entities = []
for version_entity in all_versions:
version = version_entity["version"]
if version < 0:
hero_versions.append(version_entity)
else:
versions.append(version)
version_entities.append(version_entity)
has_loaded_hero_versions = len(loaded_hero_versions) > 0
has_available_hero_version = len(hero_versions) > 0
has_outdated = False
for version in versions:
parent_id = version["parent"]
current_versions = versions_by_parent_id[parent_id]
for version_entity in version_entities:
product_id = version_entity["productId"]
current_versions = versions_by_product_id[product_id]
for current_version in current_versions:
if current_version["name"] < version["name"]:
if current_version["version"] < version_entity["version"]:
has_outdated = True
break
@ -155,46 +153,51 @@ class SceneInventoryView(QtWidgets.QTreeView):
for item in items
}
repre_docs = get_representations(
repre_entities = ayon_api.get_representations(
project_name,
representation_ids=repre_ids,
fields=["parent"]
fields={"id", "versionId"}
)
version_ids = set()
version_id_by_repre_id = {}
for repre_doc in repre_docs:
version_id = repre_doc["parent"]
repre_id = str(repre_doc["_id"])
for repre_entity in repre_entities:
repre_id = repre_entity["id"]
version_id = repre_entity["versionId"]
version_id_by_repre_id[repre_id] = version_id
version_ids.add(version_id)
version_ids = set(version_id_by_repre_id.values())
hero_versions = get_hero_versions(
project_name,
version_ids=version_ids,
fields=["version_id"]
src_version_entity_by_id = {
version_entity["id"]: version_entity
for version_entity in ayon_api.get_versions(
project_name,
version_ids,
fields={"productId", "version"}
)
}
hero_versions_by_product_id = {}
for version_entity in src_version_entity_by_id.values():
version = version_entity["version"]
if version < 0:
product_id = version_entity["productId"]
hero_versions_by_product_id[product_id] = abs(version)
if not hero_versions_by_product_id:
return
standard_versions = ayon_api.get_versions(
product_ids=hero_versions_by_product_id.keys(),
versions=hero_versions_by_product_id.values()
)
hero_src_version_ids = set()
for hero_version in hero_versions:
version_id = hero_version["version_id"]
hero_src_version_ids.add(version_id)
hero_version_id = hero_version["_id"]
for _repre_id, current_version_id in (
version_id_by_repre_id.items()
):
if current_version_id == hero_version_id:
version_id_by_repre_id[_repre_id] = version_id
version_docs = get_versions(
project_name,
version_ids=hero_src_version_ids,
fields=["name"]
)
version_name_by_id = {}
for version_doc in version_docs:
version_name_by_id[version_doc["_id"]] = \
version_doc["name"]
standard_version_by_product_id = {
product_id: {}
for product_id in hero_versions_by_product_id.keys()
}
for version_entity in standard_versions:
product_id = version_entity["productId"]
version = version_entity["version"]
standard_version_by_product_id[product_id][version] = (
version_entity
)
# Specify version per item to update to
update_items = []
@ -202,10 +205,20 @@ class SceneInventoryView(QtWidgets.QTreeView):
for item in items:
repre_id = item["representation"]
version_id = version_id_by_repre_id.get(repre_id)
version_name = version_name_by_id.get(version_id)
if version_name is not None:
version_entity = src_version_entity_by_id.get(version_id)
if not version_entity or version_entity["version"] >= 0:
continue
product_id = version_entity["productId"]
version_entities_by_version = (
standard_version_by_product_id[product_id]
)
new_version = hero_versions_by_product_id.get(product_id)
new_version_entity = version_entities_by_version.get(
new_version
)
if new_version_entity is not None:
update_items.append(item)
update_versions.append(version_name)
update_versions.append(new_version)
self._update_containers(update_items, update_versions)
update_icon = qtawesome.icon(
@ -249,8 +262,9 @@ class SceneInventoryView(QtWidgets.QTreeView):
menu
)
change_to_hero.triggered.connect(
lambda: self._update_containers(items,
version=HeroVersionType(-1))
lambda: self._update_containers(
items, version=HeroVersionType(-1)
)
)
# set version
@ -608,44 +622,31 @@ class SceneInventoryView(QtWidgets.QTreeView):
project_name = self._controller.get_current_project_name()
# Get available versions for active representation
repre_doc = get_representation_by_id(
repre_entity = ayon_api.get_representation_by_id(
project_name,
active["representation"],
fields=["parent"]
fields={"versionId"}
)
repre_version_doc = get_version_by_id(
repre_version_entity = ayon_api.get_version_by_id(
project_name,
repre_doc["parent"],
fields=["parent"]
repre_entity["versionId"],
fields={"productId"}
)
version_docs = list(get_versions(
version_entities = list(ayon_api.get_versions(
project_name,
subset_ids=[repre_version_doc["parent"]],
hero=True
product_ids={repre_version_entity["productId"]},
))
hero_version = None
standard_versions = []
for version_doc in version_docs:
if version_doc["type"] == "hero_version":
hero_version = version_doc
for version_entity in version_entities:
if version_entity["version"] < 0:
hero_version = version_entity
else:
standard_versions.append(version_doc)
versions = list(reversed(
sorted(standard_versions, key=lambda item: item["name"])
))
if hero_version:
_version_id = hero_version["version_id"]
for _version in versions:
if _version["_id"] != _version_id:
continue
hero_version["name"] = HeroVersionType(
_version["name"]
)
hero_version["data"] = _version["data"]
break
standard_versions.append(version_entity)
standard_versions.sort(key=lambda item: item["version"])
standard_versions.reverse()
# Get index among the listed versions
current_item = None
@ -653,15 +654,15 @@ class SceneInventoryView(QtWidgets.QTreeView):
if isinstance(current_version, HeroVersionType):
current_item = hero_version
else:
for version in versions:
if version["name"] == current_version:
current_item = version
for version_entity in standard_versions:
if version_entity["version"] == current_version:
current_item = version_entity
break
all_versions = []
if hero_version:
all_versions.append(hero_version)
all_versions.extend(versions)
all_versions.extend(standard_versions)
if current_item:
index = all_versions.index(current_item)
@ -670,11 +671,10 @@ class SceneInventoryView(QtWidgets.QTreeView):
versions_by_label = dict()
labels = []
for version in all_versions:
is_hero = version["type"] == "hero_version"
label = format_version(version["name"], is_hero)
for version_entity in all_versions:
label = format_version(version_entity["version"])
labels.append(label)
versions_by_label[label] = version["name"]
versions_by_label[label] = version_entity["version"]
label, state = QtWidgets.QInputDialog.getItem(
self,
@ -689,6 +689,8 @@ class SceneInventoryView(QtWidgets.QTreeView):
if label:
version = versions_by_label[label]
if version < 0:
version = HeroVersionType(version)
self._update_containers(items, version)
def _show_switch_dialog(self, items):