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

Commit

Permalink
Merge pull request #3972 from pypeclub/feature/OP-4194_Remote-publish…
Browse files Browse the repository at this point in the history
…er-controller

Publisher: Prepare publisher controller  for remote publishing
  • Loading branch information
iLLiCiTiT authored Oct 19, 2022
2 parents 41e7382 + 4641cb5 commit 1faa672
Show file tree
Hide file tree
Showing 21 changed files with 2,608 additions and 677 deletions.
175 changes: 173 additions & 2 deletions openpype/lib/attribute_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,33 @@
import collections
import uuid
import json
from abc import ABCMeta, abstractmethod
from abc import ABCMeta, abstractmethod, abstractproperty

import six
import clique

# Global variable which store attribude definitions by type
# - default types are registered on import
_attr_defs_by_type = {}


def register_attr_def_class(cls):
"""Register attribute definition.
Currently are registered definitions used to deserialize data to objects.
Attrs:
cls (AbtractAttrDef): Non-abstract class to be registered with unique
'type' attribute.
Raises:
KeyError: When type was already registered.
"""

if cls.type in _attr_defs_by_type:
raise KeyError("Type \"{}\" was already registered".format(cls.type))
_attr_defs_by_type[cls.type] = cls


def get_attributes_keys(attribute_definitions):
"""Collect keys from list of attribute definitions.
Expand Down Expand Up @@ -90,6 +112,8 @@ class AbtractAttrDef:
next to value input or ahead.
"""

type_attributes = []

is_value_def = True

def __init__(
Expand All @@ -115,6 +139,16 @@ def __eq__(self, other):
return False
return self.key == other.key

@abstractproperty
def type(self):
"""Attribute definition type also used as identifier of class.
Returns:
str: Type of attribute definition.
"""

pass

@abstractmethod
def convert_value(self, value):
"""Convert value to a valid one.
Expand All @@ -125,6 +159,35 @@ def convert_value(self, value):

pass

def serialize(self):
"""Serialize object to data so it's possible to recreate it.
Returns:
Dict[str, Any]: Serialized object that can be passed to
'deserialize' method.
"""

data = {
"type": self.type,
"key": self.key,
"label": self.label,
"tooltip": self.tooltip,
"default": self.default,
"is_label_horizontal": self.is_label_horizontal
}
for attr in self.type_attributes:
data[attr] = getattr(self, attr)
return data

@classmethod
def deserialize(cls, data):
"""Recreate object from data.
Data can be received using 'serialize' method.
"""

return cls(**data)


# -----------------------------------------
# UI attribute definitoins won't hold value
Expand All @@ -141,10 +204,12 @@ def convert_value(self, value):


class UISeparatorDef(UIDef):
pass
type = "separator"


class UILabelDef(UIDef):
type = "label"

def __init__(self, label):
super(UILabelDef, self).__init__(label=label)

Expand All @@ -160,6 +225,8 @@ class UnknownDef(AbtractAttrDef):
have known definition of type.
"""

type = "unknown"

def __init__(self, key, default=None, **kwargs):
kwargs["default"] = default
super(UnknownDef, self).__init__(key, **kwargs)
Expand All @@ -181,6 +248,13 @@ class NumberDef(AbtractAttrDef):
default(int, float): Default value for conversion.
"""

type = "number"
type_attributes = [
"minimum",
"maximum",
"decimals"
]

def __init__(
self, key, minimum=None, maximum=None, decimals=None, default=None,
**kwargs
Expand Down Expand Up @@ -252,6 +326,12 @@ class TextDef(AbtractAttrDef):
default(str, None): Default value. Empty string used when not defined.
"""

type = "text"
type_attributes = [
"multiline",
"placeholder",
]

def __init__(
self, key, multiline=None, regex=None, placeholder=None, default=None,
**kwargs
Expand Down Expand Up @@ -290,6 +370,11 @@ def convert_value(self, value):
return value
return self.default

def serialize(self):
data = super(TextDef, self).serialize()
data["regex"] = self.regex.pattern
return data


class EnumDef(AbtractAttrDef):
"""Enumeration of single item from items.
Expand All @@ -301,6 +386,8 @@ class EnumDef(AbtractAttrDef):
default: Default value. Must be one key(value) from passed items.
"""

type = "enum"

def __init__(self, key, items, default=None, **kwargs):
if not items:
raise ValueError((
Expand Down Expand Up @@ -335,6 +422,11 @@ def convert_value(self, value):
return value
return self.default

def serialize(self):
data = super(TextDef, self).serialize()
data["items"] = list(self.items)
return data


class BoolDef(AbtractAttrDef):
"""Boolean representation.
Expand All @@ -343,6 +435,8 @@ class BoolDef(AbtractAttrDef):
default(bool): Default value. Set to `False` if not defined.
"""

type = "bool"

def __init__(self, key, default=None, **kwargs):
if default is None:
default = False
Expand Down Expand Up @@ -585,6 +679,15 @@ class FileDef(AbtractAttrDef):
default(str, List[str]): Default value.
"""

type = "path"
type_attributes = [
"single_item",
"folders",
"extensions",
"allow_sequences",
"extensions_label",
]

def __init__(
self, key, single_item=True, folders=None, extensions=None,
allow_sequences=True, extensions_label=None, default=None, **kwargs
Expand Down Expand Up @@ -675,3 +778,71 @@ def convert_value(self, value):
if self.single_item:
return FileDefItem.create_empty_item().to_dict()
return []


def serialize_attr_def(attr_def):
"""Serialize attribute definition to data.
Args:
attr_def (AbtractAttrDef): Attribute definition to serialize.
Returns:
Dict[str, Any]: Serialized data.
"""

return attr_def.serialize()


def serialize_attr_defs(attr_defs):
"""Serialize attribute definitions to data.
Args:
attr_defs (List[AbtractAttrDef]): Attribute definitions to serialize.
Returns:
List[Dict[str, Any]]: Serialized data.
"""

return [
serialize_attr_def(attr_def)
for attr_def in attr_defs
]


def deserialize_attr_def(attr_def_data):
"""Deserialize attribute definition from data.
Args:
attr_def (Dict[str, Any]): Attribute definition data to deserialize.
"""

attr_type = attr_def_data.pop("type")
cls = _attr_defs_by_type[attr_type]
return cls.deserialize(attr_def_data)


def deserialize_attr_defs(attr_defs_data):
"""Deserialize attribute definitions.
Args:
List[Dict[str, Any]]: List of attribute definitions.
"""

return [
deserialize_attr_def(attr_def_data)
for attr_def_data in attr_defs_data
]


# Register attribute definitions
for _attr_class in (
UISeparatorDef,
UILabelDef,
UnknownDef,
NumberDef,
TextDef,
EnumDef,
BoolDef,
FileDef
):
register_attr_def_class(_attr_class)
49 changes: 49 additions & 0 deletions openpype/lib/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Events holding data about specific event."""
import os
import re
import copy
import inspect
import logging
import weakref
Expand Down Expand Up @@ -207,6 +208,12 @@ def id(self):

@property
def source(self):
"""Event's source used for triggering callbacks.
Returns:
Union[str, None]: Source string or None. Source is optional.
"""

return self._source

@property
Expand All @@ -215,6 +222,12 @@ def data(self):

@property
def topic(self):
"""Event's topic used for triggering callbacks.
Returns:
str: Topic string.
"""

return self._topic

def emit(self):
Expand All @@ -227,6 +240,42 @@ def emit(self):
)
self._event_system.emit_event(self)

def to_data(self):
"""Convert Event object to data.
Returns:
Dict[str, Any]: Event data.
"""

return {
"id": self.id,
"topic": self.topic,
"source": self.source,
"data": copy.deepcopy(self.data)
}

@classmethod
def from_data(cls, event_data, event_system=None):
"""Create event from data.
Args:
event_data (Dict[str, Any]): Event data with defined keys. Can be
created using 'to_data' method.
event_system (EventSystem): System to which the event belongs.
Returns:
Event: Event with attributes from passed data.
"""

obj = cls(
event_data["topic"],
event_data["data"],
event_data["source"],
event_system
)
obj._id = event_data["id"]
return obj


class EventSystem(object):
"""Encapsulate event handling into an object.
Expand Down
Loading

0 comments on commit 1faa672

Please sign in to comment.