OP-2766 - implemented auto creator for PS

Creates workfile instance, updated imprint function.
This commit is contained in:
Petr Kalis 2022-03-14 17:35:17 +01:00
parent 65b0045561
commit a71dad4608
3 changed files with 131 additions and 27 deletions

View file

@ -8,7 +8,7 @@ from avalon import pipeline, io
from openpype.api import Logger
from openpype.lib import register_event_callback
from openpype.pipeline import LegacyCreator
from openpype.pipeline import LegacyCreator, BaseCreator
import openpype.hosts.photoshop
from . import lib
@ -71,6 +71,7 @@ def install():
pyblish.api.register_plugin_path(PUBLISH_PATH)
avalon.api.register_plugin_path(avalon.api.Loader, LOAD_PATH)
avalon.api.register_plugin_path(LegacyCreator, CREATE_PATH)
avalon.api.register_plugin_path(BaseCreator, CREATE_PATH)
log.info(PUBLISH_PATH)
pyblish.api.register_callback(
@ -144,12 +145,9 @@ def list_instances():
layers_meta = stub.get_layers_metadata()
if layers_meta:
for key, instance in layers_meta.items():
schema = instance.get("schema")
if schema and "container" in schema:
continue
instance['uuid'] = key
instances.append(instance)
if instance.get("id") == "pyblish.avalon.instance": # TODO only this way?
instance['uuid'] = key
instances.append(instance)
return instances
@ -170,11 +168,18 @@ def remove_instance(instance):
if not stub:
return
stub.remove_instance(instance.get("uuid"))
layer = stub.get_layer(instance.get("uuid"))
if layer:
stub.rename_layer(instance.get("uuid"),
layer.name.replace(stub.PUBLISH_ICON, ''))
inst_id = instance.get("instance_id") or instance.get("uuid") # legacy
if not inst_id:
log.warning("No instance identifier for {}".format(instance))
return
stub.remove_instance(inst_id)
if instance.get("members"):
item = stub.get_item(instance["members"][0])
if item:
stub.rename_item(item.id,
item.name.replace(stub.PUBLISH_ICON, ''))
def _get_stub():
@ -226,6 +231,27 @@ def containerise(
"members": [str(layer.id)]
}
stub = lib.stub()
stub.imprint(layer, data)
stub.imprint(layer.id, data)
return layer
def get_context_data():
pass
def update_context_data(data, changes):
# item = data
# item["id"] = "publish_context"
# _get_stub().imprint(item["id"], item)
pass
def get_context_title():
"""Returns title for Creator window"""
import avalon.api
project_name = avalon.api.Session["AVALON_PROJECT"]
asset_name = avalon.api.Session["AVALON_ASSET"]
task_name = avalon.api.Session["AVALON_TASK"]
return "{}/{}/{}".format(project_name, asset_name, task_name)

View file

@ -27,6 +27,7 @@ class PSItem(object):
members = attr.ib(factory=list)
long_name = attr.ib(default=None)
color_code = attr.ib(default=None) # color code of layer
instance_id = attr.ib(default=None)
class PhotoshopServerStub:
@ -82,7 +83,7 @@ class PhotoshopServerStub:
return layers_meta.get(str(layer.id))
def imprint(self, layer, data, all_layers=None, layers_meta=None):
def imprint(self, item_id, data, all_layers=None, items_meta=None):
"""Save layer metadata to Headline field of active document
Stores metadata in format:
@ -108,28 +109,29 @@ class PhotoshopServerStub:
}] - for loaded instances
Args:
layer (PSItem):
item_id (str):
data(string): json representation for single layer
all_layers (list of PSItem): for performance, could be
injected for usage in loop, if not, single call will be
triggered
layers_meta(string): json representation from Headline
items_meta(string): json representation from Headline
(for performance - provide only if imprint is in
loop - value should be same)
Returns: None
"""
if not layers_meta:
layers_meta = self.get_layers_metadata()
if not items_meta:
items_meta = self.get_layers_metadata()
# json.dumps writes integer values in a dictionary to string, so
# anticipating it here.
if str(layer.id) in layers_meta and layers_meta[str(layer.id)]:
item_id = str(item_id)
if item_id in items_meta.keys():
if data:
layers_meta[str(layer.id)].update(data)
items_meta[item_id].update(data)
else:
layers_meta.pop(str(layer.id))
items_meta.pop(item_id)
else:
layers_meta[str(layer.id)] = data
items_meta[item_id] = data
# Ensure only valid ids are stored.
if not all_layers:
@ -137,12 +139,14 @@ class PhotoshopServerStub:
layer_ids = [layer.id for layer in all_layers]
cleaned_data = []
for layer_id in layers_meta:
if int(layer_id) in layer_ids:
cleaned_data.append(layers_meta[layer_id])
for item in items_meta.values():
if item.get("members"):
if int(item["members"][0]) not in layer_ids:
continue
cleaned_data.append(item)
payload = json.dumps(cleaned_data, indent=4)
self.websocketserver.call(
self.client.call('Photoshop.imprint', payload=payload)
)
@ -528,6 +532,7 @@ class PhotoshopServerStub:
d.get('type'),
d.get('members'),
d.get('long_name'),
d.get("color_code")
d.get("color_code"),
d.get("instance_id")
))
return ret

View file

@ -0,0 +1,73 @@
from avalon import io
import openpype.hosts.photoshop.api as api
from openpype.pipeline import (
AutoCreator,
CreatedInstance
)
class PSWorkfileCreator(AutoCreator):
identifier = "workfile"
family = "workfile"
def get_instance_attr_defs(self):
return []
def collect_instances(self):
for instance_data in api.list_instances():
creator_id = instance_data.get("creator_identifier")
if creator_id == self.identifier:
subset_name = instance_data["subset"]
instance = CreatedInstance(
self.family, subset_name, instance_data, self
)
self._add_instance_to_context(instance)
def update_instances(self, update_list):
# nothing to change on workfiles
pass
def create(self, options=None):
existing_instance = None
for instance in self.create_context.instances:
if instance.family == self.family:
existing_instance = instance
break
variant = ''
project_name = io.Session["AVALON_PROJECT"]
asset_name = io.Session["AVALON_ASSET"]
task_name = io.Session["AVALON_TASK"]
host_name = io.Session["AVALON_APP"]
if existing_instance is None:
asset_doc = io.find_one({"type": "asset", "name": asset_name})
subset_name = self.get_subset_name(
variant, task_name, asset_doc, project_name, host_name
)
data = {
"asset": asset_name,
"task": task_name,
"variant": variant
}
data.update(self.get_dynamic_data(
variant, task_name, asset_doc, project_name, host_name
))
new_instance = CreatedInstance(
self.family, subset_name, data, self
)
self._add_instance_to_context(new_instance)
api.stub().imprint(new_instance.get("instance_id"),
new_instance.data_to_store())
elif (
existing_instance["asset"] != asset_name
or existing_instance["task"] != task_name
):
asset_doc = io.find_one({"type": "asset", "name": asset_name})
subset_name = self.get_subset_name(
variant, task_name, asset_doc, project_name, host_name
)
existing_instance["asset"] = asset_name
existing_instance["task"] = task_name