[Automated] Merged develop into main

This commit is contained in:
pypebot 2022-06-15 05:48:58 +02:00 committed by GitHub
commit 9266439d3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 3363 additions and 1158 deletions

View 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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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"]

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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):

View file

@ -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()

View file

@ -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")

View file

@ -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):

View file

@ -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)

View file

@ -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": {

View file

@ -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\" - &lt;Name of project&gt;<br/>- \"d\" - &lt;Day of month number&gt; in shortest possible way.<br/>- \"dd\" - &lt;Day of month number&gt; with 2 digits.<br/>- \"ddd\" - &lt;Week day name&gt; shortened week day. e.g.: `Mon`, ...<br/>- \"dddd\" - &lt;Week day name&gt; full name of week day. e.g.: `Monday`, ...<br/>- \"m\" - &lt;Month number&gt; in shortest possible way. e.g.: `1` if January<br/>- \"mm\" - &lt;Month number&gt; with 2 digits.<br/>- \"mmm\" - &lt;Month name&gt; shortened month name. e.g.: `Jan`, ...<br/>- \"mmmm\" -&lt;Month name&gt; full month name. e.g.: `January`, ...<br/>- \"yy\" - &lt;Year number&gt; shortened year. e.g.: `19`, `20`, ...<br/>- \"yyyy\" - &lt;Year number&gt; full year. e.g.: `2019`, `2020`, ..."
}
]
}
]
},

View file

@ -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"],
))

View file

@ -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

View file

@ -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

View file

@ -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("")

View file

@ -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"]

View file

@ -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

View file

@ -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,

View file

@ -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):

View file

@ -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

View file

@ -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"])

View file

@ -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)

View file

@ -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:

View file

@ -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

View file

@ -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"]

View file

@ -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 >")

View file

@ -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()

View file

@ -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"]

View file

@ -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)

View file

@ -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 >")

View file

@ -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)

View file

@ -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",
)

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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'],

View file

@ -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

View file

@ -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

View file

@ -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 []

View file

@ -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)

View file

@ -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):

View file

@ -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:

View file

@ -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,

View file

@ -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)