Submit
Path:
~
/
/
opt
/
psa
/
admin
/
plib
/
modules
/
site-import
/
backend
/
lib
/
python
/
plesk_migrator
/
sdk
/
File Content:
entity.py
import inspect import yaml from plesk_migrator.sdk.dict_utils import merge_dicts def entity_pretty_yaml(cls): """Set up YAML library to dump/load entity class as mapping.""" if cls.yaml_prefix is not None: prefix_str = "%s." % cls.yaml_prefix else: prefix_str = "" tag = u'!%s%s' % (prefix_str, cls.__name__) def namedtuple_representer(dumper, data): return dumper.represent_mapping(tag, data.as_dictionary()) def namedtuple_constructor(loader, node): return cls(**loader.construct_mapping(node)) yaml.add_representer(cls, namedtuple_representer) yaml.add_constructor(tag, namedtuple_constructor) return cls class EntityMetaclass(type): def __new__(mcs, class_name, class_parents, class_attr): c = super(EntityMetaclass, mcs).__new__(mcs, class_name, class_parents, class_attr) entity_pretty_yaml(c) return c class Entity(metaclass=EntityMetaclass): yaml_prefix = None @property def properties_list(self): """List names of properties of this entity By default, all constructor arguments are considered as entity properties. :rtype: [str] """ args = inspect.getfullargspec(self.__init__).args return [arg for arg in args if arg != 'self'] @property def properties_set(self): """List names of properties of this entity By default, all constructor arguments are considered as entity properties. :rtype: set[str] """ return set(inspect.getfullargspec(self.__init__).args) - {'self'} def as_dictionary(self, recursive=False): if recursive: return self._recursive_as_dictionary(self) else: result = {} for property_name in self.properties_list: property_value = getattr(self, property_name) result[property_name] = property_value return result @classmethod def _recursive_as_dictionary(cls, entity_object): if isinstance(entity_object, Entity): result = {} for property_name in entity_object.properties_list: property_value = getattr(entity_object, property_name) property_value = cls._recursive_as_dictionary(property_value) result[property_name] = property_value return result elif isinstance(entity_object, list): result = [] for item in entity_object: result.append(cls._recursive_as_dictionary(item)) return result elif isinstance(entity_object, dict): result = {} for k, v in entity_object.items(): result[k] = cls._recursive_as_dictionary(v) return result else: return entity_object def clone(self, **kwargs): """Clone entity. Optionally replace attributes with another ones""" attributes = self.as_dictionary() for k, v in kwargs.items(): attributes[k] = v return self.__class__(**attributes) @classmethod def create_none_filled(cls, **kwargs): args = inspect.getfullargspec(cls.__init__).args properties = merge_dicts( {name: None for name in set(args) - {'self'}}, kwargs ) return cls(**properties) @staticmethod def _meta_attributes(): return {'properties_list', 'properties_set', 'as_dictionary', 'yaml_prefix', 'create_none_filled', 'clone'} def __str__(self): properties = ', '.join([ "%s=%s" % (p, self._format_property_value(getattr(self, p))) for p in self.properties_list ]) return '%s(%s)' % (self.__class__.__name__, properties) def __repr__(self): return str(self) def _format_property_value(self, prop): if isinstance(prop, list): return '[%s]' % ', '.join([self._format_property_value(i) for i in prop]) if isinstance(prop, Entity): return str(prop) else: return repr(prop) def __eq__(self, other): return type(self) == type(other) and all([ getattr(self, prop) == getattr(other, prop) for prop in self.properties_list ]) def __ne__(self, other): return not self.__eq__(other) def __iter__(self): for field in self.properties_list: yield getattr(self, field)
Edit
Rename
Chmod
Delete
FILE
FOLDER
INFO
Name
Size
Permission
Action
parsers
---
0755
__init__.py
0 bytes
0644
dict_utils.py
302 bytes
0644
entity.py
4480 bytes
0644
utils.py
9475 bytes
0644
N4ST4R_ID | Naxtarrr