mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
[Automated] Merged develop into main
This commit is contained in:
commit
9266439d3c
48 changed files with 3363 additions and 1158 deletions
71
openpype/client/__init__.py
Normal file
71
openpype/client/__init__.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
from .entities import (
|
||||
get_projects,
|
||||
get_project,
|
||||
|
||||
get_asset_by_id,
|
||||
get_asset_by_name,
|
||||
get_assets,
|
||||
get_asset_ids_with_subsets,
|
||||
|
||||
get_subset_by_id,
|
||||
get_subset_by_name,
|
||||
get_subsets,
|
||||
get_subset_families,
|
||||
|
||||
get_version_by_id,
|
||||
get_version_by_name,
|
||||
get_versions,
|
||||
get_hero_version_by_id,
|
||||
get_hero_version_by_subset_id,
|
||||
get_hero_versions,
|
||||
get_last_versions,
|
||||
get_last_version_by_subset_id,
|
||||
get_last_version_by_subset_name,
|
||||
get_output_link_versions,
|
||||
|
||||
get_representation_by_id,
|
||||
get_representation_by_name,
|
||||
get_representations,
|
||||
get_representation_parents,
|
||||
get_representations_parents,
|
||||
|
||||
get_thumbnail,
|
||||
get_thumbnails,
|
||||
get_thumbnail_id_from_source,
|
||||
)
|
||||
|
||||
__all__ = (
|
||||
"get_projects",
|
||||
"get_project",
|
||||
|
||||
"get_asset_by_id",
|
||||
"get_asset_by_name",
|
||||
"get_assets",
|
||||
"get_asset_ids_with_subsets",
|
||||
|
||||
"get_subset_by_id",
|
||||
"get_subset_by_name",
|
||||
"get_subsets",
|
||||
"get_subset_families",
|
||||
|
||||
"get_version_by_id",
|
||||
"get_version_by_name",
|
||||
"get_versions",
|
||||
"get_hero_version_by_id",
|
||||
"get_hero_version_by_subset_id",
|
||||
"get_hero_versions",
|
||||
"get_last_versions",
|
||||
"get_last_version_by_subset_id",
|
||||
"get_last_version_by_subset_name",
|
||||
"get_output_link_versions",
|
||||
|
||||
"get_representation_by_id",
|
||||
"get_representation_by_name",
|
||||
"get_representations",
|
||||
"get_representation_parents",
|
||||
"get_representations_parents",
|
||||
|
||||
"get_thumbnail",
|
||||
"get_thumbnails",
|
||||
"get_thumbnail_id_from_source",
|
||||
)
|
||||
1663
openpype/client/entities.py
Normal file
1663
openpype/client/entities.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -10,6 +10,7 @@ from . import ops
|
|||
|
||||
import pyblish.api
|
||||
|
||||
from openpype.client import get_asset_by_name
|
||||
from openpype.pipeline import (
|
||||
schema,
|
||||
legacy_io,
|
||||
|
|
@ -83,11 +84,9 @@ def uninstall():
|
|||
|
||||
|
||||
def set_start_end_frames():
|
||||
project_name = legacy_io.active_project()
|
||||
asset_name = legacy_io.Session["AVALON_ASSET"]
|
||||
asset_doc = legacy_io.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
})
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
|
||||
scene = bpy.context.scene
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
import os
|
||||
import json
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
import bpy
|
||||
import bpy_extras
|
||||
import bpy_extras.anim_utils
|
||||
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.client import get_representation_by_name
|
||||
from openpype.hosts.blender.api import plugin
|
||||
from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY
|
||||
import openpype.api
|
||||
|
|
@ -131,43 +129,32 @@ class ExtractLayout(openpype.api.Extractor):
|
|||
|
||||
fbx_count = 0
|
||||
|
||||
project_name = instance.context.data["projectEntity"]["name"]
|
||||
for asset in asset_group.children:
|
||||
metadata = asset.get(AVALON_PROPERTY)
|
||||
|
||||
parent = metadata["parent"]
|
||||
version_id = metadata["parent"]
|
||||
family = metadata["family"]
|
||||
|
||||
self.log.debug("Parent: {}".format(parent))
|
||||
self.log.debug("Parent: {}".format(version_id))
|
||||
# Get blend reference
|
||||
blend = legacy_io.find_one(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": ObjectId(parent),
|
||||
"name": "blend"
|
||||
},
|
||||
projection={"_id": True})
|
||||
blend = get_representation_by_name(
|
||||
project_name, "blend", version_id, fields=["_id"]
|
||||
)
|
||||
blend_id = None
|
||||
if blend:
|
||||
blend_id = blend["_id"]
|
||||
# Get fbx reference
|
||||
fbx = legacy_io.find_one(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": ObjectId(parent),
|
||||
"name": "fbx"
|
||||
},
|
||||
projection={"_id": True})
|
||||
fbx = get_representation_by_name(
|
||||
project_name, "fbx", version_id, fields=["_id"]
|
||||
)
|
||||
fbx_id = None
|
||||
if fbx:
|
||||
fbx_id = fbx["_id"]
|
||||
# Get abc reference
|
||||
abc = legacy_io.find_one(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": ObjectId(parent),
|
||||
"name": "abc"
|
||||
},
|
||||
projection={"_id": True})
|
||||
abc = get_representation_by_name(
|
||||
project_name, "abc", version_id, fields=["_id"]
|
||||
)
|
||||
abc_id = None
|
||||
if abc:
|
||||
abc_id = abc["_id"]
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ def create_time_effects(otio_clip, track_item):
|
|||
otio_effect = otio.schema.TimeEffect()
|
||||
otio_effect.name = name
|
||||
otio_effect.effect_name = effect_name
|
||||
otio_effect.metadata = metadata
|
||||
otio_effect.metadata.update(metadata)
|
||||
|
||||
# add otio effect to clip effects
|
||||
otio_clip.effects.append(otio_effect)
|
||||
|
|
|
|||
|
|
@ -603,6 +603,18 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
source,
|
||||
computed_source))
|
||||
|
||||
# renderman allows nodes to have filename attribute empty while
|
||||
# you can have another incoming connection from different node.
|
||||
pxr_nodes = set()
|
||||
if cmds.pluginInfo("RenderMan_for_Maya", query=True, loaded=True):
|
||||
pxr_nodes = set(
|
||||
cmds.pluginInfo("RenderMan_for_Maya",
|
||||
query=True,
|
||||
dependNode=True)
|
||||
)
|
||||
if not source and cmds.nodeType(node) in pxr_nodes:
|
||||
self.log.info("Renderman: source is empty, skipping...")
|
||||
continue
|
||||
# We replace backslashes with forward slashes because V-Ray
|
||||
# can't handle the UDIM files with the backslashes in the
|
||||
# paths as the computed patterns
|
||||
|
|
|
|||
|
|
@ -539,7 +539,9 @@ def get_created_node_imageio_setting_legacy(nodeclass, creator, subset):
|
|||
|
||||
imageio_nodes = get_nuke_imageio_settings()["nodes"]
|
||||
required_nodes = imageio_nodes["requiredNodes"]
|
||||
override_nodes = imageio_nodes["overrideNodes"]
|
||||
|
||||
# HACK: for backward compatibility this needs to be optional
|
||||
override_nodes = imageio_nodes.get("overrideNodes", [])
|
||||
|
||||
imageio_node = None
|
||||
for node in required_nodes:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,20 @@ import nuke
|
|||
|
||||
from openpype.hosts.nuke.api import plugin
|
||||
from openpype.hosts.nuke.api.lib import (
|
||||
create_write_node, create_write_node_legacy)
|
||||
create_write_node,
|
||||
create_write_node_legacy,
|
||||
get_created_node_imageio_setting_legacy
|
||||
)
|
||||
|
||||
# HACK: just to disable still image on projects which
|
||||
# are not having anatomy imageio preset for CreateWriteStill
|
||||
# TODO: remove this code as soon as it will be obsolete
|
||||
imageio_writes = get_created_node_imageio_setting_legacy(
|
||||
"Write",
|
||||
"CreateWriteStill",
|
||||
"stillMain"
|
||||
)
|
||||
print(imageio_writes["knobs"])
|
||||
|
||||
|
||||
class CreateWriteStill(plugin.AbstractWriteRender):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
import threading
|
||||
import datetime
|
||||
import copy
|
||||
import collections
|
||||
|
||||
import ftrack_api
|
||||
|
||||
from openpype.lib import get_datetime_data
|
||||
from openpype.api import get_project_settings
|
||||
from openpype_modules.ftrack.lib import ServerAction
|
||||
|
||||
|
||||
class CreateDailyReviewSessionServerAction(ServerAction):
|
||||
"""Create daily review session object per project.
|
||||
|
||||
Action creates review sessions based on settings. Settings define if is
|
||||
action enabled and what is a template for review session name. Logic works
|
||||
in a way that if review session with the name already exists then skip
|
||||
process. If review session for current day does not exist but yesterdays
|
||||
review exists and is empty then yesterdays is renamed otherwise creates
|
||||
new review session.
|
||||
|
||||
Also contains cycle creation of dailies which is triggered each morning.
|
||||
This option must be enabled in project settings. Cycle creation is also
|
||||
checked on registration of action.
|
||||
"""
|
||||
|
||||
identifier = "create.daily.review.session"
|
||||
#: Action label.
|
||||
label = "OpenPype Admin"
|
||||
variant = "- Create Daily Review Session (Server)"
|
||||
#: Action description.
|
||||
description = "Manually create daily review session"
|
||||
role_list = {"Pypeclub", "Administrator", "Project Manager"}
|
||||
|
||||
settings_key = "create_daily_review_session"
|
||||
default_template = "{yy}{mm}{dd}"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CreateDailyReviewSessionServerAction, self).__init__(
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
self._cycle_timer = None
|
||||
self._last_cyle_time = None
|
||||
self._day_delta = datetime.timedelta(days=1)
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
"""Show action only on AssetVersions."""
|
||||
|
||||
valid_selection = False
|
||||
for ent in event["data"]["selection"]:
|
||||
# Ignore entities that are not tasks or projects
|
||||
if ent["entityType"].lower() in (
|
||||
"show", "task", "reviewsession", "assetversion"
|
||||
):
|
||||
valid_selection = True
|
||||
break
|
||||
|
||||
if not valid_selection:
|
||||
return False
|
||||
return self.valid_roles(session, entities, event)
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
project_entity = self.get_project_from_entity(entities[0], session)
|
||||
project_name = project_entity["full_name"]
|
||||
project_settings = self.get_project_settings_from_event(
|
||||
event, project_name
|
||||
)
|
||||
action_settings = self._extract_action_settings(project_settings)
|
||||
project_name_by_id = {
|
||||
project_entity["id"]: project_name
|
||||
}
|
||||
settings_by_project_id = {
|
||||
project_entity["id"]: action_settings
|
||||
}
|
||||
self._process_review_session(
|
||||
session, settings_by_project_id, project_name_by_id
|
||||
)
|
||||
return True
|
||||
|
||||
def register(self, *args, **kwargs):
|
||||
"""Override register to be able trigger """
|
||||
# Register server action as would be normally
|
||||
super(CreateDailyReviewSessionServerAction, self).register(
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
# Create threading timer which will trigger creation of report
|
||||
# at the 00:00:01 of next day
|
||||
# - callback will trigger another timer which will have 1 day offset
|
||||
now = datetime.datetime.now()
|
||||
# Create object of today morning
|
||||
today_morning = datetime.datetime(
|
||||
now.year, now.month, now.day, 0, 0, 1
|
||||
)
|
||||
# Add a day delta (to calculate next day date)
|
||||
next_day_morning = today_morning + self._day_delta
|
||||
# Calculate first delta in seconds for first threading timer
|
||||
first_delta = (next_day_morning - now).total_seconds()
|
||||
# Store cycle time which will be used to create next timer
|
||||
self._last_cyle_time = next_day_morning
|
||||
# Create timer thread
|
||||
self._cycle_timer = threading.Timer(first_delta, self._timer_callback)
|
||||
self._cycle_timer.start()
|
||||
|
||||
self._check_review_session()
|
||||
|
||||
def _timer_callback(self):
|
||||
if (
|
||||
self._cycle_timer is not None
|
||||
and self._last_cyle_time is not None
|
||||
):
|
||||
now = datetime.datetime.now()
|
||||
while self._last_cyle_time < now:
|
||||
self._last_cyle_time = self._last_cyle_time + self._day_delta
|
||||
|
||||
delay = (self._last_cyle_time - now).total_seconds()
|
||||
|
||||
self._cycle_timer = threading.Timer(delay, self._timer_callback)
|
||||
self._cycle_timer.start()
|
||||
self._check_review_session()
|
||||
|
||||
def _check_review_session(self):
|
||||
session = ftrack_api.Session(
|
||||
server_url=self.session.server_url,
|
||||
api_key=self.session.api_key,
|
||||
api_user=self.session.api_user,
|
||||
auto_connect_event_hub=False
|
||||
)
|
||||
project_entities = session.query(
|
||||
"select id, full_name from Project"
|
||||
).all()
|
||||
project_names_by_id = {
|
||||
project_entity["id"]: project_entity["full_name"]
|
||||
for project_entity in project_entities
|
||||
}
|
||||
|
||||
action_settings_by_project_id = self._get_action_settings(
|
||||
project_names_by_id
|
||||
)
|
||||
enabled_action_settings_by_project_id = {}
|
||||
for item in action_settings_by_project_id.items():
|
||||
project_id, action_settings = item
|
||||
if action_settings.get("cycle_enabled"):
|
||||
enabled_action_settings_by_project_id[project_id] = (
|
||||
action_settings
|
||||
)
|
||||
|
||||
if not enabled_action_settings_by_project_id:
|
||||
self.log.info((
|
||||
"There are no projects that have enabled"
|
||||
" cycle review sesison creation"
|
||||
))
|
||||
|
||||
else:
|
||||
self._process_review_session(
|
||||
session,
|
||||
enabled_action_settings_by_project_id,
|
||||
project_names_by_id
|
||||
)
|
||||
|
||||
session.close()
|
||||
|
||||
def _process_review_session(
|
||||
self, session, settings_by_project_id, project_names_by_id
|
||||
):
|
||||
review_sessions = session.query((
|
||||
"select id, name, project_id"
|
||||
" from ReviewSession where project_id in ({})"
|
||||
).format(self.join_query_keys(settings_by_project_id))).all()
|
||||
|
||||
review_sessions_by_project_id = collections.defaultdict(list)
|
||||
for review_session in review_sessions:
|
||||
project_id = review_session["project_id"]
|
||||
review_sessions_by_project_id[project_id].append(review_session)
|
||||
|
||||
# Prepare fill data for today's review sesison and yesterdays
|
||||
now = datetime.datetime.now()
|
||||
today_obj = datetime.datetime(
|
||||
now.year, now.month, now.day, 0, 0, 0
|
||||
)
|
||||
yesterday_obj = today_obj - self._day_delta
|
||||
|
||||
today_fill_data = get_datetime_data(today_obj)
|
||||
yesterday_fill_data = get_datetime_data(yesterday_obj)
|
||||
|
||||
# Loop through projects and try to create daily reviews
|
||||
for project_id, action_settings in settings_by_project_id.items():
|
||||
review_session_template = (
|
||||
action_settings["review_session_template"]
|
||||
).strip() or self.default_template
|
||||
|
||||
today_project_fill_data = copy.deepcopy(today_fill_data)
|
||||
yesterday_project_fill_data = copy.deepcopy(yesterday_fill_data)
|
||||
project_name = project_names_by_id[project_id]
|
||||
today_project_fill_data["project_name"] = project_name
|
||||
yesterday_project_fill_data["project_name"] = project_name
|
||||
|
||||
today_session_name = self._fill_review_template(
|
||||
review_session_template, today_project_fill_data
|
||||
)
|
||||
yesterday_session_name = self._fill_review_template(
|
||||
review_session_template, yesterday_project_fill_data
|
||||
)
|
||||
# Skip if today's session name could not be filled
|
||||
if not today_session_name:
|
||||
continue
|
||||
|
||||
# Find matchin review session
|
||||
project_review_sessions = review_sessions_by_project_id[project_id]
|
||||
todays_session = None
|
||||
yesterdays_session = None
|
||||
for review_session in project_review_sessions:
|
||||
session_name = review_session["name"]
|
||||
if session_name == today_session_name:
|
||||
todays_session = review_session
|
||||
break
|
||||
elif session_name == yesterday_session_name:
|
||||
yesterdays_session = review_session
|
||||
|
||||
# Skip if today's session already exist
|
||||
if todays_session is not None:
|
||||
self.log.debug((
|
||||
"Todays ReviewSession \"{}\""
|
||||
" in project \"{}\" already exists"
|
||||
).format(today_session_name, project_name))
|
||||
continue
|
||||
|
||||
# Check if there is yesterday's session and is empty
|
||||
# - in that case just rename it
|
||||
if (
|
||||
yesterdays_session is not None
|
||||
and len(yesterdays_session["review_session_objects"]) == 0
|
||||
):
|
||||
self.log.debug((
|
||||
"Renaming yesterdays empty review session \"{}\" to \"{}\""
|
||||
" in project \"{}\""
|
||||
).format(
|
||||
yesterday_session_name, today_session_name, project_name
|
||||
))
|
||||
yesterdays_session["name"] = today_session_name
|
||||
session.commit()
|
||||
continue
|
||||
|
||||
# Create new review session with new name
|
||||
self.log.debug((
|
||||
"Creating new review session \"{}\" in project \"{}\""
|
||||
).format(today_session_name, project_name))
|
||||
session.create("ReviewSession", {
|
||||
"project_id": project_id,
|
||||
"name": today_session_name
|
||||
})
|
||||
session.commit()
|
||||
|
||||
def _get_action_settings(self, project_names_by_id):
|
||||
settings_by_project_id = {}
|
||||
for project_id, project_name in project_names_by_id.items():
|
||||
project_settings = get_project_settings(project_name)
|
||||
action_settings = self._extract_action_settings(project_settings)
|
||||
settings_by_project_id[project_id] = action_settings
|
||||
return settings_by_project_id
|
||||
|
||||
def _extract_action_settings(self, project_settings):
|
||||
return (
|
||||
project_settings
|
||||
.get("ftrack", {})
|
||||
.get(self.settings_frack_subkey, {})
|
||||
.get(self.settings_key)
|
||||
) or {}
|
||||
|
||||
def _fill_review_template(self, template, data):
|
||||
output = None
|
||||
try:
|
||||
output = template.format(**data)
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
(
|
||||
"Failed to fill review session template {} with data {}"
|
||||
).format(template, data),
|
||||
exc_info=True
|
||||
)
|
||||
return output
|
||||
|
||||
|
||||
def register(session):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
CreateDailyReviewSessionServerAction(session).register()
|
||||
|
|
@ -144,3 +144,12 @@ def parenthood(*args, **kwargs):
|
|||
@requires_install
|
||||
def bulk_write(*args, **kwargs):
|
||||
return _connection_object.bulk_write(*args, **kwargs)
|
||||
|
||||
|
||||
@requires_install
|
||||
def active_project(*args, **kwargs):
|
||||
return _connection_object.active_project(*args, **kwargs)
|
||||
|
||||
|
||||
def current_project(*args, **kwargs):
|
||||
return Session.get("AVALON_PROJECT")
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ class AvalonMongoDB:
|
|||
"""Return the name of the active project"""
|
||||
return self.Session["AVALON_PROJECT"]
|
||||
|
||||
def current_project(self):
|
||||
"""Currently set project in Session without triggering installation."""
|
||||
return self.Session.get("AVALON_PROJECT")
|
||||
|
||||
@requires_install
|
||||
@auto_reconnect
|
||||
def projects(self, projection=None, only_active=True):
|
||||
|
|
|
|||
|
|
@ -940,9 +940,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
families += current_families
|
||||
|
||||
# create relative source path for DB
|
||||
if "source" in instance.data:
|
||||
source = instance.data["source"]
|
||||
else:
|
||||
source = instance.data.get("source")
|
||||
if not source:
|
||||
source = context.data["currentFile"]
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
source = self.get_rootless_path(anatomy, source)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,15 @@
|
|||
"Administrator",
|
||||
"Project manager"
|
||||
]
|
||||
},
|
||||
"create_daily_review_session": {
|
||||
"enabled": true,
|
||||
"role_list": [
|
||||
"Administrator",
|
||||
"Project Manager"
|
||||
],
|
||||
"cycle_enabled": false,
|
||||
"review_session_template": "{yy}{mm}{dd}"
|
||||
}
|
||||
},
|
||||
"user_handlers": {
|
||||
|
|
|
|||
|
|
@ -388,6 +388,44 @@
|
|||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "create_daily_review_session",
|
||||
"label": "Create daily review session",
|
||||
"type": "dict",
|
||||
"is_group": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "role_list",
|
||||
"label": "Roles",
|
||||
"object_type": "text",
|
||||
"use_label_wrap": true
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "cycle_enabled",
|
||||
"label": "Create daily review session"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "review_session_template",
|
||||
"label": "ReviewSession template",
|
||||
"placeholder": "Default: {yy}{mm}{dd}"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Possible formatting keys in template:<br/>- \"project_name\" - <Name of project><br/>- \"d\" - <Day of month number> in shortest possible way.<br/>- \"dd\" - <Day of month number> with 2 digits.<br/>- \"ddd\" - <Week day name> shortened week day. e.g.: `Mon`, ...<br/>- \"dddd\" - <Week day name> full name of week day. e.g.: `Monday`, ...<br/>- \"m\" - <Month number> in shortest possible way. e.g.: `1` if January<br/>- \"mm\" - <Month number> with 2 digits.<br/>- \"mmm\" - <Month name> shortened month name. e.g.: `Jan`, ...<br/>- \"mmmm\" -<Month name> full month name. e.g.: `January`, ...<br/>- \"yy\" - <Year number> shortened year. e.g.: `19`, `20`, ...<br/>- \"yyyy\" - <Year number> full year. e.g.: `2019`, `2020`, ..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
import collections
|
||||
from openpype.client import (
|
||||
get_versions,
|
||||
get_subsets,
|
||||
get_assets,
|
||||
get_output_link_versions,
|
||||
)
|
||||
|
||||
from Qt import QtWidgets
|
||||
|
||||
|
||||
class SimpleLinkView(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self, dbcon, parent=None):
|
||||
def __init__(self, dbcon, parent):
|
||||
super(SimpleLinkView, self).__init__(parent=parent)
|
||||
self.dbcon = dbcon
|
||||
|
||||
|
|
@ -24,6 +30,11 @@ class SimpleLinkView(QtWidgets.QWidget):
|
|||
|
||||
self._in_view = in_view
|
||||
self._out_view = out_view
|
||||
self._version_doc_to_process = None
|
||||
|
||||
@property
|
||||
def project_name(self):
|
||||
return self.dbcon.current_project()
|
||||
|
||||
def clear(self):
|
||||
self._in_view.clear()
|
||||
|
|
@ -31,60 +42,114 @@ class SimpleLinkView(QtWidgets.QWidget):
|
|||
|
||||
def set_version(self, version_doc):
|
||||
self.clear()
|
||||
if not version_doc or not self.isVisible():
|
||||
return
|
||||
self._version_doc_to_process = version_doc
|
||||
if version_doc and self.isVisible():
|
||||
self._fill_values()
|
||||
|
||||
# inputs
|
||||
#
|
||||
def showEvent(self, event):
|
||||
super(SimpleLinkView, self).showEvent(event)
|
||||
self._fill_values()
|
||||
|
||||
def _fill_values(self):
|
||||
if self._version_doc_to_process is None:
|
||||
return
|
||||
version_doc = self._version_doc_to_process
|
||||
self._version_doc_to_process = None
|
||||
self._fill_inputs(version_doc)
|
||||
self._fill_outputs(version_doc)
|
||||
|
||||
def _fill_inputs(self, version_doc):
|
||||
version_ids = set()
|
||||
for link in version_doc["data"].get("inputLinks", []):
|
||||
# Backwards compatibility for "input" key used as "id"
|
||||
if "id" not in link:
|
||||
link_id = link["input"]
|
||||
else:
|
||||
link_id = link["id"]
|
||||
version = self.dbcon.find_one(
|
||||
{"_id": link_id, "type": "version"},
|
||||
projection={"name": 1, "parent": 1}
|
||||
)
|
||||
if not version:
|
||||
continue
|
||||
subset = self.dbcon.find_one(
|
||||
{"_id": version["parent"], "type": "subset"},
|
||||
projection={"name": 1, "parent": 1}
|
||||
)
|
||||
if not subset:
|
||||
continue
|
||||
asset = self.dbcon.find_one(
|
||||
{"_id": subset["parent"], "type": "asset"},
|
||||
projection={"name": 1}
|
||||
)
|
||||
version_ids.add(link_id)
|
||||
|
||||
self._in_view.addItem("{asset} {subset} v{version:0>3}".format(
|
||||
asset=asset["name"],
|
||||
subset=subset["name"],
|
||||
version=version["name"],
|
||||
version_docs = list(get_versions(
|
||||
self.project_name,
|
||||
version_ids=version_ids,
|
||||
fields=["name", "parent"]
|
||||
))
|
||||
|
||||
versions_by_subset_id = collections.defaultdict(list)
|
||||
for version_doc in version_docs:
|
||||
subset_id = version_doc["parent"]
|
||||
versions_by_subset_id[subset_id].append(version_doc)
|
||||
|
||||
subset_docs = []
|
||||
if versions_by_subset_id:
|
||||
subset_docs = list(get_subsets(
|
||||
self.project_name,
|
||||
subset_ids=versions_by_subset_id.keys(),
|
||||
fields=["_id", "name", "parent"]
|
||||
))
|
||||
|
||||
# outputs
|
||||
#
|
||||
outputs = self.dbcon.find(
|
||||
{"type": "version", "data.inputLinks.input": version_doc["_id"]},
|
||||
projection={"name": 1, "parent": 1}
|
||||
)
|
||||
for version in outputs or []:
|
||||
subset = self.dbcon.find_one(
|
||||
{"_id": version["parent"], "type": "subset"},
|
||||
projection={"name": 1, "parent": 1}
|
||||
)
|
||||
if not subset:
|
||||
continue
|
||||
asset = self.dbcon.find_one(
|
||||
{"_id": subset["parent"], "type": "asset"},
|
||||
projection={"name": 1}
|
||||
)
|
||||
asset_docs = []
|
||||
subsets_by_asset_id = collections.defaultdict(list)
|
||||
if subset_docs:
|
||||
for subset_doc in subset_docs:
|
||||
asset_id = subset_doc["parent"]
|
||||
subsets_by_asset_id[asset_id].append(subset_doc)
|
||||
|
||||
self._out_view.addItem("{asset} {subset} v{version:0>3}".format(
|
||||
asset=asset["name"],
|
||||
subset=subset["name"],
|
||||
version=version["name"],
|
||||
asset_docs = list(get_assets(
|
||||
self.project_name,
|
||||
asset_ids=subsets_by_asset_id.keys(),
|
||||
fields=["_id", "name"]
|
||||
))
|
||||
|
||||
for asset_doc in asset_docs:
|
||||
asset_id = asset_doc["_id"]
|
||||
for subset_doc in subsets_by_asset_id[asset_id]:
|
||||
subset_id = subset_doc["_id"]
|
||||
for version_doc in versions_by_subset_id[subset_id]:
|
||||
self._in_view.addItem("{} {} v{:0>3}".format(
|
||||
asset_doc["name"],
|
||||
subset_doc["name"],
|
||||
version_doc["name"],
|
||||
))
|
||||
|
||||
def _fill_outputs(self, version_doc):
|
||||
version_docs = list(get_output_link_versions(
|
||||
self.project_name,
|
||||
version_doc["_id"],
|
||||
fields=["name", "parent"]
|
||||
))
|
||||
versions_by_subset_id = collections.defaultdict(list)
|
||||
for version_doc in version_docs:
|
||||
subset_id = version_doc["parent"]
|
||||
versions_by_subset_id[subset_id].append(version_doc)
|
||||
|
||||
subset_docs = []
|
||||
if versions_by_subset_id:
|
||||
subset_docs = list(get_subsets(
|
||||
self.project_name,
|
||||
subset_ids=versions_by_subset_id.keys(),
|
||||
fields=["_id", "name", "parent"]
|
||||
))
|
||||
|
||||
asset_docs = []
|
||||
subsets_by_asset_id = collections.defaultdict(list)
|
||||
if subset_docs:
|
||||
for subset_doc in subset_docs:
|
||||
asset_id = subset_doc["parent"]
|
||||
subsets_by_asset_id[asset_id].append(subset_doc)
|
||||
|
||||
asset_docs = list(get_assets(
|
||||
self.project_name,
|
||||
asset_ids=subsets_by_asset_id.keys(),
|
||||
fields=["_id", "name"]
|
||||
))
|
||||
|
||||
for asset_doc in asset_docs:
|
||||
asset_id = asset_doc["_id"]
|
||||
for subset_doc in subsets_by_asset_id[asset_id]:
|
||||
subset_id = subset_doc["_id"]
|
||||
for version_doc in versions_by_subset_id[subset_id]:
|
||||
self._out_view.addItem("{} {} v{:0>3}".format(
|
||||
asset_doc["name"],
|
||||
subset_doc["name"],
|
||||
version_doc["name"],
|
||||
))
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import re
|
|||
|
||||
from Qt import QtWidgets, QtCore
|
||||
|
||||
from openpype.client import get_asset_by_name, get_subsets
|
||||
from openpype import style
|
||||
from openpype.api import get_current_project_settings
|
||||
from openpype.tools.utils.lib import qt_app_context
|
||||
|
|
@ -215,12 +216,12 @@ class CreatorWindow(QtWidgets.QDialog):
|
|||
self._set_valid_state(False)
|
||||
return
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
asset_doc = None
|
||||
if creator_plugin:
|
||||
# Get the asset from the database which match with the name
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"name": asset_name, "type": "asset"},
|
||||
projection={"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, asset_name, fields=["_id"]
|
||||
)
|
||||
|
||||
# Get plugin
|
||||
|
|
@ -235,7 +236,6 @@ class CreatorWindow(QtWidgets.QDialog):
|
|||
self._set_valid_state(False)
|
||||
return
|
||||
|
||||
project_name = legacy_io.Session["AVALON_PROJECT"]
|
||||
asset_id = asset_doc["_id"]
|
||||
task_name = legacy_io.Session["AVALON_TASK"]
|
||||
|
||||
|
|
@ -269,14 +269,13 @@ class CreatorWindow(QtWidgets.QDialog):
|
|||
self._subset_name_input.setText(subset_name)
|
||||
|
||||
# Get all subsets of the current asset
|
||||
subset_docs = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_id
|
||||
},
|
||||
{"name": 1}
|
||||
subset_docs = get_subsets(
|
||||
project_name, asset_ids=[asset_id], fields=["name"]
|
||||
)
|
||||
existing_subset_names = set(subset_docs.distinct("name"))
|
||||
existing_subset_names = {
|
||||
subset_doc["name"]
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
existing_subset_names_low = set(
|
||||
_name.lower()
|
||||
for _name in existing_subset_names
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ import appdirs
|
|||
from Qt import QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_assets,
|
||||
)
|
||||
from openpype.lib import JSONSettingRegistry
|
||||
from openpype.lib.applications import (
|
||||
CUSTOM_LAUNCH_APP_GROUPS,
|
||||
|
|
@ -81,13 +85,11 @@ class ActionModel(QtGui.QStandardItemModel):
|
|||
|
||||
def get_application_actions(self):
|
||||
actions = []
|
||||
if not self.dbcon.Session.get("AVALON_PROJECT"):
|
||||
if not self.dbcon.current_project():
|
||||
return actions
|
||||
|
||||
project_doc = self.dbcon.find_one(
|
||||
{"type": "project"},
|
||||
{"config.apps": True}
|
||||
)
|
||||
project_name = self.dbcon.active_project()
|
||||
project_doc = get_project(project_name, fields=["config.apps"])
|
||||
if not project_doc:
|
||||
return actions
|
||||
|
||||
|
|
@ -448,7 +450,7 @@ class LauncherModel(QtCore.QObject):
|
|||
@property
|
||||
def project_name(self):
|
||||
"""Current project name."""
|
||||
return self._dbcon.Session.get("AVALON_PROJECT")
|
||||
return self._dbcon.current_project()
|
||||
|
||||
@property
|
||||
def refreshing_assets(self):
|
||||
|
|
@ -649,9 +651,8 @@ class LauncherModel(QtCore.QObject):
|
|||
self._asset_refresh_thread = None
|
||||
|
||||
def _refresh_assets(self):
|
||||
asset_docs = list(self._dbcon.find(
|
||||
{"type": "asset"},
|
||||
self._asset_projection
|
||||
asset_docs = list(get_assets(
|
||||
self._last_project_name, fields=self._asset_projection.keys()
|
||||
))
|
||||
if not self._refreshing_assets:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import sys
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype import style
|
||||
from openpype.client import get_project
|
||||
from openpype.pipeline import AvalonMongoDB
|
||||
from openpype.tools.utils import lib as tools_lib
|
||||
from openpype.tools.loader.widgets import (
|
||||
|
|
@ -303,14 +304,26 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
|
|||
families = self._subsets_widget.get_subsets_families()
|
||||
self._families_filter_view.set_enabled_families(families)
|
||||
|
||||
def set_context(self, context, refresh=True):
|
||||
self.echo("Setting context: {}".format(context))
|
||||
lib.schedule(
|
||||
lambda: self._set_context(context, refresh=refresh),
|
||||
50, channel="mongo"
|
||||
)
|
||||
|
||||
# ------------------------------
|
||||
def set_context(self, context, refresh=True):
|
||||
"""Set the selection in the interface using a context.
|
||||
The context must contain `asset` data by name.
|
||||
|
||||
Args:
|
||||
context (dict): The context to apply.
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
asset_name = context.get("asset", None)
|
||||
if asset_name is None:
|
||||
return
|
||||
|
||||
if refresh:
|
||||
self._refresh_assets()
|
||||
|
||||
self._assets_widget.select_asset_by_name(asset_name)
|
||||
|
||||
def _on_family_filter_change(self, families):
|
||||
self._subsets_widget.set_family_filters(families)
|
||||
|
||||
|
|
@ -323,10 +336,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
|
|||
"""Load assets from database"""
|
||||
if self.current_project is not None:
|
||||
# Ensure a project is loaded
|
||||
project_doc = self.dbcon.find_one(
|
||||
{"type": "project"},
|
||||
{"type": 1}
|
||||
)
|
||||
project_doc = get_project(self.current_project, fields=["_id"])
|
||||
assert project_doc, "This is a bug"
|
||||
|
||||
self._families_filter_view.set_enabled_families(set())
|
||||
|
|
@ -371,7 +381,7 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
|
|||
|
||||
# Clear the version information on asset change
|
||||
self._version_info_widget.set_version(None)
|
||||
self._thumbnail_widget.set_thumbnail(asset_ids)
|
||||
self._thumbnail_widget.set_thumbnail("asset", asset_ids)
|
||||
|
||||
self.data["state"]["assetIds"] = asset_ids
|
||||
|
||||
|
|
@ -426,34 +436,17 @@ class LibraryLoaderWindow(QtWidgets.QDialog):
|
|||
version_doc["_id"]
|
||||
for version_doc in version_docs
|
||||
]
|
||||
src_type = "version"
|
||||
if not thumbnail_src_ids:
|
||||
src_type = "asset"
|
||||
thumbnail_src_ids = self._assets_widget.get_selected_asset_ids()
|
||||
|
||||
self._thumbnail_widget.set_thumbnail(thumbnail_src_ids)
|
||||
self._thumbnail_widget.set_thumbnail(src_type, thumbnail_src_ids)
|
||||
|
||||
version_ids = [doc["_id"] for doc in version_docs or []]
|
||||
if self._repres_widget:
|
||||
self._repres_widget.set_version_ids(version_ids)
|
||||
|
||||
def _set_context(self, context, refresh=True):
|
||||
"""Set the selection in the interface using a context.
|
||||
The context must contain `asset` data by name.
|
||||
|
||||
Args:
|
||||
context (dict): The context to apply.
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
asset_name = context.get("asset", None)
|
||||
if asset_name is None:
|
||||
return
|
||||
|
||||
if refresh:
|
||||
self._refresh_assets()
|
||||
|
||||
self._assets_widget.select_asset_by_name(asset_name)
|
||||
|
||||
def _on_message_timeout(self):
|
||||
self._message_label.setText("")
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import traceback
|
|||
|
||||
from Qt import QtWidgets, QtCore
|
||||
|
||||
from openpype.client import get_projects, get_project
|
||||
from openpype import style
|
||||
from openpype.lib import register_event_callback
|
||||
from openpype.pipeline import (
|
||||
|
|
@ -39,7 +40,7 @@ class LoaderWindow(QtWidgets.QDialog):
|
|||
def __init__(self, parent=None):
|
||||
super(LoaderWindow, self).__init__(parent)
|
||||
title = "Asset Loader 2.1"
|
||||
project_name = legacy_io.Session.get("AVALON_PROJECT")
|
||||
project_name = legacy_io.active_project()
|
||||
if project_name:
|
||||
title += " - {}".format(project_name)
|
||||
self.setWindowTitle(title)
|
||||
|
|
@ -274,8 +275,9 @@ class LoaderWindow(QtWidgets.QDialog):
|
|||
"""Load assets from database"""
|
||||
|
||||
# Ensure a project is loaded
|
||||
project = legacy_io.find_one({"type": "project"}, {"type": 1})
|
||||
assert project, "Project was not found! This is a bug"
|
||||
project_name = legacy_io.active_project()
|
||||
project_doc = get_project(project_name, fields=["_id"])
|
||||
assert project_doc, "Project was not found! This is a bug"
|
||||
|
||||
self._assets_widget.refresh()
|
||||
self._assets_widget.setFocus()
|
||||
|
|
@ -314,7 +316,7 @@ class LoaderWindow(QtWidgets.QDialog):
|
|||
)
|
||||
|
||||
# Clear the version information on asset change
|
||||
self._thumbnail_widget.set_thumbnail(asset_ids)
|
||||
self._thumbnail_widget.set_thumbnail("asset", asset_ids)
|
||||
self._version_info_widget.set_version(None)
|
||||
|
||||
self.data["state"]["assetIds"] = asset_ids
|
||||
|
|
@ -371,10 +373,12 @@ class LoaderWindow(QtWidgets.QDialog):
|
|||
version_doc["_id"]
|
||||
for version_doc in version_docs
|
||||
]
|
||||
source_type = "version"
|
||||
if not thumbnail_src_ids:
|
||||
source_type = "asset"
|
||||
thumbnail_src_ids = self._assets_widget.get_selected_asset_ids()
|
||||
|
||||
self._thumbnail_widget.set_thumbnail(thumbnail_src_ids)
|
||||
self._thumbnail_widget.set_thumbnail(source_type, thumbnail_src_ids)
|
||||
|
||||
if self._repres_widget is not None:
|
||||
version_ids = [doc["_id"] for doc in version_docs]
|
||||
|
|
@ -576,8 +580,7 @@ def show(debug=False, parent=None, use_context=False):
|
|||
legacy_io.install()
|
||||
|
||||
any_project = next(
|
||||
project for project in legacy_io.projects()
|
||||
if project.get("active", True) is not False
|
||||
project for project in get_projects(fields=["name"])
|
||||
)
|
||||
|
||||
legacy_io.Session["AVALON_PROJECT"] = any_project["name"]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@ from uuid import uuid4
|
|||
from Qt import QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_assets,
|
||||
get_subsets,
|
||||
get_last_versions,
|
||||
get_versions,
|
||||
get_hero_versions,
|
||||
get_version_by_name,
|
||||
get_representations
|
||||
)
|
||||
from openpype.pipeline import (
|
||||
HeroVersionType,
|
||||
schema,
|
||||
|
|
@ -56,7 +65,7 @@ class BaseRepresentationModel(object):
|
|||
remote_site = remote_provider = None
|
||||
|
||||
if not project_name:
|
||||
project_name = self.dbcon.Session.get("AVALON_PROJECT")
|
||||
project_name = self.dbcon.active_project()
|
||||
else:
|
||||
self.dbcon.Session["AVALON_PROJECT"] = project_name
|
||||
|
||||
|
|
@ -197,9 +206,6 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
if subset_doc_projection:
|
||||
self.subset_doc_projection = subset_doc_projection
|
||||
|
||||
self.asset_doc_projection = asset_doc_projection
|
||||
self.subset_doc_projection = subset_doc_projection
|
||||
|
||||
self.repre_icons = {}
|
||||
self.sync_server = None
|
||||
self.active_site = self.active_provider = None
|
||||
|
|
@ -225,7 +231,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
self._doc_fetching_stop = False
|
||||
self._doc_payload = {}
|
||||
|
||||
self.doc_fetched.connect(self.on_doc_fetched)
|
||||
self.doc_fetched.connect(self._on_doc_fetched)
|
||||
|
||||
self.refresh()
|
||||
|
||||
|
|
@ -244,7 +250,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
def set_grouping(self, state):
|
||||
self._grouping = state
|
||||
self.on_doc_fetched()
|
||||
self._on_doc_fetched()
|
||||
|
||||
def get_subsets_families(self):
|
||||
return self._doc_payload.get("subset_families") or set()
|
||||
|
|
@ -254,57 +260,61 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
# because it also updates the information in other columns
|
||||
if index.column() == self.columns_index["version"]:
|
||||
item = index.internalPointer()
|
||||
parent = item["_id"]
|
||||
subset_id = item["_id"]
|
||||
if isinstance(value, HeroVersionType):
|
||||
versions = list(self.dbcon.find({
|
||||
"type": {"$in": ["version", "hero_version"]},
|
||||
"parent": parent
|
||||
}, sort=[("name", -1)]))
|
||||
|
||||
version = None
|
||||
last_version = None
|
||||
for __version in versions:
|
||||
if __version["type"] == "hero_version":
|
||||
version = __version
|
||||
elif last_version is None:
|
||||
last_version = __version
|
||||
|
||||
if version is not None and last_version is not None:
|
||||
break
|
||||
|
||||
_version = None
|
||||
for __version in versions:
|
||||
if __version["_id"] == version["version_id"]:
|
||||
_version = __version
|
||||
break
|
||||
|
||||
version["data"] = _version["data"]
|
||||
version["name"] = _version["name"]
|
||||
version["is_from_latest"] = (
|
||||
last_version["_id"] == _version["_id"]
|
||||
)
|
||||
version_doc = self._get_hero_version(subset_id)
|
||||
|
||||
else:
|
||||
version = self.dbcon.find_one({
|
||||
"name": value,
|
||||
"type": "version",
|
||||
"parent": parent
|
||||
})
|
||||
project_name = self.dbcon.active_project()
|
||||
version_doc = get_version_by_name(
|
||||
project_name, value, subset_id
|
||||
)
|
||||
|
||||
# update availability on active site when version changes
|
||||
if self.sync_server.enabled and version:
|
||||
query = self._repre_per_version_pipeline([version["_id"]],
|
||||
self.active_site,
|
||||
self.remote_site)
|
||||
if self.sync_server.enabled and version_doc:
|
||||
query = self._repre_per_version_pipeline(
|
||||
[version_doc["_id"]],
|
||||
self.active_site,
|
||||
self.remote_site
|
||||
)
|
||||
docs = list(self.dbcon.aggregate(query))
|
||||
if docs:
|
||||
repre = docs.pop()
|
||||
version["data"].update(self._get_repre_dict(repre))
|
||||
version_doc["data"].update(self._get_repre_dict(repre))
|
||||
|
||||
self.set_version(index, version)
|
||||
self.set_version(index, version_doc)
|
||||
|
||||
return super(SubsetsModel, self).setData(index, value, role)
|
||||
|
||||
def _get_hero_version(self, subset_id):
|
||||
project_name = self.dbcon.active_project()
|
||||
version_docs = get_versions(
|
||||
project_name, subset_ids=[subset_id], hero=True
|
||||
)
|
||||
standard_versions = []
|
||||
hero_version_doc = None
|
||||
for version_doc in version_docs:
|
||||
if version_doc["type"] == "hero_version":
|
||||
hero_version_doc = version_doc
|
||||
continue
|
||||
standard_versions.append(version_doc)
|
||||
|
||||
src_version_id = hero_version_doc["version_id"]
|
||||
src_version = None
|
||||
is_from_latest = True
|
||||
for version_doc in reversed(sorted(
|
||||
standard_versions, key=lambda item: item["name"]
|
||||
)):
|
||||
if version_doc["_id"] == src_version_id:
|
||||
src_version = version_doc
|
||||
break
|
||||
is_from_latest = False
|
||||
|
||||
hero_version_doc["data"] = src_version["data"]
|
||||
hero_version_doc["name"] = src_version["name"]
|
||||
hero_version_doc["is_from_latest"] = is_from_latest
|
||||
return hero_version_doc
|
||||
|
||||
def set_version(self, index, version):
|
||||
"""Update the version data of the given index.
|
||||
|
||||
|
|
@ -391,26 +401,25 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
item["repre_info"] = repre_info
|
||||
|
||||
def _fetch(self):
|
||||
asset_docs = self.dbcon.find(
|
||||
{
|
||||
"type": "asset",
|
||||
"_id": {"$in": self._asset_ids}
|
||||
},
|
||||
self.asset_doc_projection
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_docs = get_assets(
|
||||
project_name,
|
||||
asset_ids=self._asset_ids,
|
||||
fields=self.asset_doc_projection.keys()
|
||||
)
|
||||
|
||||
asset_docs_by_id = {
|
||||
asset_doc["_id"]: asset_doc
|
||||
for asset_doc in asset_docs
|
||||
}
|
||||
|
||||
subset_docs_by_id = {}
|
||||
subset_docs = self.dbcon.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": self._asset_ids}
|
||||
},
|
||||
self.subset_doc_projection
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=self._asset_ids,
|
||||
fields=self.subset_doc_projection.keys()
|
||||
)
|
||||
|
||||
subset_families = set()
|
||||
for subset_doc in subset_docs:
|
||||
if self._doc_fetching_stop:
|
||||
|
|
@ -423,37 +432,13 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
subset_docs_by_id[subset_doc["_id"]] = subset_doc
|
||||
|
||||
subset_ids = list(subset_docs_by_id.keys())
|
||||
_pipeline = [
|
||||
# Find all versions of those subsets
|
||||
{"$match": {
|
||||
"type": "version",
|
||||
"parent": {"$in": subset_ids}
|
||||
}},
|
||||
# Sorting versions all together
|
||||
{"$sort": {"name": 1}},
|
||||
# Group them by "parent", but only take the last
|
||||
{"$group": {
|
||||
"_id": "$parent",
|
||||
"_version_id": {"$last": "$_id"},
|
||||
"name": {"$last": "$name"},
|
||||
"type": {"$last": "$type"},
|
||||
"data": {"$last": "$data"},
|
||||
"locations": {"$last": "$locations"},
|
||||
"schema": {"$last": "$schema"}
|
||||
}}
|
||||
]
|
||||
last_versions_by_subset_id = dict()
|
||||
for doc in self.dbcon.aggregate(_pipeline):
|
||||
if self._doc_fetching_stop:
|
||||
return
|
||||
doc["parent"] = doc["_id"]
|
||||
doc["_id"] = doc.pop("_version_id")
|
||||
last_versions_by_subset_id[doc["parent"]] = doc
|
||||
last_versions_by_subset_id = get_last_versions(
|
||||
project_name,
|
||||
subset_ids,
|
||||
fields=["_id", "parent", "name", "type", "data", "schema"]
|
||||
)
|
||||
|
||||
hero_versions = self.dbcon.find({
|
||||
"type": "hero_version",
|
||||
"parent": {"$in": subset_ids}
|
||||
})
|
||||
hero_versions = get_hero_versions(project_name, subset_ids=subset_ids)
|
||||
missing_versions = []
|
||||
for hero_version in hero_versions:
|
||||
version_id = hero_version["version_id"]
|
||||
|
|
@ -462,10 +447,9 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
missing_versions_by_id = {}
|
||||
if missing_versions:
|
||||
missing_version_docs = self.dbcon.find({
|
||||
"type": "version",
|
||||
"_id": {"$in": missing_versions}
|
||||
})
|
||||
missing_version_docs = get_versions(
|
||||
project_name, version_ids=missing_versions
|
||||
)
|
||||
missing_versions_by_id = {
|
||||
missing_version_doc["_id"]: missing_version_doc
|
||||
for missing_version_doc in missing_version_docs
|
||||
|
|
@ -488,23 +472,16 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
last_versions_by_subset_id[subset_id] = hero_version
|
||||
|
||||
self._doc_payload = {
|
||||
"asset_docs_by_id": asset_docs_by_id,
|
||||
"subset_docs_by_id": subset_docs_by_id,
|
||||
"subset_families": subset_families,
|
||||
"last_versions_by_subset_id": last_versions_by_subset_id
|
||||
}
|
||||
|
||||
repre_info = {}
|
||||
if self.sync_server.enabled:
|
||||
version_ids = set()
|
||||
for _subset_id, doc in last_versions_by_subset_id.items():
|
||||
version_ids.add(doc["_id"])
|
||||
|
||||
query = self._repre_per_version_pipeline(list(version_ids),
|
||||
self.active_site,
|
||||
self.remote_site)
|
||||
query = self._repre_per_version_pipeline(
|
||||
list(version_ids), self.active_site, self.remote_site
|
||||
)
|
||||
|
||||
repre_info = {}
|
||||
for doc in self.dbcon.aggregate(query):
|
||||
if self._doc_fetching_stop:
|
||||
return
|
||||
|
|
@ -512,7 +489,13 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
doc["remote_provider"] = self.remote_provider
|
||||
repre_info[doc["_id"]] = doc
|
||||
|
||||
self._doc_payload["repre_info_by_version_id"] = repre_info
|
||||
self._doc_payload = {
|
||||
"asset_docs_by_id": asset_docs_by_id,
|
||||
"subset_docs_by_id": subset_docs_by_id,
|
||||
"subset_families": subset_families,
|
||||
"last_versions_by_subset_id": last_versions_by_subset_id,
|
||||
"repre_info_by_version_id": repre_info
|
||||
}
|
||||
|
||||
self.doc_fetched.emit()
|
||||
|
||||
|
|
@ -545,7 +528,7 @@ class SubsetsModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
self.fetch_subset_and_version()
|
||||
|
||||
def on_doc_fetched(self):
|
||||
def _on_doc_fetched(self):
|
||||
self.clear()
|
||||
self._items_by_id = {}
|
||||
self.beginResetModel()
|
||||
|
|
@ -1036,7 +1019,6 @@ class RepresentationSortProxyModel(GroupMemberFilterProxyModel):
|
|||
|
||||
|
||||
class RepresentationModel(TreeModel, BaseRepresentationModel):
|
||||
|
||||
doc_fetched = QtCore.Signal()
|
||||
refreshed = QtCore.Signal(bool)
|
||||
|
||||
|
|
@ -1062,33 +1044,43 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
"remote_site": "Remote"
|
||||
}
|
||||
|
||||
def __init__(self, dbcon, header, version_ids):
|
||||
repre_projection = {
|
||||
"_id": 1,
|
||||
"name": 1,
|
||||
"context.subset": 1,
|
||||
"context.asset": 1,
|
||||
"context.version": 1,
|
||||
"context.representation": 1,
|
||||
'files.sites': 1
|
||||
}
|
||||
|
||||
def __init__(self, dbcon, header):
|
||||
super(RepresentationModel, self).__init__()
|
||||
self.dbcon = dbcon
|
||||
self._data = []
|
||||
self._header = header
|
||||
self.version_ids = version_ids
|
||||
self._version_ids = []
|
||||
|
||||
manager = ModulesManager()
|
||||
sync_server = active_site = remote_site = None
|
||||
active_provider = remote_provider = None
|
||||
|
||||
project = dbcon.Session["AVALON_PROJECT"]
|
||||
if project:
|
||||
project_name = dbcon.current_project()
|
||||
if project_name:
|
||||
sync_server = manager.modules_by_name["sync_server"]
|
||||
active_site = sync_server.get_active_site(project)
|
||||
remote_site = sync_server.get_remote_site(project)
|
||||
active_site = sync_server.get_active_site(project_name)
|
||||
remote_site = sync_server.get_remote_site(project_name)
|
||||
|
||||
# TODO refactor
|
||||
active_provider = \
|
||||
sync_server.get_provider_for_site(project,
|
||||
active_site)
|
||||
active_provider = sync_server.get_provider_for_site(
|
||||
project_name, active_site
|
||||
)
|
||||
if active_site == 'studio':
|
||||
active_provider = 'studio'
|
||||
|
||||
remote_provider = \
|
||||
sync_server.get_provider_for_site(project,
|
||||
remote_site)
|
||||
remote_provider = sync_server.get_provider_for_site(
|
||||
project_name, remote_site
|
||||
)
|
||||
|
||||
if remote_site == 'studio':
|
||||
remote_provider = 'studio'
|
||||
|
|
@ -1099,7 +1091,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
self.remote_site = remote_site
|
||||
self.remote_provider = remote_provider
|
||||
|
||||
self.doc_fetched.connect(self.on_doc_fetched)
|
||||
self.doc_fetched.connect(self._on_doc_fetched)
|
||||
|
||||
self._docs = {}
|
||||
self._icons = lib.get_repre_icons()
|
||||
|
|
@ -1110,7 +1102,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
self._items_by_id = {}
|
||||
|
||||
def set_version_ids(self, version_ids):
|
||||
self.version_ids = version_ids
|
||||
self._version_ids = version_ids
|
||||
self.refresh()
|
||||
|
||||
def data(self, index, role):
|
||||
|
|
@ -1127,8 +1119,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
if index.column() == self.Columns.index("name"):
|
||||
if item.get("isMerged"):
|
||||
return item["icon"]
|
||||
else:
|
||||
return self._icons["repre"]
|
||||
return self._icons["repre"]
|
||||
|
||||
active_index = self.Columns.index("active_site")
|
||||
remote_index = self.Columns.index("remote_site")
|
||||
|
|
@ -1144,12 +1135,12 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
# site added, sync in progress
|
||||
progress_str = "not avail."
|
||||
if progress >= 0:
|
||||
# progress == 0 for isMerged is unavailable
|
||||
if progress == 0 and item.get("isMerged"):
|
||||
progress_str = "not avail."
|
||||
else:
|
||||
progress_str = "{}% {}".format(int(progress * 100),
|
||||
label)
|
||||
progress_str = "{}% {}".format(
|
||||
int(progress * 100), label
|
||||
)
|
||||
|
||||
return progress_str
|
||||
|
||||
|
|
@ -1179,7 +1170,7 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
|
||||
return super(RepresentationModel, self).data(index, role)
|
||||
|
||||
def on_doc_fetched(self):
|
||||
def _on_doc_fetched(self):
|
||||
self.clear()
|
||||
self.beginResetModel()
|
||||
subsets = set()
|
||||
|
|
@ -1189,10 +1180,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
group = None
|
||||
self._items_by_id = {}
|
||||
for doc in self._docs:
|
||||
if len(self.version_ids) > 1:
|
||||
if len(self._version_ids) > 1:
|
||||
group = repre_groups.get(doc["name"])
|
||||
if not group:
|
||||
|
||||
group_item = Item()
|
||||
item_id = str(uuid4())
|
||||
group_item.update({
|
||||
|
|
@ -1213,9 +1203,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
repre_groups_items[doc["name"]] = 0
|
||||
group = group_item
|
||||
|
||||
progress = lib.get_progress_for_repre(doc,
|
||||
self.active_site,
|
||||
self.remote_site)
|
||||
progress = lib.get_progress_for_repre(
|
||||
doc, self.active_site, self.remote_site
|
||||
)
|
||||
|
||||
active_site_icon = self._icons.get(self.active_provider)
|
||||
remote_site_icon = self._icons.get(self.remote_provider)
|
||||
|
|
@ -1248,9 +1238,9 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
'remote_site_progress': progress[self.remote_site]
|
||||
}
|
||||
if group:
|
||||
group = self._sum_group_progress(doc["name"], group,
|
||||
current_progress,
|
||||
repre_groups_items)
|
||||
group = self._sum_group_progress(
|
||||
doc["name"], group, current_progress, repre_groups_items
|
||||
)
|
||||
|
||||
self.add_child(item, group)
|
||||
|
||||
|
|
@ -1269,47 +1259,39 @@ class RepresentationModel(TreeModel, BaseRepresentationModel):
|
|||
return self._items_by_id.get(item_id)
|
||||
|
||||
def refresh(self):
|
||||
docs = []
|
||||
session_project = self.dbcon.Session['AVALON_PROJECT']
|
||||
if not session_project:
|
||||
project_name = self.dbcon.current_project()
|
||||
if not project_name:
|
||||
return
|
||||
|
||||
if self.version_ids:
|
||||
repre_docs = []
|
||||
if self._version_ids:
|
||||
# Simple find here for now, expected to receive lower number of
|
||||
# representations and logic could be in Python
|
||||
docs = list(self.dbcon.find(
|
||||
{"type": "representation", "parent": {"$in": self.version_ids},
|
||||
"files.sites.name": {"$exists": 1}}, self.projection()))
|
||||
self._docs = docs
|
||||
repre_docs = list(get_representations(
|
||||
project_name,
|
||||
version_ids=self._version_ids,
|
||||
fields=self.repre_projection.keys()
|
||||
))
|
||||
|
||||
self._docs = repre_docs
|
||||
|
||||
self.doc_fetched.emit()
|
||||
|
||||
@classmethod
|
||||
def projection(cls):
|
||||
return {
|
||||
"_id": 1,
|
||||
"name": 1,
|
||||
"context.subset": 1,
|
||||
"context.asset": 1,
|
||||
"context.version": 1,
|
||||
"context.representation": 1,
|
||||
'files.sites': 1
|
||||
}
|
||||
def _sum_group_progress(
|
||||
self, repre_name, group, current_item_progress, repre_groups_items
|
||||
):
|
||||
"""Update final group progress
|
||||
|
||||
def _sum_group_progress(self, repre_name, group, current_item_progress,
|
||||
repre_groups_items):
|
||||
"""
|
||||
Update final group progress
|
||||
Called after every item in group is added
|
||||
Called after every item in group is added
|
||||
|
||||
Args:
|
||||
repre_name(string)
|
||||
group(dict): info about group of selected items
|
||||
current_item_progress(dict): {'active_site_progress': XX,
|
||||
'remote_site_progress': YY}
|
||||
repre_groups_items(dict)
|
||||
Returns:
|
||||
(dict): updated group info
|
||||
Args:
|
||||
repre_name(string)
|
||||
group(dict): info about group of selected items
|
||||
current_item_progress(dict): {'active_site_progress': XX,
|
||||
'remote_site_progress': YY}
|
||||
repre_groups_items(dict)
|
||||
Returns:
|
||||
(dict): updated group info
|
||||
"""
|
||||
repre_groups_items[repre_name] += 1
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ import collections
|
|||
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype.client import (
|
||||
get_subset_families,
|
||||
get_subset_by_id,
|
||||
get_subsets,
|
||||
get_version_by_id,
|
||||
get_versions,
|
||||
get_representations,
|
||||
get_thumbnail_id_from_source,
|
||||
get_thumbnail,
|
||||
)
|
||||
from openpype.api import Anatomy
|
||||
from openpype.pipeline import HeroVersionType
|
||||
from openpype.pipeline.thumbnail import get_thumbnail_binary
|
||||
|
|
@ -237,8 +247,7 @@ class SubsetWidget(QtWidgets.QWidget):
|
|||
self.model = model
|
||||
self.view = view
|
||||
|
||||
actual_project = dbcon.Session["AVALON_PROJECT"]
|
||||
self.on_project_change(actual_project)
|
||||
self.on_project_change(dbcon.current_project())
|
||||
|
||||
view.customContextMenuRequested.connect(self.on_context_menu)
|
||||
|
||||
|
|
@ -302,33 +311,23 @@ class SubsetWidget(QtWidgets.QWidget):
|
|||
item["version_document"]
|
||||
)
|
||||
|
||||
subset_docs = list(self.dbcon.find(
|
||||
{
|
||||
"_id": {"$in": list(version_docs_by_subset_id.keys())},
|
||||
"type": "subset"
|
||||
},
|
||||
{
|
||||
"schema": 1,
|
||||
"data.families": 1
|
||||
}
|
||||
project_name = self.dbcon.active_project()
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
subset_ids=version_docs_by_subset_id.keys(),
|
||||
fields=["schema", "data.families"]
|
||||
))
|
||||
subset_docs_by_id = {
|
||||
subset_doc["_id"]: subset_doc
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
version_ids = list(version_docs_by_id.keys())
|
||||
repre_docs = self.dbcon.find(
|
||||
# Query all representations for selected versions at once
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": version_ids}
|
||||
},
|
||||
# Query only name and parent from representation
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=version_ids,
|
||||
fields=["name", "parent"]
|
||||
)
|
||||
|
||||
repre_docs_by_version_id = {
|
||||
version_id: []
|
||||
for version_id in version_ids
|
||||
|
|
@ -566,28 +565,42 @@ class SubsetWidget(QtWidgets.QWidget):
|
|||
# same representation available
|
||||
|
||||
# Trigger
|
||||
repre_ids = []
|
||||
project_name = self.dbcon.active_project()
|
||||
subset_names_by_version_id = collections.defaultdict(set)
|
||||
for item in items:
|
||||
representation = self.dbcon.find_one(
|
||||
{
|
||||
"type": "representation",
|
||||
"name": representation_name,
|
||||
"parent": item["version_document"]["_id"]
|
||||
},
|
||||
{"_id": 1}
|
||||
)
|
||||
if not representation:
|
||||
self.echo("Subset '{}' has no representation '{}'".format(
|
||||
item["subset"], representation_name
|
||||
))
|
||||
continue
|
||||
repre_ids.append(representation["_id"])
|
||||
version_id = item["version_document"]["_id"]
|
||||
subset_names_by_version_id[version_id].add(item["subset"])
|
||||
|
||||
version_ids = set(subset_names_by_version_id.keys())
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
representation_names=[representation_name],
|
||||
version_ids=version_ids,
|
||||
fields=["_id", "parent"]
|
||||
)
|
||||
|
||||
repre_ids = []
|
||||
for repre_doc in repre_docs:
|
||||
repre_ids.append(repre_doc["_id"])
|
||||
|
||||
version_id = repre_doc["parent"]
|
||||
if version_id not in version_ids:
|
||||
version_ids.remove(version_id)
|
||||
|
||||
for version_id in version_ids:
|
||||
joined_subset_names = ", ".join([
|
||||
'"{}"'.format(subset)
|
||||
for subset in subset_names_by_version_id[version_id]
|
||||
])
|
||||
self.echo("Subsets {} don't have representation '{}'".format(
|
||||
joined_subset_names, representation_name
|
||||
))
|
||||
|
||||
# get contexts only for selected menu option
|
||||
repre_contexts = get_repres_contexts(repre_ids, self.dbcon)
|
||||
options = lib.get_options(action, loader, self,
|
||||
list(repre_contexts.values()))
|
||||
|
||||
options = lib.get_options(
|
||||
action, loader, self, list(repre_contexts.values())
|
||||
)
|
||||
error_info = _load_representations_by_loader(
|
||||
loader, repre_contexts, options=options
|
||||
)
|
||||
|
|
@ -661,27 +674,21 @@ class VersionTextEdit(QtWidgets.QTextEdit):
|
|||
|
||||
print("Querying..")
|
||||
|
||||
project_name = self.dbcon.active_project()
|
||||
if not version_doc:
|
||||
version_doc = self.dbcon.find_one({
|
||||
"_id": version_id,
|
||||
"type": {"$in": ["version", "hero_version"]}
|
||||
})
|
||||
version_doc = get_version_by_id(project_name, version_id)
|
||||
assert version_doc, "Not a valid version id"
|
||||
|
||||
if version_doc["type"] == "hero_version":
|
||||
_version_doc = self.dbcon.find_one({
|
||||
"_id": version_doc["version_id"],
|
||||
"type": "version"
|
||||
})
|
||||
_version_doc = get_version_by_id(
|
||||
project_name, version_doc["version_id"]
|
||||
)
|
||||
version_doc["data"] = _version_doc["data"]
|
||||
version_doc["name"] = HeroVersionType(
|
||||
_version_doc["name"]
|
||||
)
|
||||
|
||||
subset = self.dbcon.find_one({
|
||||
"_id": version_doc["parent"],
|
||||
"type": "subset"
|
||||
})
|
||||
subset = get_subset_by_id(project_name, version_doc["parent"])
|
||||
assert subset, "No valid subset parent for version"
|
||||
|
||||
# Define readable creation timestamp
|
||||
|
|
@ -752,7 +759,7 @@ class VersionTextEdit(QtWidgets.QTextEdit):
|
|||
if not source:
|
||||
return
|
||||
|
||||
project_name = self.dbcon.Session["AVALON_PROJECT"]
|
||||
project_name = self.dbcon.current_project()
|
||||
if self._anatomy is None or self._anatomy.project_name != project_name:
|
||||
self._anatomy = Anatomy(project_name)
|
||||
|
||||
|
|
@ -833,24 +840,19 @@ class ThumbnailWidget(QtWidgets.QLabel):
|
|||
QtCore.Qt.SmoothTransformation
|
||||
)
|
||||
|
||||
def set_thumbnail(self, doc_id=None):
|
||||
if not doc_id:
|
||||
def set_thumbnail(self, src_type, doc_ids):
|
||||
if not doc_ids:
|
||||
self.set_pixmap()
|
||||
return
|
||||
|
||||
if isinstance(doc_id, (list, tuple)):
|
||||
if len(doc_id) < 1:
|
||||
self.set_pixmap()
|
||||
return
|
||||
doc_id = doc_id[0]
|
||||
src_id = doc_ids[0]
|
||||
|
||||
doc = self.dbcon.find_one(
|
||||
{"_id": doc_id},
|
||||
{"data.thumbnail_id"}
|
||||
project_name = self.dbcon.active_project()
|
||||
thumbnail_id = get_thumbnail_id_from_source(
|
||||
project_name,
|
||||
src_type,
|
||||
src_id,
|
||||
)
|
||||
thumbnail_id = None
|
||||
if doc:
|
||||
thumbnail_id = doc.get("data", {}).get("thumbnail_id")
|
||||
if thumbnail_id == self.current_thumb_id:
|
||||
if self.current_thumbnail is None:
|
||||
self.set_pixmap()
|
||||
|
|
@ -861,9 +863,7 @@ class ThumbnailWidget(QtWidgets.QLabel):
|
|||
self.set_pixmap()
|
||||
return
|
||||
|
||||
thumbnail_ent = self.dbcon.find_one(
|
||||
{"type": "thumbnail", "_id": thumbnail_id}
|
||||
)
|
||||
thumbnail_ent = get_thumbnail(project_name, thumbnail_id)
|
||||
if not thumbnail_ent:
|
||||
return
|
||||
|
||||
|
|
@ -917,21 +917,9 @@ class FamilyModel(QtGui.QStandardItemModel):
|
|||
|
||||
def refresh(self):
|
||||
families = set()
|
||||
if self.dbcon.Session.get("AVALON_PROJECT"):
|
||||
result = list(self.dbcon.aggregate([
|
||||
{"$match": {
|
||||
"type": "subset"
|
||||
}},
|
||||
{"$project": {
|
||||
"family": {"$arrayElemAt": ["$data.families", 0]}
|
||||
}},
|
||||
{"$group": {
|
||||
"_id": "family_group",
|
||||
"families": {"$addToSet": "$family"}
|
||||
}}
|
||||
]))
|
||||
if result:
|
||||
families = set(result[0]["families"])
|
||||
project_name = self.dbcon.current_project()
|
||||
if project_name:
|
||||
families = get_subset_families(project_name)
|
||||
|
||||
root_item = self.invisibleRootItem()
|
||||
|
||||
|
|
@ -1176,7 +1164,7 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
|
||||
headers = [item[0] for item in self.default_widths]
|
||||
|
||||
model = RepresentationModel(self.dbcon, headers, [])
|
||||
model = RepresentationModel(self.dbcon, headers)
|
||||
|
||||
proxy_model = RepresentationSortProxyModel(self)
|
||||
proxy_model.setSourceModel(model)
|
||||
|
|
@ -1213,8 +1201,8 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
self.proxy_model = proxy_model
|
||||
|
||||
self.sync_server_enabled = False
|
||||
actual_project = dbcon.Session["AVALON_PROJECT"]
|
||||
self.on_project_change(actual_project)
|
||||
|
||||
self.on_project_change(dbcon.current_project())
|
||||
|
||||
self.model.refresh()
|
||||
|
||||
|
|
@ -1243,23 +1231,18 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
for item in items:
|
||||
repre_ids.append(item["_id"])
|
||||
|
||||
repre_docs = list(self.dbcon.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"_id": {"$in": repre_ids}
|
||||
},
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
project_name = self.dbcon.active_project()
|
||||
repre_docs = list(get_representations(
|
||||
project_name,
|
||||
representation_ids=repre_ids,
|
||||
fields=["name", "parent"]
|
||||
))
|
||||
|
||||
version_ids = [
|
||||
repre_doc["parent"]
|
||||
for repre_doc in repre_docs
|
||||
]
|
||||
version_docs = self.dbcon.find({
|
||||
"_id": {"$in": version_ids}
|
||||
})
|
||||
version_docs = get_versions(project_name, version_ids=version_ids)
|
||||
|
||||
version_docs_by_id = {}
|
||||
version_docs_by_subset_id = collections.defaultdict(list)
|
||||
|
|
@ -1269,15 +1252,10 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
version_docs_by_id[version_id] = version_doc
|
||||
version_docs_by_subset_id[subset_id].append(version_doc)
|
||||
|
||||
subset_docs = list(self.dbcon.find(
|
||||
{
|
||||
"_id": {"$in": list(version_docs_by_subset_id.keys())},
|
||||
"type": "subset"
|
||||
},
|
||||
{
|
||||
"schema": 1,
|
||||
"data.families": 1
|
||||
}
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
subset_ids=version_docs_by_subset_id.keys(),
|
||||
fields=["schema", "data.families"]
|
||||
))
|
||||
subset_docs_by_id = {
|
||||
subset_doc["_id"]: subset_doc
|
||||
|
|
@ -1446,13 +1424,12 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
self._process_action(items, menu, point)
|
||||
|
||||
def _process_action(self, items, menu, point):
|
||||
"""
|
||||
Show the context action menu and process selected
|
||||
"""Show the context action menu and process selected
|
||||
|
||||
Args:
|
||||
items(dict): menu items
|
||||
menu(OptionalMenu)
|
||||
point(PointIndex)
|
||||
Args:
|
||||
items(dict): menu items
|
||||
menu(OptionalMenu)
|
||||
point(PointIndex)
|
||||
"""
|
||||
global_point = self.tree_view.mapToGlobal(point)
|
||||
action = menu.exec_(global_point)
|
||||
|
|
@ -1468,21 +1445,23 @@ class RepresentationWidget(QtWidgets.QWidget):
|
|||
data_by_repre_id = {}
|
||||
selected_side = action_representation.get("selected_side")
|
||||
|
||||
is_sync_loader = tools_lib.is_sync_loader(loader)
|
||||
for item in items:
|
||||
if tools_lib.is_sync_loader(loader):
|
||||
site_name = "{}_site_name".format(selected_side)
|
||||
data = {
|
||||
"_id": item.get("_id"),
|
||||
"site_name": item.get(site_name),
|
||||
"project_name": self.dbcon.Session["AVALON_PROJECT"]
|
||||
}
|
||||
item_id = item.get("_id")
|
||||
repre_ids.append(item_id)
|
||||
if not is_sync_loader:
|
||||
continue
|
||||
|
||||
if not data["site_name"]:
|
||||
continue
|
||||
site_name = "{}_site_name".format(selected_side)
|
||||
data_site_name = item.get(site_name)
|
||||
if not data_site_name:
|
||||
continue
|
||||
|
||||
data_by_repre_id[data["_id"]] = data
|
||||
|
||||
repre_ids.append(item.get("_id"))
|
||||
data_by_repre_id[item_id] = {
|
||||
"_id": item_id,
|
||||
"site_name": data_site_name,
|
||||
"project_name": self.dbcon.active_project()
|
||||
}
|
||||
|
||||
repre_contexts = get_repres_contexts(repre_ids, self.dbcon)
|
||||
options = lib.get_options(action, loader, self,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import logging
|
|||
|
||||
from Qt import QtWidgets, QtCore
|
||||
|
||||
from openpype.client import get_last_version_by_subset_id
|
||||
from openpype import style
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.tools.utils.lib import qt_app_context
|
||||
|
|
@ -211,6 +212,7 @@ class MayaLookAssignerWindow(QtWidgets.QWidget):
|
|||
selection = self.assign_selected.isChecked()
|
||||
asset_nodes = self.asset_outliner.get_nodes(selection=selection)
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
start = time.time()
|
||||
for i, (asset, item) in enumerate(asset_nodes.items()):
|
||||
|
||||
|
|
@ -222,23 +224,20 @@ class MayaLookAssignerWindow(QtWidgets.QWidget):
|
|||
assign_look = next((subset for subset in item["looks"]
|
||||
if subset["name"] in looks), None)
|
||||
if not assign_look:
|
||||
self.echo("{} No matching selected "
|
||||
"look for {}".format(prefix, asset))
|
||||
self.echo(
|
||||
"{} No matching selected look for {}".format(prefix, asset)
|
||||
)
|
||||
continue
|
||||
|
||||
# Get the latest version of this asset's look subset
|
||||
version = legacy_io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": assign_look["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
version = get_last_version_by_subset_id(
|
||||
project_name, assign_look["_id"], fields=["_id"]
|
||||
)
|
||||
|
||||
subset_name = assign_look["name"]
|
||||
self.echo("{} Assigning {} to {}\t".format(prefix,
|
||||
subset_name,
|
||||
asset))
|
||||
self.echo("{} Assigning {} to {}\t".format(
|
||||
prefix, subset_name, asset
|
||||
))
|
||||
nodes = item["nodes"]
|
||||
|
||||
if cmds.pluginInfo('vrayformaya', query=True, loaded=True):
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ from collections import defaultdict
|
|||
import logging
|
||||
import os
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
import maya.cmds as cmds
|
||||
|
||||
from openpype.client import get_asset_by_id
|
||||
from openpype.pipeline import (
|
||||
legacy_io,
|
||||
remove_container,
|
||||
|
|
@ -159,11 +159,9 @@ def create_items_from_nodes(nodes):
|
|||
log.warning("No id hashes")
|
||||
return asset_view_items
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
for _id, id_nodes in id_hashes.items():
|
||||
asset = legacy_io.find_one(
|
||||
{"_id": ObjectId(_id)},
|
||||
projection={"name": True}
|
||||
)
|
||||
asset = get_asset_by_id(project_name, _id, fields=["name"])
|
||||
|
||||
# Skip if asset id is not found
|
||||
if not asset:
|
||||
|
|
@ -180,10 +178,12 @@ def create_items_from_nodes(nodes):
|
|||
namespace = get_namespace_from_node(node)
|
||||
namespaces.add(namespace)
|
||||
|
||||
asset_view_items.append({"label": asset["name"],
|
||||
"asset": asset,
|
||||
"looks": looks,
|
||||
"namespaces": namespaces})
|
||||
asset_view_items.append({
|
||||
"label": asset["name"],
|
||||
"asset": asset,
|
||||
"looks": looks,
|
||||
"namespaces": namespaces
|
||||
})
|
||||
|
||||
return asset_view_items
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,14 @@ import logging
|
|||
import json
|
||||
|
||||
import six
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
import alembic.Abc
|
||||
from maya import cmds
|
||||
|
||||
from openpype.client import (
|
||||
get_representation_by_name,
|
||||
get_last_version_by_subset_name,
|
||||
)
|
||||
from openpype.pipeline import (
|
||||
legacy_io,
|
||||
load_container,
|
||||
|
|
@ -155,13 +158,12 @@ def get_look_relationships(version_id):
|
|||
|
||||
Returns:
|
||||
dict: Dictionary of relations.
|
||||
|
||||
"""
|
||||
json_representation = legacy_io.find_one({
|
||||
"type": "representation",
|
||||
"parent": version_id,
|
||||
"name": "json"
|
||||
})
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
json_representation = get_representation_by_name(
|
||||
project_name, representation_name="json", version_id=version_id
|
||||
)
|
||||
|
||||
# Load relationships
|
||||
shader_relation = get_representation_path(json_representation)
|
||||
|
|
@ -184,12 +186,12 @@ def load_look(version_id):
|
|||
list of shader nodes.
|
||||
|
||||
"""
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
# Get representations of shader file and relationships
|
||||
look_representation = legacy_io.find_one({
|
||||
"type": "representation",
|
||||
"parent": version_id,
|
||||
"name": "ma"
|
||||
})
|
||||
look_representation = get_representation_by_name(
|
||||
project_name, representation_name="ma", version_id=version_id
|
||||
)
|
||||
|
||||
# See if representation is already loaded, if so reuse it.
|
||||
host = registered_host()
|
||||
|
|
@ -220,42 +222,6 @@ def load_look(version_id):
|
|||
return shader_nodes
|
||||
|
||||
|
||||
def get_latest_version(asset_id, subset):
|
||||
# type: (str, str) -> dict
|
||||
"""Get latest version of subset.
|
||||
|
||||
Args:
|
||||
asset_id (str): Asset ID
|
||||
subset (str): Subset name.
|
||||
|
||||
Returns:
|
||||
Latest version
|
||||
|
||||
Throws:
|
||||
RuntimeError: When subset or version doesn't exist.
|
||||
|
||||
"""
|
||||
subset = legacy_io.find_one({
|
||||
"name": subset,
|
||||
"parent": ObjectId(asset_id),
|
||||
"type": "subset"
|
||||
})
|
||||
if not subset:
|
||||
raise RuntimeError("Subset does not exist: %s" % subset)
|
||||
|
||||
version = legacy_io.find_one(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": subset["_id"]
|
||||
},
|
||||
sort=[("name", -1)]
|
||||
)
|
||||
if not version:
|
||||
raise RuntimeError("Version does not exist.")
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def vrayproxy_assign_look(vrayproxy, subset="lookDefault"):
|
||||
# type: (str, str) -> None
|
||||
"""Assign look to vray proxy.
|
||||
|
|
@ -281,13 +247,20 @@ def vrayproxy_assign_look(vrayproxy, subset="lookDefault"):
|
|||
asset_id = node_id.split(":", 1)[0]
|
||||
node_ids_by_asset_id[asset_id].add(node_id)
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
for asset_id, node_ids in node_ids_by_asset_id.items():
|
||||
|
||||
# Get latest look version
|
||||
try:
|
||||
version = get_latest_version(asset_id, subset=subset)
|
||||
except RuntimeError as exc:
|
||||
print(exc)
|
||||
version = get_last_version_by_subset_name(
|
||||
project_name,
|
||||
subset_name=subset,
|
||||
asset_id=asset_id,
|
||||
fields=["_id"]
|
||||
)
|
||||
if not version:
|
||||
print("Didn't find last version for subset name {}".format(
|
||||
subset
|
||||
))
|
||||
continue
|
||||
|
||||
relationships = get_look_relationships(version["_id"])
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ from pymongo import UpdateOne, DeleteOne
|
|||
|
||||
from Qt import QtCore, QtGui
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_assets,
|
||||
get_asset_ids_with_subsets,
|
||||
)
|
||||
from openpype.lib import (
|
||||
CURRENT_DOC_SCHEMAS,
|
||||
PypeLogger,
|
||||
|
|
@ -255,10 +260,11 @@ class HierarchyModel(QtCore.QAbstractItemModel):
|
|||
return
|
||||
|
||||
# Find project'd document
|
||||
project_doc = self.dbcon.database[project_name].find_one(
|
||||
{"type": "project"},
|
||||
ProjectItem.query_projection
|
||||
project_doc = get_project(
|
||||
project_name,
|
||||
fields=list(ProjectItem.query_projection.keys())
|
||||
)
|
||||
|
||||
# Skip if project document does not exist
|
||||
# - this shouldn't happen using only UI elements
|
||||
if not project_doc:
|
||||
|
|
@ -269,9 +275,8 @@ class HierarchyModel(QtCore.QAbstractItemModel):
|
|||
self.add_item(project_item)
|
||||
|
||||
# Query all assets of the project
|
||||
asset_docs = self.dbcon.database[project_name].find(
|
||||
{"type": "asset"},
|
||||
AssetItem.query_projection
|
||||
asset_docs = get_assets(
|
||||
project_name, fields=AssetItem.query_projection.keys()
|
||||
)
|
||||
asset_docs_by_id = {
|
||||
asset_doc["_id"]: asset_doc
|
||||
|
|
@ -282,31 +287,16 @@ class HierarchyModel(QtCore.QAbstractItemModel):
|
|||
# if asset item can be modified (name and hierarchy change)
|
||||
# - the same must be applied to all it's parents
|
||||
asset_ids = list(asset_docs_by_id.keys())
|
||||
result = []
|
||||
asset_ids_with_subsets = []
|
||||
if asset_ids:
|
||||
result = self.dbcon.database[project_name].aggregate([
|
||||
{
|
||||
"$match": {
|
||||
"type": "subset",
|
||||
"parent": {"$in": asset_ids}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$group": {
|
||||
"_id": "$parent",
|
||||
"count": {"$sum": 1}
|
||||
}
|
||||
}
|
||||
])
|
||||
asset_ids_with_subsets = get_asset_ids_with_subsets(
|
||||
project_name, asset_ids=asset_ids
|
||||
)
|
||||
|
||||
asset_modifiable = {
|
||||
asset_id: True
|
||||
asset_id: asset_id not in asset_ids_with_subsets
|
||||
for asset_id in asset_docs_by_id.keys()
|
||||
}
|
||||
for item in result:
|
||||
asset_id = item["_id"]
|
||||
count = item["count"]
|
||||
asset_modifiable[asset_id] = count < 1
|
||||
|
||||
# Store assets by their visual parent to be able create their hierarchy
|
||||
asset_docs_by_parent_id = collections.defaultdict(list)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from queue import Queue
|
|||
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype.client import get_project
|
||||
from .delegates import (
|
||||
NumberDelegate,
|
||||
NameDelegate,
|
||||
|
|
@ -47,12 +48,8 @@ class ProjectDocCache:
|
|||
def set_project(self, project_name):
|
||||
self.project_doc = None
|
||||
|
||||
if not project_name:
|
||||
return
|
||||
|
||||
self.project_doc = self.dbcon.database[project_name].find_one(
|
||||
{"type": "project"}
|
||||
)
|
||||
if project_name:
|
||||
self.project_doc = get_project(project_name)
|
||||
|
||||
|
||||
class ToolsCache:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import re
|
||||
|
||||
from openpype.client import get_projects
|
||||
from .constants import (
|
||||
NAME_ALLOWED_SYMBOLS,
|
||||
NAME_REGEX
|
||||
|
|
@ -272,15 +273,9 @@ class CreateProjectDialog(QtWidgets.QDialog):
|
|||
def _get_existing_projects(self):
|
||||
project_names = set()
|
||||
project_codes = set()
|
||||
for project_name in self.dbcon.database.collection_names():
|
||||
# Each collection will have exactly one project document
|
||||
project_doc = self.dbcon.database[project_name].find_one(
|
||||
{"type": "project"},
|
||||
{"name": 1, "data.code": 1}
|
||||
)
|
||||
if not project_doc:
|
||||
continue
|
||||
|
||||
for project_doc in get_projects(
|
||||
inactive=True, fields=["name", "data.code"]
|
||||
):
|
||||
project_name = project_doc.get("name")
|
||||
if not project_name:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ except Exception:
|
|||
|
||||
import pyblish.api
|
||||
|
||||
from openpype.client import get_assets
|
||||
from openpype.pipeline import (
|
||||
PublishValidationError,
|
||||
registered_host,
|
||||
|
|
@ -116,10 +117,10 @@ class AssetDocsCache:
|
|||
|
||||
def _query(self):
|
||||
if self._asset_docs is None:
|
||||
asset_docs = list(self.dbcon.find(
|
||||
{"type": "asset"},
|
||||
self.projection
|
||||
))
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_docs = get_assets(
|
||||
project_name, fields=self.projection.keys()
|
||||
)
|
||||
task_names_by_asset_name = {}
|
||||
for asset_doc in asset_docs:
|
||||
asset_name = asset_doc["name"]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ try:
|
|||
except Exception:
|
||||
commonmark = None
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype.client import get_asset_by_name, get_subsets
|
||||
from openpype.lib import TaskNotSetError
|
||||
from openpype.pipeline.create import (
|
||||
CreatorError,
|
||||
|
|
@ -647,21 +649,19 @@ class CreateDialog(QtWidgets.QDialog):
|
|||
if asset_name is None:
|
||||
return
|
||||
|
||||
asset_doc = self.dbcon.find_one({
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
})
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_doc = get_asset_by_name(project_name, asset_name)
|
||||
self._asset_doc = asset_doc
|
||||
|
||||
if asset_doc:
|
||||
subset_docs = self.dbcon.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"]
|
||||
},
|
||||
{"name": 1}
|
||||
asset_id = asset_doc["_id"]
|
||||
subset_docs = get_subsets(
|
||||
project_name, asset_ids=[asset_id], fields=["name"]
|
||||
)
|
||||
self._subset_names = set(subset_docs.distinct("name"))
|
||||
self._subset_names = {
|
||||
subset_doc["name"]
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
|
||||
if not asset_doc:
|
||||
self.subset_name_input.setText("< Asset is not set >")
|
||||
|
|
|
|||
|
|
@ -5,8 +5,14 @@ from collections import defaultdict
|
|||
|
||||
from Qt import QtCore, QtGui
|
||||
import qtawesome
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
from openpype.client import (
|
||||
get_asset_by_id,
|
||||
get_subset_by_id,
|
||||
get_version_by_id,
|
||||
get_last_version_by_subset_id,
|
||||
get_representation_by_id,
|
||||
)
|
||||
from openpype.pipeline import (
|
||||
legacy_io,
|
||||
schema,
|
||||
|
|
@ -55,7 +61,7 @@ class InventoryModel(TreeModel):
|
|||
if not self.sync_enabled:
|
||||
return
|
||||
|
||||
project_name = legacy_io.Session["AVALON_PROJECT"]
|
||||
project_name = legacy_io.current_project()
|
||||
active_site = sync_server.get_active_site(project_name)
|
||||
remote_site = sync_server.get_remote_site(project_name)
|
||||
|
||||
|
|
@ -192,12 +198,12 @@ class InventoryModel(TreeModel):
|
|||
self.clear()
|
||||
|
||||
if self._hierarchy_view and selected:
|
||||
|
||||
if not hasattr(host.pipeline, "update_hierarchy"):
|
||||
# If host doesn't support hierarchical containers, then
|
||||
# cherry-pick only.
|
||||
self.add_items((item for item in items
|
||||
if item["objectName"] in selected))
|
||||
return
|
||||
|
||||
# Update hierarchy info for all containers
|
||||
items_by_name = {item["objectName"]: item
|
||||
|
|
@ -291,6 +297,9 @@ class InventoryModel(TreeModel):
|
|||
node.Item: root node which has children added based on the data
|
||||
"""
|
||||
|
||||
# NOTE: @iLLiCiTiT this need refactor
|
||||
project_name = legacy_io.active_project()
|
||||
|
||||
self.beginResetModel()
|
||||
|
||||
# Group by representation
|
||||
|
|
@ -304,32 +313,36 @@ class InventoryModel(TreeModel):
|
|||
for repre_id, group_dict in sorted(grouped.items()):
|
||||
group_items = group_dict["items"]
|
||||
# Get parenthood per group
|
||||
representation = legacy_io.find_one({"_id": ObjectId(repre_id)})
|
||||
representation = get_representation_by_id(
|
||||
project_name, repre_id
|
||||
)
|
||||
if not representation:
|
||||
not_found["representation"].append(group_items)
|
||||
not_found_ids.append(repre_id)
|
||||
continue
|
||||
|
||||
version = legacy_io.find_one({"_id": representation["parent"]})
|
||||
version = get_version_by_id(
|
||||
project_name, representation["parent"]
|
||||
)
|
||||
if not version:
|
||||
not_found["version"].append(group_items)
|
||||
not_found_ids.append(repre_id)
|
||||
continue
|
||||
|
||||
elif version["type"] == "hero_version":
|
||||
_version = legacy_io.find_one({
|
||||
"_id": version["version_id"]
|
||||
})
|
||||
_version = get_version_by_id(
|
||||
project_name, version["version_id"]
|
||||
)
|
||||
version["name"] = HeroVersionType(_version["name"])
|
||||
version["data"] = _version["data"]
|
||||
|
||||
subset = legacy_io.find_one({"_id": version["parent"]})
|
||||
subset = get_subset_by_id(project_name, version["parent"])
|
||||
if not subset:
|
||||
not_found["subset"].append(group_items)
|
||||
not_found_ids.append(repre_id)
|
||||
continue
|
||||
|
||||
asset = legacy_io.find_one({"_id": subset["parent"]})
|
||||
asset = get_asset_by_id(project_name, subset["parent"])
|
||||
if not asset:
|
||||
not_found["asset"].append(group_items)
|
||||
not_found_ids.append(repre_id)
|
||||
|
|
@ -390,10 +403,9 @@ class InventoryModel(TreeModel):
|
|||
|
||||
# Store the highest available version so the model can know
|
||||
# whether current version is currently up-to-date.
|
||||
highest_version = legacy_io.find_one({
|
||||
"type": "version",
|
||||
"parent": version["parent"]
|
||||
}, sort=[("name", -1)])
|
||||
highest_version = get_last_version_by_subset_id(
|
||||
project_name, version["parent"]
|
||||
)
|
||||
|
||||
# create the group header
|
||||
group_node = Item()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@ from Qt import QtWidgets, QtCore
|
|||
import qtawesome
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
from openpype.client import (
|
||||
get_asset_by_name,
|
||||
get_assets,
|
||||
get_subset_by_name,
|
||||
get_subsets,
|
||||
get_versions,
|
||||
get_hero_versions,
|
||||
get_last_versions,
|
||||
get_representations,
|
||||
)
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.pipeline.load import (
|
||||
discover_loader_plugins,
|
||||
|
|
@ -144,6 +154,9 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
self._prepare_content_data()
|
||||
self.refresh(True)
|
||||
|
||||
def active_project(self):
|
||||
return legacy_io.active_project()
|
||||
|
||||
def _prepare_content_data(self):
|
||||
repre_ids = set()
|
||||
content_loaders = set()
|
||||
|
|
@ -151,10 +164,12 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
repre_ids.add(ObjectId(item["representation"]))
|
||||
content_loaders.add(item["loader"])
|
||||
|
||||
repres = list(legacy_io.find({
|
||||
"type": {"$in": ["representation", "archived_representation"]},
|
||||
"_id": {"$in": list(repre_ids)}
|
||||
}))
|
||||
project_name = self.active_project()
|
||||
repres = list(get_representations(
|
||||
project_name,
|
||||
representation_ids=repre_ids,
|
||||
archived=True
|
||||
))
|
||||
repres_by_id = {repre["_id"]: repre for repre in repres}
|
||||
|
||||
# stash context values, works only for single representation
|
||||
|
|
@ -179,10 +194,11 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
content_repres[repre_id] = repres_by_id[repre_id]
|
||||
version_ids.append(repre["parent"])
|
||||
|
||||
versions = legacy_io.find({
|
||||
"type": {"$in": ["version", "hero_version"]},
|
||||
"_id": {"$in": list(set(version_ids))}
|
||||
})
|
||||
versions = get_versions(
|
||||
project_name,
|
||||
version_ids=set(version_ids),
|
||||
hero=True
|
||||
)
|
||||
content_versions = {}
|
||||
hero_version_ids = set()
|
||||
for version in versions:
|
||||
|
|
@ -198,10 +214,9 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
else:
|
||||
subset_ids.append(content_versions[version_id]["parent"])
|
||||
|
||||
subsets = legacy_io.find({
|
||||
"type": {"$in": ["subset", "archived_subset"]},
|
||||
"_id": {"$in": subset_ids}
|
||||
})
|
||||
subsets = get_subsets(
|
||||
project_name, subset_ids=subset_ids, archived=True
|
||||
)
|
||||
subsets_by_id = {sub["_id"]: sub for sub in subsets}
|
||||
|
||||
asset_ids = []
|
||||
|
|
@ -220,10 +235,7 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
asset_ids.append(subset["parent"])
|
||||
content_subsets[subset_id] = subset
|
||||
|
||||
assets = legacy_io.find({
|
||||
"type": {"$in": ["asset", "archived_asset"]},
|
||||
"_id": {"$in": list(asset_ids)}
|
||||
})
|
||||
assets = get_assets(project_name, asset_ids=asset_ids, archived=True)
|
||||
assets_by_id = {asset["_id"]: asset for asset in assets}
|
||||
|
||||
missing_assets = []
|
||||
|
|
@ -472,9 +484,10 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
# Prepare asset document if asset is selected
|
||||
asset_doc = None
|
||||
if selected_asset:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": True}
|
||||
asset_doc = get_asset_by_name(
|
||||
self.active_project(),
|
||||
selected_asset,
|
||||
fields=["_id"]
|
||||
)
|
||||
if not asset_doc:
|
||||
return []
|
||||
|
|
@ -523,38 +536,35 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
def _get_current_output_repre_ids_xxx(
|
||||
self, asset_doc, selected_subset, selected_repre
|
||||
):
|
||||
subset_doc = legacy_io.find_one(
|
||||
{
|
||||
"type": "subset",
|
||||
"name": selected_subset,
|
||||
"parent": asset_doc["_id"]
|
||||
},
|
||||
{"_id": True}
|
||||
project_name = self.active_project()
|
||||
subset_doc = get_subset_by_name(
|
||||
project_name,
|
||||
selected_subset,
|
||||
asset_doc["_id"],
|
||||
fields=["_id"]
|
||||
)
|
||||
|
||||
subset_id = subset_doc["_id"]
|
||||
last_versions_by_subset_id = self.find_last_versions([subset_id])
|
||||
version_doc = last_versions_by_subset_id.get(subset_id)
|
||||
if not version_doc:
|
||||
return []
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": version_doc["_id"],
|
||||
"name": selected_repre
|
||||
},
|
||||
{"_id": True}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=[version_doc["_id"]],
|
||||
representation_names=[selected_repre],
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_xxo(self, asset_doc, selected_subset):
|
||||
subset_doc = legacy_io.find_one(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"],
|
||||
"name": selected_subset
|
||||
},
|
||||
{"_id": True}
|
||||
project_name = self.active_project()
|
||||
subset_doc = get_subset_by_name(
|
||||
project_name,
|
||||
selected_subset,
|
||||
asset_doc["_id"],
|
||||
fields=["_id"]
|
||||
)
|
||||
if not subset_doc:
|
||||
return []
|
||||
|
|
@ -563,41 +573,51 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
for repre_doc in self.content_repres.values():
|
||||
repre_names.add(repre_doc["name"])
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": subset_doc["_id"],
|
||||
"name": {"$in": list(repre_names)}
|
||||
},
|
||||
{"_id": True}
|
||||
# TODO where to take version ids?
|
||||
version_ids = []
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
representation_names=repre_names,
|
||||
version_ids=version_ids,
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_xox(self, asset_doc, selected_repre):
|
||||
susbet_names = set()
|
||||
subset_names = set()
|
||||
for subset_doc in self.content_subsets.values():
|
||||
susbet_names.add(subset_doc["name"])
|
||||
subset_names.add(subset_doc["name"])
|
||||
|
||||
subset_docs = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"name": {"$in": list(susbet_names)},
|
||||
"parent": asset_doc["_id"]
|
||||
},
|
||||
{"_id": True}
|
||||
project_name = self.active_project()
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=[asset_doc["_id"]],
|
||||
subset_names=subset_names,
|
||||
fields=["_id", "name"]
|
||||
)
|
||||
subset_ids = [subset_doc["_id"] for subset_doc in subset_docs]
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": subset_ids},
|
||||
"name": selected_repre
|
||||
},
|
||||
{"_id": True}
|
||||
subset_name_by_id = {
|
||||
subset_doc["_id"]: subset_doc["name"]
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
subset_ids = list(subset_name_by_id.keys())
|
||||
last_versions_by_subset_id = self.find_last_versions(subset_ids)
|
||||
last_version_id_by_subset_name = {}
|
||||
for subset_id, last_version in last_versions_by_subset_id.items():
|
||||
subset_name = subset_name_by_id[subset_id]
|
||||
last_version_id_by_subset_name[subset_name] = (
|
||||
last_version["_id"]
|
||||
)
|
||||
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=last_version_id_by_subset_name.values(),
|
||||
representation_names=[selected_repre],
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_xoo(self, asset_doc):
|
||||
project_name = self.active_project()
|
||||
repres_by_subset_name = collections.defaultdict(set)
|
||||
for repre_doc in self.content_repres.values():
|
||||
repre_name = repre_doc["name"]
|
||||
|
|
@ -606,13 +626,11 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
subset_name = subset_doc["name"]
|
||||
repres_by_subset_name[subset_name].add(repre_name)
|
||||
|
||||
subset_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"],
|
||||
"name": {"$in": list(repres_by_subset_name.keys())}
|
||||
},
|
||||
{"_id": True, "name": True}
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
asset_ids=[asset_doc["_id"]],
|
||||
subset_names=repres_by_subset_name.keys(),
|
||||
fields=["_id", "name"]
|
||||
))
|
||||
subset_name_by_id = {
|
||||
subset_doc["_id"]: subset_doc["name"]
|
||||
|
|
@ -627,60 +645,59 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
last_version["_id"]
|
||||
)
|
||||
|
||||
repre_or_query = []
|
||||
repre_names_by_version_id = {}
|
||||
for subset_name, repre_names in repres_by_subset_name.items():
|
||||
version_id = last_version_id_by_subset_name.get(subset_name)
|
||||
# This should not happen but why to crash?
|
||||
if version_id is None:
|
||||
continue
|
||||
repre_or_query.append({
|
||||
"parent": version_id,
|
||||
"name": {"$in": list(repre_names)}
|
||||
})
|
||||
repre_docs = legacy_io.find(
|
||||
{"$or": repre_or_query},
|
||||
{"_id": True}
|
||||
if version_id is not None:
|
||||
repre_names_by_version_id[version_id] = list(repre_names)
|
||||
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
names_by_version_ids=repre_names_by_version_id,
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_oxx(
|
||||
self, selected_subset, selected_repre
|
||||
):
|
||||
subset_docs = list(legacy_io.find({
|
||||
"type": "subset",
|
||||
"parent": {"$in": list(self.content_assets.keys())},
|
||||
"name": selected_subset
|
||||
}))
|
||||
project_name = self.active_project()
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=self.content_assets.keys(),
|
||||
subset_names=[selected_subset],
|
||||
fields=["_id"]
|
||||
)
|
||||
subset_ids = [subset_doc["_id"] for subset_doc in subset_docs]
|
||||
last_versions_by_subset_id = self.find_last_versions(subset_ids)
|
||||
last_version_ids = [
|
||||
last_version["_id"]
|
||||
for last_version in last_versions_by_subset_id.values()
|
||||
]
|
||||
repre_docs = legacy_io.find({
|
||||
"type": "representation",
|
||||
"parent": {"$in": last_version_ids},
|
||||
"name": selected_repre
|
||||
})
|
||||
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=last_version_ids,
|
||||
representation_names=[selected_repre],
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_oxo(self, selected_subset):
|
||||
subset_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": list(self.content_assets.keys())},
|
||||
"name": selected_subset
|
||||
},
|
||||
{"_id": True, "parent": True}
|
||||
))
|
||||
if not subset_docs:
|
||||
return list()
|
||||
|
||||
project_name = self.active_project()
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=self.content_assets.keys(),
|
||||
subset_names=[selected_subset],
|
||||
fields=["_id", "parent"]
|
||||
)
|
||||
subset_docs_by_id = {
|
||||
subset_doc["_id"]: subset_doc
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
if not subset_docs:
|
||||
return list()
|
||||
|
||||
last_versions_by_subset_id = self.find_last_versions(
|
||||
subset_docs_by_id.keys()
|
||||
)
|
||||
|
|
@ -702,56 +719,44 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
asset_id = asset_doc["_id"]
|
||||
repre_names_by_asset_id[asset_id].add(repre_name)
|
||||
|
||||
repre_or_query = []
|
||||
repre_names_by_version_id = {}
|
||||
for last_version_id, subset_id in subset_id_by_version_id.items():
|
||||
subset_doc = subset_docs_by_id[subset_id]
|
||||
asset_id = subset_doc["parent"]
|
||||
repre_names = repre_names_by_asset_id.get(asset_id)
|
||||
if not repre_names:
|
||||
continue
|
||||
repre_or_query.append({
|
||||
"parent": last_version_id,
|
||||
"name": {"$in": list(repre_names)}
|
||||
})
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"$or": repre_or_query
|
||||
},
|
||||
{"_id": True}
|
||||
)
|
||||
repre_names_by_version_id[last_version_id] = repre_names
|
||||
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
names_by_version_ids=repre_names_by_version_id,
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_current_output_repre_ids_oox(self, selected_repre):
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"name": selected_repre,
|
||||
"parent": {"$in": list(self.content_versions.keys())}
|
||||
},
|
||||
{"_id": True}
|
||||
project_name = self.active_project()
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
representation_names=[selected_repre],
|
||||
version_ids=self.content_versions.keys(),
|
||||
fields=["_id"]
|
||||
)
|
||||
return [repre_doc["_id"] for repre_doc in repre_docs]
|
||||
|
||||
def _get_asset_box_values(self):
|
||||
asset_docs = legacy_io.find(
|
||||
{"type": "asset"},
|
||||
{"_id": 1, "name": 1}
|
||||
)
|
||||
project_name = self.active_project()
|
||||
asset_docs = get_assets(project_name, fields=["_id", "name"])
|
||||
asset_names_by_id = {
|
||||
asset_doc["_id"]: asset_doc["name"]
|
||||
for asset_doc in asset_docs
|
||||
}
|
||||
subsets = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": list(asset_names_by_id.keys())}
|
||||
},
|
||||
{
|
||||
"parent": 1
|
||||
}
|
||||
subsets = get_subsets(
|
||||
project_name,
|
||||
asset_ids=asset_names_by_id.keys(),
|
||||
fields=["parent"]
|
||||
)
|
||||
|
||||
filtered_assets = []
|
||||
for subset in subsets:
|
||||
asset_name = asset_names_by_id[subset["parent"]]
|
||||
|
|
@ -760,25 +765,20 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
return sorted(filtered_assets)
|
||||
|
||||
def _get_subset_box_values(self):
|
||||
project_name = self.active_project()
|
||||
selected_asset = self._assets_box.get_valid_value()
|
||||
if selected_asset:
|
||||
asset_doc = legacy_io.find_one({
|
||||
"type": "asset",
|
||||
"name": selected_asset
|
||||
})
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
asset_ids = [asset_doc["_id"]]
|
||||
else:
|
||||
asset_ids = list(self.content_assets.keys())
|
||||
|
||||
subsets = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": asset_ids}
|
||||
},
|
||||
{
|
||||
"parent": 1,
|
||||
"name": 1
|
||||
}
|
||||
subsets = get_subsets(
|
||||
project_name,
|
||||
asset_ids=asset_ids,
|
||||
fields=["parent", "name"]
|
||||
)
|
||||
|
||||
subset_names_by_parent_id = collections.defaultdict(set)
|
||||
|
|
@ -800,6 +800,7 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
def _representations_box_values(self):
|
||||
# NOTE hero versions are not used because it is expected that
|
||||
# hero version has same representations as latests
|
||||
project_name = self.active_project()
|
||||
selected_asset = self._assets_box.currentText()
|
||||
selected_subset = self._subsets_box.currentText()
|
||||
|
||||
|
|
@ -807,16 +808,11 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
# [ ] [ ] [?]
|
||||
if not selected_asset and not selected_subset:
|
||||
# Find all representations of selection's subsets
|
||||
possible_repres = list(legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": list(self.content_versions.keys())}
|
||||
},
|
||||
{
|
||||
"parent": 1,
|
||||
"name": 1
|
||||
}
|
||||
))
|
||||
possible_repres = get_representations(
|
||||
project_name,
|
||||
version_ids=self.content_versions.keys(),
|
||||
fields=["parent", "name"]
|
||||
)
|
||||
|
||||
possible_repres_by_parent = collections.defaultdict(set)
|
||||
for repre in possible_repres:
|
||||
|
|
@ -836,29 +832,23 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
|
||||
# [x] [x] [?]
|
||||
if selected_asset and selected_subset:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
subset_doc = legacy_io.find_one(
|
||||
{
|
||||
"type": "subset",
|
||||
"name": selected_subset,
|
||||
"parent": asset_doc["_id"]
|
||||
},
|
||||
{"_id": 1}
|
||||
subset_doc = get_subset_by_name(
|
||||
project_name,
|
||||
selected_subset,
|
||||
asset_doc["_id"],
|
||||
fields=["_id"]
|
||||
)
|
||||
|
||||
subset_id = subset_doc["_id"]
|
||||
last_versions_by_subset_id = self.find_last_versions([subset_id])
|
||||
version_doc = last_versions_by_subset_id.get(subset_id)
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": version_doc["_id"]
|
||||
},
|
||||
{
|
||||
"name": 1
|
||||
}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=[version_doc["_id"]],
|
||||
fields=["name"]
|
||||
)
|
||||
return [
|
||||
repre_doc["name"]
|
||||
|
|
@ -868,9 +858,8 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
# [x] [ ] [?]
|
||||
# If asset only is selected
|
||||
if selected_asset:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
if not asset_doc:
|
||||
return list()
|
||||
|
|
@ -879,13 +868,12 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
subset_names = set()
|
||||
for subset_doc in self.content_subsets.values():
|
||||
subset_names.add(subset_doc["name"])
|
||||
subset_docs = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"],
|
||||
"name": {"$in": list(subset_names)}
|
||||
},
|
||||
{"_id": 1}
|
||||
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=[asset_doc["_id"]],
|
||||
subset_names=subset_names,
|
||||
fields=["_id"]
|
||||
)
|
||||
subset_ids = [
|
||||
subset_doc["_id"]
|
||||
|
|
@ -903,15 +891,10 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
if not subset_id_by_version_id:
|
||||
return list()
|
||||
|
||||
repre_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": list(subset_id_by_version_id.keys())}
|
||||
},
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
repre_docs = list(get_representations(
|
||||
project_name,
|
||||
version_ids=subset_id_by_version_id.keys(),
|
||||
fields=["name", "parent"]
|
||||
))
|
||||
if not repre_docs:
|
||||
return list()
|
||||
|
|
@ -933,13 +916,11 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
return list(available_repres)
|
||||
|
||||
# [ ] [x] [?]
|
||||
subset_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": list(self.content_assets.keys())},
|
||||
"name": selected_subset
|
||||
},
|
||||
{"_id": 1, "parent": 1}
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
asset_ids=self.content_assets.keys(),
|
||||
subset_names=[selected_subset],
|
||||
fields=["_id", "parent"]
|
||||
))
|
||||
if not subset_docs:
|
||||
return list()
|
||||
|
|
@ -960,16 +941,13 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
if not subset_id_by_version_id:
|
||||
return list()
|
||||
|
||||
repre_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": list(subset_id_by_version_id.keys())}
|
||||
},
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
))
|
||||
repre_docs = list(
|
||||
get_representations(
|
||||
project_name,
|
||||
version_ids=subset_id_by_version_id.keys(),
|
||||
fields=["name", "parent"]
|
||||
)
|
||||
)
|
||||
if not repre_docs:
|
||||
return list()
|
||||
|
||||
|
|
@ -1016,14 +994,14 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
return
|
||||
|
||||
# [x] [ ] [?]
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": 1}
|
||||
project_name = self.active_project()
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
subset_docs = legacy_io.find(
|
||||
{"type": "subset", "parent": asset_doc["_id"]},
|
||||
{"name": 1}
|
||||
subset_docs = get_subsets(
|
||||
project_name, asset_ids=[asset_doc["_id"]], fields=["name"]
|
||||
)
|
||||
|
||||
subset_names = set(
|
||||
subset_doc["name"]
|
||||
for subset_doc in subset_docs
|
||||
|
|
@ -1035,27 +1013,12 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
break
|
||||
|
||||
def find_last_versions(self, subset_ids):
|
||||
_pipeline = [
|
||||
# Find all versions of those subsets
|
||||
{"$match": {
|
||||
"type": "version",
|
||||
"parent": {"$in": list(subset_ids)}
|
||||
}},
|
||||
# Sorting versions all together
|
||||
{"$sort": {"name": 1}},
|
||||
# Group them by "parent", but only take the last
|
||||
{"$group": {
|
||||
"_id": "$parent",
|
||||
"_version_id": {"$last": "$_id"},
|
||||
"type": {"$last": "$type"}
|
||||
}}
|
||||
]
|
||||
last_versions_by_subset_id = dict()
|
||||
for doc in legacy_io.aggregate(_pipeline):
|
||||
doc["parent"] = doc["_id"]
|
||||
doc["_id"] = doc.pop("_version_id")
|
||||
last_versions_by_subset_id[doc["parent"]] = doc
|
||||
return last_versions_by_subset_id
|
||||
project_name = self.active_project()
|
||||
return get_last_versions(
|
||||
project_name,
|
||||
subset_ids=subset_ids,
|
||||
fields=["_id", "parent", "type"]
|
||||
)
|
||||
|
||||
def _is_repre_ok(self, validation_state):
|
||||
selected_asset = self._assets_box.get_valid_value()
|
||||
|
|
@ -1078,33 +1041,28 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
return
|
||||
|
||||
# [x] [x] [ ]
|
||||
project_name = self.active_project()
|
||||
if selected_asset is not None and selected_subset is not None:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
subset_doc = legacy_io.find_one(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"],
|
||||
"name": selected_subset
|
||||
},
|
||||
{"_id": 1}
|
||||
subset_doc = get_subset_by_name(
|
||||
project_name,
|
||||
selected_subset,
|
||||
asset_doc["_id"],
|
||||
fields=["_id"]
|
||||
)
|
||||
last_versions_by_subset_id = self.find_last_versions(
|
||||
[subset_doc["_id"]]
|
||||
)
|
||||
last_version = last_versions_by_subset_id.get(subset_doc["_id"])
|
||||
subset_id = subset_doc["_id"]
|
||||
last_versions_by_subset_id = self.find_last_versions([subset_id])
|
||||
last_version = last_versions_by_subset_id.get(subset_id)
|
||||
if not last_version:
|
||||
validation_state.repre_ok = False
|
||||
return
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": last_version["_id"]
|
||||
},
|
||||
{"name": 1}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=[last_version["_id"]],
|
||||
fields=["name"]
|
||||
)
|
||||
|
||||
repre_names = set(
|
||||
|
|
@ -1119,16 +1077,13 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
|
||||
# [x] [ ] [ ]
|
||||
if selected_asset is not None:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{"type": "asset", "name": selected_asset},
|
||||
{"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, selected_asset, fields=["_id"]
|
||||
)
|
||||
subset_docs = list(legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_doc["_id"]
|
||||
},
|
||||
{"_id": 1, "name": 1}
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
asset_ids=[asset_doc["_id"]],
|
||||
fields=["_id", "name"]
|
||||
))
|
||||
|
||||
subset_name_by_id = {}
|
||||
|
|
@ -1145,15 +1100,10 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
version_id = last_version["_id"]
|
||||
subset_id_by_version_id[version_id] = subset_id
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": list(subset_id_by_version_id.keys())}
|
||||
},
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=subset_id_by_version_id.keys(),
|
||||
fields=["name", "parent"]
|
||||
)
|
||||
repres_by_subset_name = {}
|
||||
for repre_doc in repre_docs:
|
||||
|
|
@ -1176,15 +1126,12 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
|
||||
# [ ] [x] [ ]
|
||||
# Subset documents
|
||||
subset_docs = legacy_io.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": {"$in": list(self.content_assets.keys())},
|
||||
"name": selected_subset
|
||||
},
|
||||
{"_id": 1, "name": 1, "parent": 1}
|
||||
subset_docs = get_subsets(
|
||||
project_name,
|
||||
asset_ids=self.content_assets.keys(),
|
||||
subset_names=[selected_subset],
|
||||
fields=["_id", "name", "parent"]
|
||||
)
|
||||
|
||||
subset_docs_by_id = {}
|
||||
for subset_doc in subset_docs:
|
||||
subset_docs_by_id[subset_doc["_id"]] = subset_doc
|
||||
|
|
@ -1197,15 +1144,10 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
version_id = last_version["_id"]
|
||||
subset_id_by_version_id[version_id] = subset_id
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": list(subset_id_by_version_id.keys())}
|
||||
},
|
||||
{
|
||||
"name": 1,
|
||||
"parent": 1
|
||||
}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
version_ids=subset_id_by_version_id.keys(),
|
||||
fields=["name", "parent"]
|
||||
)
|
||||
repres_by_asset_id = {}
|
||||
for repre_doc in repre_docs:
|
||||
|
|
@ -1245,11 +1187,9 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
selected_subset = self._subsets_box.get_valid_value()
|
||||
selected_representation = self._representations_box.get_valid_value()
|
||||
|
||||
project_name = self.active_project()
|
||||
if selected_asset:
|
||||
asset_doc = legacy_io.find_one({
|
||||
"type": "asset",
|
||||
"name": selected_asset
|
||||
})
|
||||
asset_doc = get_asset_by_name(project_name, selected_asset)
|
||||
asset_docs_by_id = {asset_doc["_id"]: asset_doc}
|
||||
else:
|
||||
asset_docs_by_id = self.content_assets
|
||||
|
|
@ -1259,16 +1199,15 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
for asset_doc in asset_docs_by_id.values()
|
||||
}
|
||||
|
||||
asset_ids = list(asset_docs_by_id.keys())
|
||||
|
||||
subset_query = {
|
||||
"type": "subset",
|
||||
"parent": {"$in": asset_ids}
|
||||
}
|
||||
subset_names = None
|
||||
if selected_subset:
|
||||
subset_query["name"] = selected_subset
|
||||
subset_names = [selected_subset]
|
||||
|
||||
subset_docs = list(legacy_io.find(subset_query))
|
||||
subset_docs = list(get_subsets(
|
||||
project_name,
|
||||
subset_names=subset_names,
|
||||
asset_ids=asset_docs_by_id.keys()
|
||||
))
|
||||
subset_ids = []
|
||||
subset_docs_by_parent_and_name = collections.defaultdict(dict)
|
||||
for subset in subset_docs:
|
||||
|
|
@ -1278,15 +1217,14 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
subset_docs_by_parent_and_name[parent_id][name] = subset
|
||||
|
||||
# versions
|
||||
version_docs = list(legacy_io.find({
|
||||
"type": "version",
|
||||
"parent": {"$in": subset_ids}
|
||||
}, sort=[("name", -1)]))
|
||||
_version_docs = get_versions(project_name, subset_ids=subset_ids)
|
||||
version_docs = list(reversed(
|
||||
sorted(_version_docs, key=lambda item: item["name"])
|
||||
))
|
||||
|
||||
hero_version_docs = list(legacy_io.find({
|
||||
"type": "hero_version",
|
||||
"parent": {"$in": subset_ids}
|
||||
}))
|
||||
hero_version_docs = list(get_hero_versions(
|
||||
project_name, subset_ids=subset_ids
|
||||
))
|
||||
|
||||
version_ids = list()
|
||||
|
||||
|
|
@ -1303,10 +1241,7 @@ class SwitchAssetDialog(QtWidgets.QDialog):
|
|||
parent_id = hero_version_doc["parent"]
|
||||
hero_version_docs_by_parent_id[parent_id] = hero_version_doc
|
||||
|
||||
repre_docs = legacy_io.find({
|
||||
"type": "representation",
|
||||
"parent": {"$in": version_ids}
|
||||
})
|
||||
repre_docs = get_representations(project_name, version_ids=version_ids)
|
||||
repre_docs_by_parent_id_by_name = collections.defaultdict(dict)
|
||||
for repre_doc in repre_docs:
|
||||
parent_id = repre_doc["parent"]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ from Qt import QtWidgets, QtCore
|
|||
import qtawesome
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
from openpype.client import (
|
||||
get_version_by_id,
|
||||
get_versions,
|
||||
get_hero_versions,
|
||||
get_representation_by_id,
|
||||
get_representations,
|
||||
)
|
||||
from openpype import style
|
||||
from openpype.pipeline import (
|
||||
legacy_io,
|
||||
|
|
@ -83,12 +90,9 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if item_id not in repre_ids:
|
||||
repre_ids.append(item_id)
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"_id": {"$in": repre_ids}
|
||||
},
|
||||
{"parent": 1}
|
||||
project_name = legacy_io.active_project()
|
||||
repre_docs = get_representations(
|
||||
project_name, representation_ids=repre_ids, fields=["parent"]
|
||||
)
|
||||
|
||||
version_ids = []
|
||||
|
|
@ -97,10 +101,9 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if version_id not in version_ids:
|
||||
version_ids.append(version_id)
|
||||
|
||||
loaded_versions = legacy_io.find({
|
||||
"_id": {"$in": version_ids},
|
||||
"type": {"$in": ["version", "hero_version"]}
|
||||
})
|
||||
loaded_versions = get_versions(
|
||||
project_name, version_ids=version_ids, hero=True
|
||||
)
|
||||
|
||||
loaded_hero_versions = []
|
||||
versions_by_parent_id = collections.defaultdict(list)
|
||||
|
|
@ -114,10 +117,9 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if parent_id not in version_parents:
|
||||
version_parents.append(parent_id)
|
||||
|
||||
all_versions = legacy_io.find({
|
||||
"type": {"$in": ["hero_version", "version"]},
|
||||
"parent": {"$in": version_parents}
|
||||
})
|
||||
all_versions = get_versions(
|
||||
project_name, subset_ids=version_parents, hero=True
|
||||
)
|
||||
hero_versions = []
|
||||
versions = []
|
||||
for version in all_versions:
|
||||
|
|
@ -150,12 +152,10 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if item_id not in repre_ids:
|
||||
repre_ids.append(item_id)
|
||||
|
||||
repre_docs = legacy_io.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"_id": {"$in": repre_ids}
|
||||
},
|
||||
{"parent": 1}
|
||||
repre_docs = get_representations(
|
||||
project_name,
|
||||
representation_ids=repre_ids,
|
||||
fields=["parent"]
|
||||
)
|
||||
|
||||
version_ids = []
|
||||
|
|
@ -165,13 +165,13 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
version_id_by_repre_id[repre_doc["_id"]] = version_id
|
||||
if version_id not in version_ids:
|
||||
version_ids.append(version_id)
|
||||
hero_versions = legacy_io.find(
|
||||
{
|
||||
"_id": {"$in": version_ids},
|
||||
"type": "hero_version"
|
||||
},
|
||||
{"version_id": 1}
|
||||
|
||||
hero_versions = get_hero_versions(
|
||||
project_name,
|
||||
version_ids=version_ids,
|
||||
fields=["version_id"]
|
||||
)
|
||||
|
||||
version_ids = set()
|
||||
for hero_version in hero_versions:
|
||||
version_id = hero_version["version_id"]
|
||||
|
|
@ -183,12 +183,10 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
if current_version_id == hero_version_id:
|
||||
version_id_by_repre_id[_repre_id] = version_id
|
||||
|
||||
version_docs = legacy_io.find(
|
||||
{
|
||||
"_id": {"$in": list(version_ids)},
|
||||
"type": "version"
|
||||
},
|
||||
{"name": 1}
|
||||
version_docs = get_versions(
|
||||
project_name,
|
||||
version_ids=version_ids,
|
||||
fields=["name"]
|
||||
)
|
||||
version_name_by_id = {}
|
||||
for version_doc in version_docs:
|
||||
|
|
@ -370,10 +368,9 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
active_site = self.sync_server.get_active_site(project_name)
|
||||
remote_site = self.sync_server.get_remote_site(project_name)
|
||||
|
||||
repre_docs = legacy_io.find({
|
||||
"type": "representation",
|
||||
"_id": {"$in": repre_ids}
|
||||
})
|
||||
repre_docs = get_representations(
|
||||
project_name, representation_ids=repre_ids
|
||||
)
|
||||
repre_docs_by_id = {
|
||||
repre_doc["_id"]: repre_doc
|
||||
for repre_doc in repre_docs
|
||||
|
|
@ -658,25 +655,35 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
|
||||
active = items[-1]
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
# Get available versions for active representation
|
||||
representation_id = ObjectId(active["representation"])
|
||||
representation = legacy_io.find_one({"_id": representation_id})
|
||||
version = legacy_io.find_one({
|
||||
"_id": representation["parent"]
|
||||
})
|
||||
repre_doc = get_representation_by_id(
|
||||
project_name,
|
||||
active["representation"],
|
||||
fields=["parent"]
|
||||
)
|
||||
|
||||
versions = list(legacy_io.find(
|
||||
{
|
||||
"parent": version["parent"],
|
||||
"type": "version"
|
||||
},
|
||||
sort=[("name", 1)]
|
||||
repre_version_doc = get_version_by_id(
|
||||
project_name,
|
||||
repre_doc["parent"],
|
||||
fields=["parent"]
|
||||
)
|
||||
|
||||
version_docs = list(get_versions(
|
||||
project_name,
|
||||
subset_ids=[repre_version_doc["parent"]],
|
||||
hero=True
|
||||
))
|
||||
hero_version = None
|
||||
standard_versions = []
|
||||
for version_doc in version_docs:
|
||||
if version_doc["type"] == "hero_version":
|
||||
hero_version = version_doc
|
||||
else:
|
||||
standard_versions.append(version_doc)
|
||||
versions = list(reversed(
|
||||
sorted(standard_versions, key=lambda item: item["name"])
|
||||
))
|
||||
|
||||
hero_version = legacy_io.find_one({
|
||||
"parent": version["parent"],
|
||||
"type": "hero_version"
|
||||
})
|
||||
if hero_version:
|
||||
_version_id = hero_version["version_id"]
|
||||
for _version in versions:
|
||||
|
|
@ -703,7 +710,7 @@ class SceneInventoryView(QtWidgets.QTreeView):
|
|||
all_versions = []
|
||||
if hero_version:
|
||||
all_versions.append(hero_version)
|
||||
all_versions.extend(reversed(versions))
|
||||
all_versions.extend(versions)
|
||||
|
||||
if current_item:
|
||||
index = all_versions.index(current_item)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import os
|
||||
import sys
|
||||
import json
|
||||
import traceback
|
||||
import functools
|
||||
import datetime
|
||||
|
||||
from Qt import QtWidgets, QtGui, QtCore
|
||||
|
||||
|
|
@ -10,7 +12,66 @@ from openpype.tools.settings import CHILD_OFFSET
|
|||
|
||||
from .widgets import ExpandingWidget
|
||||
from .lib import create_deffered_value_change_timer
|
||||
from .constants import DEFAULT_PROJECT_LABEL
|
||||
from .constants import (
|
||||
DEFAULT_PROJECT_LABEL,
|
||||
SETTINGS_PATH_KEY,
|
||||
ROOT_KEY,
|
||||
VALUE_KEY,
|
||||
SAVE_TIME_KEY,
|
||||
PROJECT_NAME_KEY,
|
||||
)
|
||||
|
||||
_MENU_SEPARATOR_REQ = object()
|
||||
|
||||
|
||||
class ExtractHelper:
|
||||
_last_save_dir = os.path.expanduser("~")
|
||||
|
||||
@classmethod
|
||||
def get_last_save_dir(cls):
|
||||
return cls._last_save_dir
|
||||
|
||||
@classmethod
|
||||
def set_last_save_dir(cls, save_dir):
|
||||
cls._last_save_dir = save_dir
|
||||
|
||||
@classmethod
|
||||
def ask_for_save_filepath(cls, parent):
|
||||
dialog = QtWidgets.QFileDialog(
|
||||
parent,
|
||||
"Save settings values",
|
||||
cls.get_last_save_dir(),
|
||||
"Values (*.json)"
|
||||
)
|
||||
# dialog.setOption(dialog.DontUseNativeDialog)
|
||||
dialog.setAcceptMode(dialog.AcceptSave)
|
||||
if dialog.exec() != dialog.Accepted:
|
||||
return
|
||||
|
||||
selected_urls = dialog.selectedUrls()
|
||||
if not selected_urls:
|
||||
return
|
||||
|
||||
filepath = selected_urls[0].toLocalFile()
|
||||
if not filepath:
|
||||
return
|
||||
|
||||
if not filepath.lower().endswith(".json"):
|
||||
filepath += ".json"
|
||||
return filepath
|
||||
|
||||
@classmethod
|
||||
def extract_settings_to_json(cls, filepath, settings_data, project_name):
|
||||
now = datetime.datetime.now()
|
||||
settings_data[SAVE_TIME_KEY] = now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
if project_name != 0:
|
||||
settings_data[PROJECT_NAME_KEY] = project_name
|
||||
|
||||
with open(filepath, "w") as stream:
|
||||
json.dump(settings_data, stream, indent=4)
|
||||
|
||||
new_dir = os.path.dirname(filepath)
|
||||
cls.set_last_save_dir(new_dir)
|
||||
|
||||
|
||||
class BaseWidget(QtWidgets.QWidget):
|
||||
|
|
@ -190,24 +251,29 @@ class BaseWidget(QtWidgets.QWidget):
|
|||
actions_mapping[action] = remove_from_project_override
|
||||
menu.addAction(action)
|
||||
|
||||
def _get_mime_data_from_entity(self):
|
||||
if self.entity.is_dynamic_item or self.entity.is_in_dynamic_item:
|
||||
entity_path = None
|
||||
else:
|
||||
entity_path = "/".join(
|
||||
[self.entity.root_key, self.entity.path]
|
||||
)
|
||||
|
||||
value = self.entity.value
|
||||
|
||||
# Copy for settings tool
|
||||
return {
|
||||
VALUE_KEY: value,
|
||||
ROOT_KEY: self.entity.root_key,
|
||||
SETTINGS_PATH_KEY: entity_path
|
||||
}
|
||||
|
||||
def _copy_value_actions(self, menu):
|
||||
def copy_value():
|
||||
mime_data = QtCore.QMimeData()
|
||||
|
||||
if self.entity.is_dynamic_item or self.entity.is_in_dynamic_item:
|
||||
entity_path = None
|
||||
else:
|
||||
entity_path = "/".join(
|
||||
[self.entity.root_key, self.entity.path]
|
||||
)
|
||||
|
||||
value = self.entity.value
|
||||
# Copy for settings tool
|
||||
settings_data = {
|
||||
"root_key": self.entity.root_key,
|
||||
"value": value,
|
||||
"path": entity_path
|
||||
}
|
||||
settings_data = self._get_mime_data_from_entity()
|
||||
settings_encoded_data = QtCore.QByteArray()
|
||||
settings_stream = QtCore.QDataStream(
|
||||
settings_encoded_data, QtCore.QIODevice.WriteOnly
|
||||
|
|
@ -218,6 +284,7 @@ class BaseWidget(QtWidgets.QWidget):
|
|||
)
|
||||
|
||||
# Copy as json
|
||||
value = settings_data[VALUE_KEY]
|
||||
json_encoded_data = None
|
||||
if isinstance(value, (dict, list)):
|
||||
json_encoded_data = QtCore.QByteArray()
|
||||
|
|
@ -241,25 +308,87 @@ class BaseWidget(QtWidgets.QWidget):
|
|||
action = QtWidgets.QAction("Copy", menu)
|
||||
return [(action, copy_value)]
|
||||
|
||||
def _extract_to_file(self):
|
||||
filepath = ExtractHelper.ask_for_save_filepath(self)
|
||||
if not filepath:
|
||||
return
|
||||
|
||||
settings_data = self._get_mime_data_from_entity()
|
||||
project_name = 0
|
||||
if hasattr(self.category_widget, "project_name"):
|
||||
project_name = self.category_widget.project_name
|
||||
|
||||
ExtractHelper.extract_settings_to_json(
|
||||
filepath, settings_data, project_name
|
||||
)
|
||||
|
||||
def _extract_value_to_file_actions(self, menu):
|
||||
extract_action = QtWidgets.QAction("Extract to file", menu)
|
||||
return [
|
||||
_MENU_SEPARATOR_REQ,
|
||||
(extract_action, self._extract_to_file)
|
||||
]
|
||||
|
||||
def _parse_source_data_for_paste(self, data):
|
||||
settings_path = None
|
||||
root_key = None
|
||||
if isinstance(data, dict):
|
||||
data.pop(SAVE_TIME_KEY, None)
|
||||
data.pop(PROJECT_NAME_KEY, None)
|
||||
settings_path = data.pop(SETTINGS_PATH_KEY, settings_path)
|
||||
root_key = data.pop(ROOT_KEY, root_key)
|
||||
data = data.pop(VALUE_KEY, data)
|
||||
|
||||
return {
|
||||
VALUE_KEY: data,
|
||||
SETTINGS_PATH_KEY: settings_path,
|
||||
ROOT_KEY: root_key
|
||||
}
|
||||
|
||||
def _get_value_from_clipboard(self):
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
mime_data = clipboard.mimeData()
|
||||
app_value = mime_data.data("application/copy_settings_value")
|
||||
if app_value:
|
||||
settings_stream = QtCore.QDataStream(
|
||||
app_value, QtCore.QIODevice.ReadOnly
|
||||
)
|
||||
mime_data_value_str = settings_stream.readQString()
|
||||
return json.loads(mime_data_value_str)
|
||||
|
||||
if mime_data.hasUrls():
|
||||
for url in mime_data.urls():
|
||||
local_file = url.toLocalFile()
|
||||
try:
|
||||
with open(local_file, "r") as stream:
|
||||
value = json.load(stream)
|
||||
except Exception:
|
||||
continue
|
||||
if value:
|
||||
return self._parse_source_data_for_paste(value)
|
||||
|
||||
if mime_data.hasText():
|
||||
text = mime_data.text()
|
||||
try:
|
||||
value = json.loads(text)
|
||||
except Exception:
|
||||
try:
|
||||
value = self.entity.convert_to_valid_type(text)
|
||||
except Exception:
|
||||
return None
|
||||
return self._parse_source_data_for_paste(value)
|
||||
|
||||
def _paste_value_actions(self, menu):
|
||||
output = []
|
||||
# Allow paste of value only if were copied from this UI
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
mime_data = clipboard.mimeData()
|
||||
mime_value = mime_data.data("application/copy_settings_value")
|
||||
mime_data_value = self._get_value_from_clipboard()
|
||||
# Skip if there is nothing to do
|
||||
if not mime_value:
|
||||
if not mime_data_value:
|
||||
return output
|
||||
|
||||
settings_stream = QtCore.QDataStream(
|
||||
mime_value, QtCore.QIODevice.ReadOnly
|
||||
)
|
||||
mime_data_value_str = settings_stream.readQString()
|
||||
mime_data_value = json.loads(mime_data_value_str)
|
||||
|
||||
value = mime_data_value["value"]
|
||||
path = mime_data_value["path"]
|
||||
root_key = mime_data_value["root_key"]
|
||||
value = mime_data_value[VALUE_KEY]
|
||||
path = mime_data_value[SETTINGS_PATH_KEY]
|
||||
root_key = mime_data_value[ROOT_KEY]
|
||||
|
||||
# Try to find matching entity to be able paste values to same spot
|
||||
# - entity can't by dynamic or in dynamic item
|
||||
|
|
@ -391,10 +520,19 @@ class BaseWidget(QtWidgets.QWidget):
|
|||
ui_actions.extend(self._copy_value_actions(menu))
|
||||
ui_actions.extend(self._paste_value_actions(menu))
|
||||
if ui_actions:
|
||||
menu.addSeparator()
|
||||
for action, callback in ui_actions:
|
||||
menu.addAction(action)
|
||||
actions_mapping[action] = callback
|
||||
ui_actions.insert(0, _MENU_SEPARATOR_REQ)
|
||||
|
||||
ui_actions.extend(self._extract_value_to_file_actions(menu))
|
||||
|
||||
for item in ui_actions:
|
||||
if item is _MENU_SEPARATOR_REQ:
|
||||
if len(menu.actions()) > 0:
|
||||
menu.addSeparator()
|
||||
continue
|
||||
|
||||
action, callback = item
|
||||
menu.addAction(action)
|
||||
actions_mapping[action] = callback
|
||||
|
||||
if not actions_mapping:
|
||||
action = QtWidgets.QAction("< No action >")
|
||||
|
|
|
|||
|
|
@ -45,8 +45,15 @@ from .breadcrumbs_widget import (
|
|||
SystemSettingsBreadcrumbs,
|
||||
ProjectSettingsBreadcrumbs
|
||||
)
|
||||
|
||||
from .base import GUIWidget
|
||||
from .constants import (
|
||||
SETTINGS_PATH_KEY,
|
||||
ROOT_KEY,
|
||||
VALUE_KEY,
|
||||
)
|
||||
from .base import (
|
||||
ExtractHelper,
|
||||
GUIWidget,
|
||||
)
|
||||
from .list_item_widget import ListWidget
|
||||
from .list_strict_widget import ListStrictWidget
|
||||
from .dict_mutable_widget import DictMutableKeysWidget
|
||||
|
|
@ -627,11 +634,35 @@ class SettingsCategoryWidget(QtWidgets.QWidget):
|
|||
self._on_context_version_trigger
|
||||
)
|
||||
submenu.addAction(action)
|
||||
|
||||
menu.addMenu(submenu)
|
||||
|
||||
extract_action = QtWidgets.QAction("Extract to file", menu)
|
||||
extract_action.triggered.connect(self._on_extract_to_file)
|
||||
|
||||
menu.addAction(extract_action)
|
||||
|
||||
def _on_context_version_trigger(self, version):
|
||||
self._on_source_version_change(version)
|
||||
|
||||
def _on_extract_to_file(self):
|
||||
filepath = ExtractHelper.ask_for_save_filepath(self)
|
||||
if not filepath:
|
||||
return
|
||||
|
||||
settings_data = {
|
||||
SETTINGS_PATH_KEY: self.entity.root_key,
|
||||
ROOT_KEY: self.entity.root_key,
|
||||
VALUE_KEY: self.entity.value
|
||||
}
|
||||
project_name = 0
|
||||
if hasattr(self, "project_name"):
|
||||
project_name = self.project_name
|
||||
|
||||
ExtractHelper.extract_settings_to_json(
|
||||
filepath, settings_data, project_name
|
||||
)
|
||||
|
||||
def _on_reset_crash(self):
|
||||
self.save_btn.setEnabled(False)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@ PROJECT_IS_ACTIVE_ROLE = QtCore.Qt.UserRole + 2
|
|||
PROJECT_IS_SELECTED_ROLE = QtCore.Qt.UserRole + 3
|
||||
PROJECT_VERSION_ROLE = QtCore.Qt.UserRole + 4
|
||||
|
||||
# Save/Extract keys
|
||||
SETTINGS_PATH_KEY = "__settings_path__"
|
||||
ROOT_KEY = "__root_key__"
|
||||
VALUE_KEY = "__value__"
|
||||
SAVE_TIME_KEY = "__extracted__"
|
||||
PROJECT_NAME_KEY = "__project_name__"
|
||||
|
||||
__all__ = (
|
||||
"DEFAULT_PROJECT_LABEL",
|
||||
|
|
@ -15,4 +21,11 @@ __all__ = (
|
|||
"PROJECT_IS_ACTIVE_ROLE",
|
||||
"PROJECT_IS_SELECTED_ROLE",
|
||||
"PROJECT_VERSION_ROLE",
|
||||
|
||||
"SETTINGS_PATH_KEY",
|
||||
"ROOT_KEY",
|
||||
"SETTINGS_PATH_KEY",
|
||||
"VALUE_KEY",
|
||||
"SAVE_TIME_KEY",
|
||||
"PROJECT_NAME_KEY",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import signal
|
|||
from bson.objectid import ObjectId
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
|
||||
from openpype.client import get_asset_by_id
|
||||
|
||||
from .widgets import (
|
||||
AssetWidget, FamilyWidget, ComponentsWidget, ShadowWidget
|
||||
)
|
||||
|
|
@ -126,17 +128,6 @@ class Window(QtWidgets.QDialog):
|
|||
if event:
|
||||
super().resizeEvent(event)
|
||||
|
||||
def get_avalon_parent(self, entity):
|
||||
''' Avalon DB entities helper - get all parents (exclude project).
|
||||
'''
|
||||
parent_id = entity['data']['visualParent']
|
||||
parents = []
|
||||
if parent_id is not None:
|
||||
parent = self.db.find_one({'_id': parent_id})
|
||||
parents.extend(self.get_avalon_parent(parent))
|
||||
parents.append(parent['name'])
|
||||
return parents
|
||||
|
||||
def on_project_change(self, project_name):
|
||||
self.widget_family.refresh()
|
||||
|
||||
|
|
@ -152,7 +143,10 @@ class Window(QtWidgets.QDialog):
|
|||
]
|
||||
if len(selected) == 1:
|
||||
self.valid_parent = True
|
||||
asset = self.db.find_one({"_id": selected[0], "type": "asset"})
|
||||
project_name = self.db.active_project()
|
||||
asset = get_asset_by_id(
|
||||
project_name, selected[0], fields=["name"]
|
||||
)
|
||||
self.widget_family.change_asset(asset['name'])
|
||||
else:
|
||||
self.valid_parent = False
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import collections
|
|||
from Qt import QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import get_assets
|
||||
from openpype.style import (
|
||||
get_default_entity_icon_color,
|
||||
get_deprecated_entity_font_color,
|
||||
|
|
@ -104,17 +105,18 @@ class AssetModel(TreeModel):
|
|||
def refresh(self):
|
||||
"""Refresh the data for the model."""
|
||||
|
||||
project_name = self.dbcon.active_project()
|
||||
self.clear()
|
||||
if (
|
||||
self.dbcon.active_project() is None or
|
||||
self.dbcon.active_project() == ''
|
||||
):
|
||||
if not project_name:
|
||||
return
|
||||
|
||||
self.beginResetModel()
|
||||
|
||||
# Get all assets in current project sorted by name
|
||||
db_assets = self.dbcon.find({"type": "asset"}).sort("name", 1)
|
||||
asset_docs = get_assets(project_name)
|
||||
db_assets = list(
|
||||
sorted(asset_docs, key=lambda item: item["name"])
|
||||
)
|
||||
|
||||
# Group the assets by their visual parent's id
|
||||
assets_by_parent = collections.defaultdict(list)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@ import contextlib
|
|||
from Qt import QtWidgets, QtCore
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_asset_by_id,
|
||||
)
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
|
||||
from openpype.style import get_default_tools_icon_color
|
||||
|
|
@ -218,7 +222,8 @@ class AssetWidget(QtWidgets.QWidget):
|
|||
self.view = view
|
||||
|
||||
def collect_data(self):
|
||||
project = self.dbcon.find_one({'type': 'project'})
|
||||
project_name = self.dbcon.active_project()
|
||||
project = get_project(project_name, fields=["name"])
|
||||
asset = self.get_active_asset()
|
||||
|
||||
try:
|
||||
|
|
@ -241,9 +246,16 @@ class AssetWidget(QtWidgets.QWidget):
|
|||
return ent_parents
|
||||
|
||||
output = []
|
||||
if entity.get('data', {}).get('visualParent', None) is None:
|
||||
parent_asset_id = entity.get('data', {}).get('visualParent', None)
|
||||
if parent_asset_id is None:
|
||||
return output
|
||||
parent = self.dbcon.find_one({'_id': entity['data']['visualParent']})
|
||||
|
||||
project_name = self.dbcon.active_project()
|
||||
parent = get_asset_by_id(
|
||||
project_name,
|
||||
parent_asset_id,
|
||||
fields=["name", "data.visualParent"]
|
||||
)
|
||||
output.append(parent['name'])
|
||||
output.extend(self.get_parents(parent))
|
||||
return output
|
||||
|
|
@ -349,9 +361,10 @@ class AssetWidget(QtWidgets.QWidget):
|
|||
tasks = []
|
||||
selected = self.get_selected_assets()
|
||||
if len(selected) == 1:
|
||||
asset = self.dbcon.find_one({
|
||||
"_id": selected[0], "type": "asset"
|
||||
})
|
||||
project_name = self.dbcon.active_project()
|
||||
asset = get_asset_by_id(
|
||||
project_name, selected[0], fields=["data.tasks"]
|
||||
)
|
||||
if asset:
|
||||
tasks = asset.get('data', {}).get('tasks', [])
|
||||
self.task_model.set_tasks(tasks)
|
||||
|
|
@ -400,7 +413,7 @@ class AssetWidget(QtWidgets.QWidget):
|
|||
|
||||
# Select
|
||||
mode = selection_model.Select | selection_model.Rows
|
||||
for index in lib.iter_model_rows(
|
||||
for index in _iter_model_rows(
|
||||
self.proxy, column=0, include_root=False
|
||||
):
|
||||
# stop iteration if there are no assets to process
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
import re
|
||||
|
||||
from Qt import QtWidgets, QtCore
|
||||
from . import HelpRole, FamilyRole, ExistsRole, PluginRole, PluginKeyRole
|
||||
from . import FamilyDescriptionWidget
|
||||
|
||||
from openpype.client import (
|
||||
get_asset_by_name,
|
||||
get_subset_by_name,
|
||||
get_subsets,
|
||||
get_last_version_by_subset_id,
|
||||
)
|
||||
from openpype.api import get_project_settings
|
||||
from openpype.pipeline import LegacyCreator
|
||||
from openpype.lib import TaskNotSetError
|
||||
from openpype.pipeline.create import SUBSET_NAME_ALLOWED_SYMBOLS
|
||||
|
||||
from . import HelpRole, FamilyRole, ExistsRole, PluginRole, PluginKeyRole
|
||||
from . import FamilyDescriptionWidget
|
||||
|
||||
|
||||
class FamilyWidget(QtWidgets.QWidget):
|
||||
|
||||
|
|
@ -180,12 +187,9 @@ class FamilyWidget(QtWidgets.QWidget):
|
|||
asset_doc = None
|
||||
if asset_name != self.NOT_SELECTED:
|
||||
# Get the assets from the database which match with the name
|
||||
asset_doc = self.dbcon.find_one(
|
||||
{
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
},
|
||||
{"_id": 1}
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, asset_name, fields=["_id"]
|
||||
)
|
||||
|
||||
# Get plugin and family
|
||||
|
|
@ -200,14 +204,13 @@ class FamilyWidget(QtWidgets.QWidget):
|
|||
return
|
||||
|
||||
# Get the asset from the database which match with the name
|
||||
asset_doc = self.dbcon.find_one(
|
||||
{"name": asset_name, "type": "asset"},
|
||||
projection={"_id": 1}
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, asset_name, fields=["_id"]
|
||||
)
|
||||
# Get plugin
|
||||
plugin = item.data(PluginRole)
|
||||
if asset_doc and plugin:
|
||||
project_name = self.dbcon.Session["AVALON_PROJECT"]
|
||||
asset_id = asset_doc["_id"]
|
||||
task_name = self.dbcon.Session["AVALON_TASK"]
|
||||
|
||||
|
|
@ -231,14 +234,14 @@ class FamilyWidget(QtWidgets.QWidget):
|
|||
self.input_result.setText("Select task please")
|
||||
|
||||
# Get all subsets of the current asset
|
||||
subset_docs = self.dbcon.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": asset_id
|
||||
},
|
||||
{"name": 1}
|
||||
subset_docs = get_subsets(
|
||||
project_name, asset_ids=[asset_id], fields=["name"]
|
||||
)
|
||||
existing_subset_names = set(subset_docs.distinct("name"))
|
||||
|
||||
existing_subset_names = {
|
||||
subset_doc["name"]
|
||||
for subset_doc in subset_docs
|
||||
}
|
||||
|
||||
# Defaults to dropdown
|
||||
defaults = []
|
||||
|
|
@ -296,47 +299,37 @@ class FamilyWidget(QtWidgets.QWidget):
|
|||
if not auto_version:
|
||||
return
|
||||
|
||||
project_name = self.dbcon.active_project()
|
||||
asset_name = self.asset_name
|
||||
subset_name = self.input_result.text()
|
||||
version = 1
|
||||
|
||||
asset_doc = None
|
||||
subset_doc = None
|
||||
versions = None
|
||||
if (
|
||||
asset_name != self.NOT_SELECTED and
|
||||
subset_name.strip() != ''
|
||||
):
|
||||
asset_doc = self.dbcon.find_one(
|
||||
{
|
||||
'type': 'asset',
|
||||
'name': asset_name
|
||||
},
|
||||
{"_id": 1}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, asset_name, fields=["_id"]
|
||||
)
|
||||
|
||||
if asset_doc:
|
||||
subset_doc = self.dbcon.find_one(
|
||||
{
|
||||
'type': 'subset',
|
||||
'parent': asset_doc['_id'],
|
||||
'name': subset_name
|
||||
},
|
||||
{"_id": 1}
|
||||
subset_doc = get_subset_by_name(
|
||||
project_name,
|
||||
subset_name,
|
||||
asset_doc['_id'],
|
||||
fields=["_id"]
|
||||
)
|
||||
|
||||
if subset_doc:
|
||||
versions = self.dbcon.find(
|
||||
{
|
||||
'type': 'version',
|
||||
'parent': subset_doc['_id']
|
||||
},
|
||||
{"name": 1}
|
||||
).distinct("name")
|
||||
|
||||
if versions:
|
||||
versions = sorted(versions)
|
||||
version = int(versions[-1]) + 1
|
||||
last_version = get_last_version_by_subset_id(
|
||||
project_name,
|
||||
subset_doc["_id"],
|
||||
fields=["name"]
|
||||
)
|
||||
if last_version:
|
||||
version = last_version["name"] + 1
|
||||
|
||||
self.version_spinbox.setValue(version)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import click
|
|||
|
||||
import speedcopy
|
||||
|
||||
from openpype.client import get_project, get_asset_by_name
|
||||
from openpype.lib import Terminal
|
||||
from openpype.api import Anatomy
|
||||
from openpype.pipeline import legacy_io
|
||||
|
|
@ -29,20 +30,6 @@ class TextureCopy:
|
|||
if os.path.splitext(x)[1].lower() in texture_extensions)
|
||||
return textures
|
||||
|
||||
def _get_project(self, project_name):
|
||||
project = legacy_io.find_one({
|
||||
'type': 'project',
|
||||
'name': project_name
|
||||
})
|
||||
return project
|
||||
|
||||
def _get_asset(self, asset_name):
|
||||
asset = legacy_io.find_one({
|
||||
'type': 'asset',
|
||||
'name': asset_name
|
||||
})
|
||||
return asset
|
||||
|
||||
def _get_destination_path(self, asset, project):
|
||||
project_name = project["name"]
|
||||
hierarchy = ""
|
||||
|
|
@ -88,11 +75,12 @@ class TextureCopy:
|
|||
t.echo("!!! {}".format(e))
|
||||
exit(1)
|
||||
|
||||
def process(self, asset, project, path):
|
||||
def process(self, asset_name, project_name, path):
|
||||
"""
|
||||
Process all textures found in path and copy them to asset under
|
||||
project.
|
||||
"""
|
||||
|
||||
t.echo(">>> Looking for textures ...")
|
||||
textures = self._get_textures(path)
|
||||
if len(textures) < 1:
|
||||
|
|
@ -101,14 +89,14 @@ class TextureCopy:
|
|||
else:
|
||||
t.echo(">>> Found {} textures ...".format(len(textures)))
|
||||
|
||||
project = self._get_project(project)
|
||||
project = get_project(project_name)
|
||||
if not project:
|
||||
t.echo("!!! Project name [ {} ] not found.".format(project))
|
||||
t.echo("!!! Project name [ {} ] not found.".format(project_name))
|
||||
exit(1)
|
||||
|
||||
asset = self._get_asset(asset)
|
||||
if not project:
|
||||
t.echo("!!! Asset [ {} ] not found in project".format(asset))
|
||||
asset = get_asset_by_name(project_name, asset_name)
|
||||
if not asset:
|
||||
t.echo("!!! Asset [ {} ] not found in project".format(asset_name))
|
||||
exit(1)
|
||||
t.echo((">>> Project [ {} ] and "
|
||||
"asset [ {} ] seems to be OK ...").format(project['name'],
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import Qt
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_assets,
|
||||
)
|
||||
from openpype.style import (
|
||||
get_objected_colors,
|
||||
get_default_tools_icon_color,
|
||||
|
|
@ -525,21 +529,18 @@ class AssetModel(QtGui.QStandardItemModel):
|
|||
self._doc_fetched.emit()
|
||||
|
||||
def _fetch_asset_docs(self):
|
||||
if not self.dbcon.Session.get("AVALON_PROJECT"):
|
||||
project_name = self.dbcon.current_project()
|
||||
if not project_name:
|
||||
return []
|
||||
|
||||
project_doc = self.dbcon.find_one(
|
||||
{"type": "project"},
|
||||
{"_id": True}
|
||||
)
|
||||
project_doc = get_project(project_name, fields=["_id"])
|
||||
if not project_doc:
|
||||
return []
|
||||
|
||||
# Get all assets sorted by name
|
||||
return list(self.dbcon.find(
|
||||
{"type": "asset"},
|
||||
self._asset_projection
|
||||
))
|
||||
return list(
|
||||
get_assets(project_name, fields=self._asset_projection.keys())
|
||||
)
|
||||
|
||||
def _stop_fetch_thread(self):
|
||||
self._refreshing = False
|
||||
|
|
|
|||
|
|
@ -6,15 +6,19 @@ import numbers
|
|||
import Qt
|
||||
from Qt import QtWidgets, QtGui, QtCore
|
||||
|
||||
from openpype.pipeline import HeroVersionType
|
||||
from .models import TreeModel
|
||||
from . import lib
|
||||
|
||||
if Qt.__binding__ == "PySide":
|
||||
from PySide.QtGui import QStyleOptionViewItemV4
|
||||
elif Qt.__binding__ == "PyQt4":
|
||||
from PyQt4.QtGui import QStyleOptionViewItemV4
|
||||
|
||||
from openpype.client import (
|
||||
get_versions,
|
||||
get_hero_versions,
|
||||
)
|
||||
from openpype.pipeline import HeroVersionType
|
||||
from .models import TreeModel
|
||||
from . import lib
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -114,26 +118,24 @@ class VersionDelegate(QtWidgets.QStyledItemDelegate):
|
|||
"Version is not integer"
|
||||
)
|
||||
|
||||
project_name = self.dbcon.active_project()
|
||||
# Add all available versions to the editor
|
||||
parent_id = item["version_document"]["parent"]
|
||||
version_docs = list(self.dbcon.find(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": parent_id
|
||||
},
|
||||
sort=[("name", 1)]
|
||||
version_docs = list(sorted(
|
||||
get_versions(project_name, subset_ids=[parent_id]),
|
||||
key=lambda item: item["name"]
|
||||
))
|
||||
|
||||
hero_version_doc = self.dbcon.find_one(
|
||||
{
|
||||
"type": "hero_version",
|
||||
"parent": parent_id
|
||||
}, {
|
||||
"name": 1,
|
||||
"data.tags": 1,
|
||||
"version_id": 1
|
||||
}
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import collections
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_asset_by_name,
|
||||
)
|
||||
from openpype.style import (
|
||||
get_default_entity_icon_color,
|
||||
get_objected_colors,
|
||||
|
|
@ -430,9 +434,8 @@ class FamilyConfigCache:
|
|||
database = getattr(self.dbcon, "database", None)
|
||||
if database is None:
|
||||
database = self.dbcon._database
|
||||
asset_doc = database[project_name].find_one(
|
||||
{"type": "asset", "name": asset_name},
|
||||
{"data.tasks": True}
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name, asset_name, fields=["data.tasks"]
|
||||
) or {}
|
||||
tasks_info = asset_doc.get("data", {}).get("tasks") or {}
|
||||
task_type = tasks_info.get(task_name, {}).get("type")
|
||||
|
|
@ -500,10 +503,7 @@ class GroupsConfig:
|
|||
project_name = self.dbcon.Session.get("AVALON_PROJECT")
|
||||
if project_name:
|
||||
# Get pre-defined group name and appearance from project config
|
||||
project_doc = self.dbcon.find_one(
|
||||
{"type": "project"},
|
||||
projection={"config.groups": True}
|
||||
)
|
||||
project_doc = get_project(project_name, fields=["config.groups"])
|
||||
|
||||
if project_doc:
|
||||
group_configs = project_doc["config"].get("groups") or []
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
from Qt import QtWidgets, QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_asset_by_id,
|
||||
)
|
||||
from openpype.style import get_disabled_entity_icon_color
|
||||
from openpype.tools.utils.lib import get_task_icon
|
||||
|
||||
|
|
@ -47,7 +51,8 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
# Get the project configured icons from database
|
||||
project_doc = {}
|
||||
if self._context_is_valid():
|
||||
project_doc = self.dbcon.find_one({"type": "project"})
|
||||
project_name = self.dbcon.active_project()
|
||||
project_doc = get_project(project_name)
|
||||
|
||||
self._loaded_project_name = self._get_current_project()
|
||||
self._project_doc = project_doc
|
||||
|
|
@ -71,9 +76,9 @@ class TasksModel(QtGui.QStandardItemModel):
|
|||
def set_asset_id(self, asset_id):
|
||||
asset_doc = None
|
||||
if self._context_is_valid():
|
||||
asset_doc = self.dbcon.find_one(
|
||||
{"_id": asset_id},
|
||||
{"data.tasks": True}
|
||||
project_name = self._get_current_project()
|
||||
asset_doc = get_asset_by_id(
|
||||
project_name, asset_id, fields=["data.tasks"]
|
||||
)
|
||||
self._set_asset(asset_doc)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import shutil
|
|||
import Qt
|
||||
from Qt import QtWidgets, QtCore
|
||||
|
||||
from openpype.client import get_asset_by_id
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
from openpype.tools.utils.delegates import PrettyTimeDelegate
|
||||
from openpype.lib import (
|
||||
|
|
@ -384,7 +385,9 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
return None
|
||||
|
||||
if self._asset_doc is None:
|
||||
self._asset_doc = legacy_io.find_one({"_id": self._asset_id})
|
||||
project_name = legacy_io.active_project()
|
||||
self._asset_doc = get_asset_by_id(project_name, self._asset_id)
|
||||
|
||||
return self._asset_doc
|
||||
|
||||
def _get_session(self):
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ import logging
|
|||
from Qt import QtCore, QtGui
|
||||
import qtawesome
|
||||
|
||||
from openpype.client import (
|
||||
get_subsets,
|
||||
get_versions,
|
||||
get_representations,
|
||||
)
|
||||
from openpype.style import (
|
||||
get_default_entity_icon_color,
|
||||
get_disabled_entity_icon_color,
|
||||
|
|
@ -215,6 +220,7 @@ class PublishFilesModel(QtGui.QStandardItemModel):
|
|||
|
||||
self._dbcon = dbcon
|
||||
self._anatomy = anatomy
|
||||
|
||||
self._file_extensions = extensions
|
||||
|
||||
self._invalid_context_item = None
|
||||
|
|
@ -234,6 +240,10 @@ class PublishFilesModel(QtGui.QStandardItemModel):
|
|||
self._asset_id = None
|
||||
self._task_name = None
|
||||
|
||||
@property
|
||||
def project_name(self):
|
||||
return self._dbcon.Session["AVALON_PROJECT"]
|
||||
|
||||
def _set_item_invalid(self, item):
|
||||
item.setFlags(QtCore.Qt.NoItemFlags)
|
||||
item.setData(self._invalid_icon, QtCore.Qt.DecorationRole)
|
||||
|
|
@ -285,15 +295,11 @@ class PublishFilesModel(QtGui.QStandardItemModel):
|
|||
def _get_workfie_representations(self):
|
||||
output = []
|
||||
# Get subset docs of asset
|
||||
subset_docs = self._dbcon.find(
|
||||
{
|
||||
"type": "subset",
|
||||
"parent": self._asset_id
|
||||
},
|
||||
{
|
||||
"_id": True,
|
||||
"name": True
|
||||
}
|
||||
subset_docs = get_subsets(
|
||||
self.project_name,
|
||||
asset_ids=[self._asset_id],
|
||||
fields=["_id", "name"]
|
||||
|
||||
)
|
||||
|
||||
subset_ids = [subset_doc["_id"] for subset_doc in subset_docs]
|
||||
|
|
@ -301,17 +307,12 @@ class PublishFilesModel(QtGui.QStandardItemModel):
|
|||
return output
|
||||
|
||||
# Get version docs of subsets with their families
|
||||
version_docs = self._dbcon.find(
|
||||
{
|
||||
"type": "version",
|
||||
"parent": {"$in": subset_ids}
|
||||
},
|
||||
{
|
||||
"_id": True,
|
||||
"data.families": True,
|
||||
"parent": True
|
||||
}
|
||||
version_docs = get_versions(
|
||||
self.project_name,
|
||||
subset_ids=subset_ids,
|
||||
fields=["_id", "parent", "data.families"]
|
||||
)
|
||||
|
||||
# Filter versions if they contain 'workfile' family
|
||||
filtered_versions = []
|
||||
for version_doc in version_docs:
|
||||
|
|
@ -327,13 +328,10 @@ class PublishFilesModel(QtGui.QStandardItemModel):
|
|||
# Query representations of filtered versions and add filter for
|
||||
# extension
|
||||
extensions = [ext.replace(".", "") for ext in self._file_extensions]
|
||||
repre_docs = self._dbcon.find(
|
||||
{
|
||||
"type": "representation",
|
||||
"parent": {"$in": version_ids},
|
||||
"context.ext": {"$in": extensions}
|
||||
}
|
||||
repre_docs = get_representations(
|
||||
self.project_name, version_ids, extensions
|
||||
)
|
||||
|
||||
# Filter queried representations by task name if task is set
|
||||
filtered_repre_docs = []
|
||||
for repre_doc in repre_docs:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ import logging
|
|||
|
||||
from Qt import QtWidgets, QtCore
|
||||
|
||||
from openpype.client import (
|
||||
get_project,
|
||||
get_asset_by_name,
|
||||
)
|
||||
from openpype.lib import (
|
||||
get_last_workfile_with_version,
|
||||
get_workdir_data,
|
||||
|
|
@ -22,29 +26,19 @@ def build_workfile_data(session):
|
|||
"""Get the data required for workfile formatting from avalon `session`"""
|
||||
|
||||
# Set work file data for template formatting
|
||||
project_name = session["AVALON_PROJECT"]
|
||||
asset_name = session["AVALON_ASSET"]
|
||||
task_name = session["AVALON_TASK"]
|
||||
host_name = session["AVALON_APP"]
|
||||
project_doc = legacy_io.find_one(
|
||||
{"type": "project"},
|
||||
{
|
||||
"name": True,
|
||||
"data.code": True,
|
||||
"config.tasks": True,
|
||||
}
|
||||
project_doc = get_project(
|
||||
project_name, fields=["name", "data.code", "config.tasks"]
|
||||
)
|
||||
asset_doc = get_asset_by_name(
|
||||
project_name,
|
||||
asset_name,
|
||||
fields=["name", "data.tasks", "data.parents"]
|
||||
)
|
||||
|
||||
asset_doc = legacy_io.find_one(
|
||||
{
|
||||
"type": "asset",
|
||||
"name": asset_name
|
||||
},
|
||||
{
|
||||
"name": True,
|
||||
"data.tasks": True,
|
||||
"data.parents": True
|
||||
}
|
||||
)
|
||||
data = get_workdir_data(project_doc, asset_doc, task_name, host_name)
|
||||
data.update({
|
||||
"version": 1,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import os
|
|||
import datetime
|
||||
from Qt import QtCore, QtWidgets
|
||||
|
||||
from openpype.client import get_asset_by_id, get_asset_by_name
|
||||
from openpype import style
|
||||
from openpype.lib import (
|
||||
get_workfile_doc,
|
||||
|
|
@ -223,6 +224,10 @@ class Window(QtWidgets.QMainWindow):
|
|||
self._first_show = True
|
||||
self._context_to_set = None
|
||||
|
||||
@property
|
||||
def project_name(self):
|
||||
return legacy_io.Session["AVALON_PROJECT"]
|
||||
|
||||
def showEvent(self, event):
|
||||
super(Window, self).showEvent(event)
|
||||
if self._first_show:
|
||||
|
|
@ -296,7 +301,8 @@ class Window(QtWidgets.QMainWindow):
|
|||
if not workfile_doc:
|
||||
workdir, filename = os.path.split(filepath)
|
||||
asset_id = self.assets_widget.get_selected_asset_id()
|
||||
asset_doc = legacy_io.find_one({"_id": asset_id})
|
||||
project_name = legacy_io.active_project()
|
||||
asset_doc = get_asset_by_id(project_name, asset_id)
|
||||
task_name = self.tasks_widget.get_selected_task_name()
|
||||
create_workfile_doc(
|
||||
asset_doc, task_name, filename, workdir, legacy_io
|
||||
|
|
@ -322,14 +328,13 @@ class Window(QtWidgets.QMainWindow):
|
|||
|
||||
self._context_to_set, context = None, self._context_to_set
|
||||
if "asset" in context:
|
||||
asset_doc = legacy_io.find_one(
|
||||
{
|
||||
"name": context["asset"],
|
||||
"type": "asset"
|
||||
},
|
||||
{"_id": 1}
|
||||
) or {}
|
||||
asset_id = asset_doc.get("_id")
|
||||
asset_doc = get_asset_by_name(
|
||||
self.project_name, context["asset"], fields=["_id"]
|
||||
)
|
||||
|
||||
asset_id = None
|
||||
if asset_doc:
|
||||
asset_id = asset_doc["_id"]
|
||||
# Select the asset
|
||||
self.assets_widget.select_asset(asset_id)
|
||||
self.tasks_widget.set_asset_id(asset_id)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue