Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
#663 - Added load/update/remove implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
kalisp committed Oct 28, 2020
1 parent 02e906d commit c3018ba
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 4 deletions.
41 changes: 37 additions & 4 deletions pype/modules/websocket_server/stubs/aftereffects_server_stub.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
from collections import namedtuple


import logging
log = logging.getLogger(__name__)

class AfterEffectsServerStub():
"""
Stub for calling function on client (Photoshop js) side.
Expand Down Expand Up @@ -44,10 +47,15 @@ def read(self, layer, layers_meta=None):
return layers_meta.get(str(layer.id))

def get_metadata(self):
layers_data = {}
res = self.websocketserver.call(self.client.call
('AfterEffects.get_metadata')
)
return self._to_records(res)
try:
layers_data = json.loads(res)
except json.decoder.JSONDecodeError:
raise ValueError("Unparsable metadata {}".format(res))
return layers_data or {}

def imprint(self, layer, data, all_layers=None, layers_meta=None):
"""
Expand All @@ -65,6 +73,7 @@ def imprint(self, layer, data, all_layers=None, layers_meta=None):
"""
if not layers_meta:
layers_meta = self.get_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)]:
Expand All @@ -74,13 +83,11 @@ def imprint(self, layer, data, all_layers=None, layers_meta=None):
layers_meta.pop(str(layer.id))
else:
layers_meta[str(layer.id)] = data

# Ensure only valid ids are stored.
if not all_layers:
all_layers = self.get_items(False)
item_ids = [item.id for item in all_layers]
item_ids = [int(item.id) for item in all_layers]
cleaned_data = {}

for id in layers_meta:
if int(id) in item_ids:
cleaned_data[id] = layers_meta[id]
Expand Down Expand Up @@ -118,6 +125,28 @@ def get_items(self, layers=True):
)
return self._to_records(res)

def import_file(self, path, item_name):
res = self.websocketserver.call(self.client.call(
'AfterEffects.import_file',
path=path,
item_name=item_name)
)
return self._to_records(res).pop()

def replace_item(self, item, path, item_name):
""" item is currently comp, might be layer, investigate TODO """
self.websocketserver.call(self.client.call
('AfterEffects.replace_item',
item_id=item.id,
path=path, item_name=item_name))

def delete_item(self, item):
""" item is currently comp, might be layer, investigate TODO """
self.websocketserver.call(self.client.call
('AfterEffects.delete_item',
item_id=item.id
))

def is_saved(self):
# TODO
return True
Expand Down Expand Up @@ -153,12 +182,16 @@ def _to_records(self, res):
Returns: <list of named tuples>
res(string): - json representation
"""
if not res:
return []

try:
layers_data = json.loads(res)
except json.decoder.JSONDecodeError:
raise ValueError("Received broken JSON {}".format(res))
if not layers_data:
return []

ret = []
# convert to namedtuple to use dot donation
if isinstance(layers_data, dict): # TODO refactore
Expand Down
72 changes: 72 additions & 0 deletions pype/plugins/aftereffects/load/load_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from avalon import api, aftereffects
from pype.plugins import lib
import re

stub = aftereffects.stub()


class ImageLoader(api.Loader):
"""Load images
Stores the imported asset in a container named after the asset.
"""

families = ["image"]
representations = ["*"]

def load(self, context, name=None, namespace=None, data=None):
print("Load:::")
layer_name = lib.get_unique_layer_name(stub.get_items(False),
context["asset"]["name"],
name)
#with photoshop.maintained_selection():
comp = stub.import_file(self.fname, layer_name)

self[:] = [comp]
namespace = namespace or layer_name

return aftereffects.containerise(
name,
namespace,
comp,
context,
self.__class__.__name__
)

def update(self, container, representation):
""" Switch asset or change version """
layer = container.pop("layer")

context = representation.get("context", {})

namespace_from_container = re.sub(r'_\d{3}$', '',
container["namespace"])
layer_name = "{}_{}".format(context["asset"], context["subset"])
# switching assets
if namespace_from_container != layer_name:
layer_name = lib.get_unique_layer_name(stub.get_items(False),
context["asset"],
context["subset"])
else: # switching version - keep same name
layer_name = container["namespace"]
path = api.get_representation_path(representation)
# with aftereffects.maintained_selection(): # TODO
stub.replace_item(layer, path, layer_name)
stub.imprint(
layer, {"representation": str(representation["_id"])}
)

def remove(self, container):
"""
Removes element from scene: deletes layer + removes from Headline
Args:
container (dict): container to be removed - used to get layer_id
"""
layer = container.pop("layer")
stub.imprint(layer, {})
stub.delete_layer(layer.id)

def switch(self, container, representation):
self.update(container, representation)


25 changes: 25 additions & 0 deletions pype/plugins/lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import re

def get_unique_layer_name(layers, asset_name, subset_name):
"""
Gets all layer names and if 'name' is present in them, increases
suffix by 1 (eg. creates unique layer name - for Loader)
Args:
layers (list): of namedtuples, expects 'name' field present
asset_name (string): in format asset_subset (Hero)
subset_name (string): (LOD)
Returns:
(string): name_00X (without version)
"""
name = "{}_{}".format(asset_name, subset_name)
names = {}
for layer in layers:
layer_name = re.sub(r'_\d{3}$', '', layer.name)
if layer_name in names.keys():
names[layer_name] = names[layer_name] + 1
else:
names[layer_name] = 1
occurrences = names.get(name, 0)

return "{}_{:0>3d}".format(name, occurrences + 1)

0 comments on commit c3018ba

Please sign in to comment.