Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load and manage products from a library project #1005

Draft
wants to merge 26 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
aaadaff
refactoring the load container so that it can load the library project
moonyuet Nov 11, 2024
e0ff639
Merge branch 'develop' into enhancement/Load-and-manage-products-from…
moonyuet Nov 11, 2024
dcb838e
resolve the project root during updating container
moonyuet Nov 11, 2024
735409f
do not get the container item from self.get_container
moonyuet Nov 12, 2024
0bec953
query the product id per project
moonyuet Nov 14, 2024
574ea35
codes clean up & make sure it supports mulitple asset loading per pro…
moonyuet Nov 15, 2024
8965a88
clean up code and add project name row into scene inventory
moonyuet Nov 18, 2024
0866c00
code tweaks - kuba's comment
moonyuet Nov 18, 2024
004e962
big roy comment - refactoring the dict per repre_id per project
moonyuet Nov 18, 2024
3078ba2
kuba's comment - add current project name as argument in the get_cont…
moonyuet Nov 19, 2024
d9c1a29
loading the asset per repre_id and per project
moonyuet Nov 21, 2024
ec56335
Merge branch 'develop' into enhancement/Load-and-manage-products-from…
moonyuet Nov 21, 2024
7a22491
remove unused variable
moonyuet Nov 21, 2024
a70135b
implement switch and set version by repre_id/product_id per project
moonyuet Nov 21, 2024
77e5317
remove unused variable
moonyuet Nov 21, 2024
e625901
big roy's comment - code tweak
moonyuet Nov 22, 2024
7edc759
remove unused variables
iLLiCiTiT Nov 22, 2024
ef26dc2
added empty lines for readability
iLLiCiTiT Nov 22, 2024
7935ed3
site sync expects project name
iLLiCiTiT Nov 22, 2024
b25715e
use project name in site sync calls
iLLiCiTiT Nov 22, 2024
a30698e
refactor view codebase
iLLiCiTiT Nov 22, 2024
562f2ed
site sync is fully project specific
iLLiCiTiT Nov 22, 2024
eea31b6
don't slow down project name getter
iLLiCiTiT Nov 22, 2024
e21c7a1
use project name to get correct status icons
iLLiCiTiT Nov 22, 2024
87907b5
fix switch version
iLLiCiTiT Nov 22, 2024
b28f4b0
comment out unused variables
iLLiCiTiT Nov 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions client/ayon_core/pipeline/load/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def update_container(container, version=-1):
from ayon_core.pipeline import get_current_project_name

# Compute the different version from 'representation'
project_name = get_current_project_name()
project_name = container.get("project_name", get_current_project_name())
repre_id = container["representation"]
if not _is_valid_representation_id(repre_id):
raise ValueError(
Expand Down Expand Up @@ -542,9 +542,6 @@ def update_container(container, version=-1):
)
)

path = get_representation_path(new_representation)
if not path or not os.path.exists(path):
raise ValueError("Path {} doesn't exist".format(path))
project_entity = ayon_api.get_project(project_name)
context = {
"project": project_entity,
Expand All @@ -553,6 +550,9 @@ def update_container(container, version=-1):
"version": new_version,
"representation": new_representation,
}
path = get_representation_path_from_context(context)
if not path or not os.path.exists(path):
raise ValueError("Path {} doesn't exist".format(path))

return Loader().update(container, context)

Expand Down Expand Up @@ -588,7 +588,7 @@ def switch_container(container, representation, loader_plugin=None):
)

# Get the new representation to switch to
project_name = get_current_project_name()
project_name = container.get("project_name", get_current_project_name())

context = get_representation_context(
project_name, representation["id"]
Expand Down
9 changes: 5 additions & 4 deletions client/ayon_core/tools/sceneinventory/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,14 @@ def get_container_items(self):
def get_container_items_by_id(self, item_ids):
return self._containers_model.get_container_items_by_id(item_ids)

def get_representation_info_items(self, representation_ids):
def get_representation_info_items(self, project_name, representation_ids):
return self._containers_model.get_representation_info_items(
representation_ids
project_name, representation_ids
)

def get_version_items(self, product_ids):
return self._containers_model.get_version_items(product_ids)
def get_version_items(self, project_name, product_ids):
return self._containers_model.get_version_items(
project_name, product_ids)

# Site Sync methods
def is_sitesync_enabled(self):
Expand Down
250 changes: 131 additions & 119 deletions client/ayon_core/tools/sceneinventory/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
# This value hold unique value of container that should be used to identify
# containers inbetween refresh.
ITEM_UNIQUE_NAME_ROLE = QtCore.Qt.UserRole + 24
PROJECT_NAME_ROLE = QtCore.Qt.UserRole + 25


class InventoryModel(QtGui.QStandardItemModel):
Expand All @@ -52,6 +53,7 @@ class InventoryModel(QtGui.QStandardItemModel):
"Object name",
"Active site",
"Remote site",
"Project",
]
name_col = column_labels.index("Name")
version_col = column_labels.index("Version")
Expand All @@ -63,6 +65,7 @@ class InventoryModel(QtGui.QStandardItemModel):
object_name_col = column_labels.index("Object name")
active_site_col = column_labels.index("Active site")
remote_site_col = column_labels.index("Remote site")
project_col = column_labels.index("Project")
display_role_by_column = {
name_col: QtCore.Qt.DisplayRole,
version_col: VERSION_LABEL_ROLE,
Expand All @@ -72,6 +75,7 @@ class InventoryModel(QtGui.QStandardItemModel):
product_group_col: PRODUCT_GROUP_NAME_ROLE,
loader_col: LOADER_NAME_ROLE,
object_name_col: OBJECT_NAME_ROLE,
project_col: PROJECT_NAME_ROLE,
active_site_col: ACTIVE_SITE_PROGRESS_ROLE,
remote_site_col: REMOTE_SITE_PROGRESS_ROLE,
}
Expand All @@ -85,7 +89,7 @@ class InventoryModel(QtGui.QStandardItemModel):
foreground_role_by_column = {
name_col: NAME_COLOR_ROLE,
version_col: VERSION_COLOR_ROLE,
status_col: STATUS_COLOR_ROLE
status_col: STATUS_COLOR_ROLE,
}
width_by_column = {
name_col: 250,
Expand All @@ -95,6 +99,7 @@ class InventoryModel(QtGui.QStandardItemModel):
product_type_col: 150,
product_group_col: 120,
loader_col: 150,
project_col: 150,
}

OUTDATED_COLOR = QtGui.QColor(235, 30, 30)
Expand Down Expand Up @@ -126,32 +131,39 @@ def refresh(self, selected=None):
"""Refresh the model"""
# for debugging or testing, injecting items from outside
container_items = self._controller.get_container_items()

self._clear_items()

items_by_repre_id = {}
for container_item in container_items:
repre_id = set()
moonyuet marked this conversation as resolved.
Show resolved Hide resolved
version_items_by_product_id = collections.defaultdict(dict)
repre_info_by_id_by_project = collections.defaultdict(list)
item_by_repre_id_by_project_id = collections.defaultdict(
lambda: collections.defaultdict(set))
for project_name, container_item in container_items.items():
# if (
# selected is not None
# and container_item.item_id not in selected
# ):
# continue
repre_id = container_item.representation_id
items = items_by_repre_id.setdefault(repre_id, [])
items.append(container_item)
for item in container_item.values():
representation_id = item.representation_id
if item.project_name != project_name:
continue
repre_id.add(representation_id)
item_by_repre_id_by_project_id[project_name][representation_id].add(item)
repre_info = self._controller.get_representation_info_items(
project_name, repre_id
)
repre_info_by_id_by_project[project_name] = repre_info

product_ids = {
repre_info.product_id
for repre_info in repre_info.values()
if repre_info.is_valid
}
version_items = self._controller.get_version_items(
project_name, product_ids
)
version_items_by_product_id[project_name] = version_items

repre_id = set(items_by_repre_id.keys())
repre_info_by_id = self._controller.get_representation_info_items(
repre_id
)
product_ids = {
repre_info.product_id
for repre_info in repre_info_by_id.values()
if repre_info.is_valid
}
version_items_by_product_id = self._controller.get_version_items(
product_ids
)
# SiteSync addon information
progress_by_id = self._controller.get_representations_site_progress(
repre_id
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we may want to open an issue AFTER this PR that technically the statuses may differ per project - and hence below get_project_status_items may need to also be accounted for PER project. @iLLiCiTiT thoughts?

Expand Down Expand Up @@ -192,113 +204,113 @@ def refresh(self, selected=None):

root_item = self.invisibleRootItem()
group_items = []
for repre_id, container_items in items_by_repre_id.items():
repre_info = repre_info_by_id[repre_id]
version_color = None
if not repre_info.is_valid:
version_label = "N/A"
group_name = "< Entity N/A >"
item_icon = invalid_item_icon
is_latest = False
is_hero = False
status_name = None

else:
group_name = "{}_{}: ({})".format(
repre_info.folder_path.rsplit("/")[-1],
repre_info.product_name,
repre_info.representation_name
for project_name, items_by_repre_id in item_by_repre_id_by_project_id.items():
for repre_id, container_items in items_by_repre_id.items():
repre_info = repre_info_by_id_by_project[project_name][repre_id]
version_color = None
if not repre_info.is_valid:
version_label = "N/A"
group_name = "< Entity N/A >"
item_icon = invalid_item_icon
is_latest = False
is_hero = False
status_name = None

else:
group_name = "{}_{}: ({})".format(
repre_info.folder_path.rsplit("/")[-1],
repre_info.product_name,
repre_info.representation_name
)
item_icon = valid_item_icon

version_items = (
version_items_by_product_id[project_name][repre_info.product_id]
)
version_item = version_items[repre_info.version_id]
version_label = format_version(version_item.version)
is_hero = version_item.version < 0
is_latest = version_item.is_latest
if not version_item.is_latest:
version_color = self.OUTDATED_COLOR
status_name = version_item.status

status_color, status_short, status_icon = self._get_status_data(
status_name
)
item_icon = valid_item_icon

version_items = (
version_items_by_product_id[repre_info.product_id]
repre_name = (
repre_info.representation_name or "<unknown representation>"
)
container_model_items = []
for container_item in container_items:
object_name = container_item.object_name or "<none>"
unique_name = repre_name + object_name
item = QtGui.QStandardItem()
item.setColumnCount(root_item.columnCount())
item.setData(container_item.namespace, QtCore.Qt.DisplayRole)
item.setData(self.GRAYOUT_COLOR, NAME_COLOR_ROLE)
item.setData(self.GRAYOUT_COLOR, VERSION_COLOR_ROLE)
item.setData(item_icon, QtCore.Qt.DecorationRole)
item.setData(repre_info.product_id, PRODUCT_ID_ROLE)
item.setData(container_item.item_id, ITEM_ID_ROLE)
item.setData(version_label, VERSION_LABEL_ROLE)
item.setData(container_item.loader_name, LOADER_NAME_ROLE)
item.setData(container_item.object_name, OBJECT_NAME_ROLE)
item.setData(container_item.project_name, PROJECT_NAME_ROLE)
item.setData(True, IS_CONTAINER_ITEM_ROLE)
item.setData(unique_name, ITEM_UNIQUE_NAME_ROLE)
container_model_items.append(item)
if not container_model_items:
continue

progress = progress_by_id[repre_id]
active_site_progress = "{}%".format(
max(progress["active_site"], 0) * 100
)
remote_site_progress = "{}%".format(
max(progress["remote_site"], 0) * 100
)
version_item = version_items[repre_info.version_id]
version_label = format_version(version_item.version)
is_hero = version_item.version < 0
is_latest = version_item.is_latest
if not version_item.is_latest:
version_color = self.OUTDATED_COLOR
status_name = version_item.status

status_color, status_short, status_icon = self._get_status_data(
status_name
)

repre_name = (
repre_info.representation_name or "<unknown representation>"
)
container_model_items = []
for container_item in container_items:
object_name = container_item.object_name or "<none>"
unique_name = repre_name + object_name

item = QtGui.QStandardItem()
item.setColumnCount(root_item.columnCount())
item.setData(container_item.namespace, QtCore.Qt.DisplayRole)
item.setData(self.GRAYOUT_COLOR, NAME_COLOR_ROLE)
item.setData(self.GRAYOUT_COLOR, VERSION_COLOR_ROLE)
item.setData(item_icon, QtCore.Qt.DecorationRole)
item.setData(repre_info.product_id, PRODUCT_ID_ROLE)
item.setData(container_item.item_id, ITEM_ID_ROLE)
item.setData(version_label, VERSION_LABEL_ROLE)
item.setData(container_item.loader_name, LOADER_NAME_ROLE)
item.setData(container_item.object_name, OBJECT_NAME_ROLE)
item.setData(True, IS_CONTAINER_ITEM_ROLE)
item.setData(unique_name, ITEM_UNIQUE_NAME_ROLE)
container_model_items.append(item)

if not container_model_items:
continue

progress = progress_by_id[repre_id]
active_site_progress = "{}%".format(
max(progress["active_site"], 0) * 100
)
remote_site_progress = "{}%".format(
max(progress["remote_site"], 0) * 100
)

group_item = QtGui.QStandardItem()
group_item.setColumnCount(root_item.columnCount())
group_item.setData(group_name, QtCore.Qt.DisplayRole)
group_item.setData(group_name, ITEM_UNIQUE_NAME_ROLE)
group_item.setData(group_item_icon, QtCore.Qt.DecorationRole)
group_item.setData(group_item_font, QtCore.Qt.FontRole)
group_item.setData(repre_info.product_id, PRODUCT_ID_ROLE)
group_item.setData(repre_info.product_type, PRODUCT_TYPE_ROLE)
group_item.setData(product_type_icon, PRODUCT_TYPE_ICON_ROLE)
group_item.setData(is_latest, VERSION_IS_LATEST_ROLE)
group_item.setData(is_hero, VERSION_IS_HERO_ROLE)
group_item.setData(version_label, VERSION_LABEL_ROLE)
group_item.setData(len(container_items), COUNT_ROLE)
group_item.setData(status_name, STATUS_NAME_ROLE)
group_item.setData(status_short, STATUS_SHORT_ROLE)
group_item.setData(status_color, STATUS_COLOR_ROLE)
group_item.setData(status_icon, STATUS_ICON_ROLE)

group_item.setData(
active_site_progress, ACTIVE_SITE_PROGRESS_ROLE
)
group_item.setData(
remote_site_progress, REMOTE_SITE_PROGRESS_ROLE
)
group_item.setData(active_site_icon, ACTIVE_SITE_ICON_ROLE)
group_item.setData(remote_site_icon, REMOTE_SITE_ICON_ROLE)
group_item.setData(False, IS_CONTAINER_ITEM_ROLE)

if version_color is not None:
group_item.setData(version_color, VERSION_COLOR_ROLE)
group_item = QtGui.QStandardItem()
group_item.setColumnCount(root_item.columnCount())
group_item.setData(group_name, QtCore.Qt.DisplayRole)
group_item.setData(group_name, ITEM_UNIQUE_NAME_ROLE)
group_item.setData(group_item_icon, QtCore.Qt.DecorationRole)
group_item.setData(group_item_font, QtCore.Qt.FontRole)
group_item.setData(repre_info.product_id, PRODUCT_ID_ROLE)
group_item.setData(repre_info.product_type, PRODUCT_TYPE_ROLE)
group_item.setData(product_type_icon, PRODUCT_TYPE_ICON_ROLE)
group_item.setData(is_latest, VERSION_IS_LATEST_ROLE)
group_item.setData(is_hero, VERSION_IS_HERO_ROLE)
group_item.setData(version_label, VERSION_LABEL_ROLE)
group_item.setData(len(container_items), COUNT_ROLE)
group_item.setData(status_name, STATUS_NAME_ROLE)
group_item.setData(status_short, STATUS_SHORT_ROLE)
group_item.setData(status_color, STATUS_COLOR_ROLE)
group_item.setData(status_icon, STATUS_ICON_ROLE)

if repre_info.product_group:
group_item.setData(
repre_info.product_group, PRODUCT_GROUP_NAME_ROLE
active_site_progress, ACTIVE_SITE_PROGRESS_ROLE
)
group_item.setData(
remote_site_progress, REMOTE_SITE_PROGRESS_ROLE
)
group_item.setData(group_icon, PRODUCT_GROUP_ICON_ROLE)
group_item.setData(active_site_icon, ACTIVE_SITE_ICON_ROLE)
group_item.setData(remote_site_icon, REMOTE_SITE_ICON_ROLE)
group_item.setData(False, IS_CONTAINER_ITEM_ROLE)

if version_color is not None:
group_item.setData(version_color, VERSION_COLOR_ROLE)

if repre_info.product_group:
group_item.setData(
repre_info.product_group, PRODUCT_GROUP_NAME_ROLE
)
group_item.setData(group_icon, PRODUCT_GROUP_ICON_ROLE)

group_item.appendRows(container_model_items)
group_items.append(group_item)
group_item.appendRows(container_model_items)
group_items.append(group_item)

if group_items:
root_item.appendRows(group_items)
Expand Down
Loading