Advertisement
Uno-Dan

Untitled

Jan 25th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.26 KB | None | 0 0
  1. ########################################################################################################################
  2. #    File: dict2object.py
  3. #  Author: Dan Huckson, https://github.com/unodan
  4. #    Date: 2019-01-25
  5. ########################################################################################################################
  6.  
  7.  
  8. class _BaseObject:
  9.     def __init__(self, path, **config):
  10.         self._id = None
  11.         self._uri = None
  12.         self._type = None
  13.         self._parent = None
  14.         self._config = config
  15.  
  16.         for key, value in config.items():
  17.             if isinstance(value, dict):
  18.                 if key in dir(self):
  19.                     attributes = []
  20.                     for attribute in dir(self):
  21.                         if attribute.startswith('_'):
  22.                             continue
  23.                         attributes.append(attribute)
  24.                     attributes = ', '.join(attributes)
  25.                     _class = f'<{self.__class__.__name__}>'
  26.                     raise KeyError(f'The key "{key}" is a {_class} reserved attribute. Reserved Keywords: {attributes}')
  27.  
  28.                 uri = f'{path}/{key}'
  29.                 if 'type' not in value:
  30.                     msg = f'No type has been specified for node with id={key}, uri={uri}, nodes must have a type.'
  31.                     raise KeyError(msg)
  32.  
  33.                 obj = self.__dict__[key] = _BaseObject(uri, **value)
  34.                 obj._id = key
  35.                 obj._uri = uri.lstrip('/')
  36.                 obj._type = value['type']
  37.             else:
  38.                 self.__dict__[key] = value
  39.  
  40.     @property
  41.     def id(self):
  42.         return self._id
  43.  
  44.     @property
  45.     def uri(self):
  46.         return self._uri
  47.  
  48.     @property
  49.     def type(self):
  50.         return self._type
  51.  
  52.     @property
  53.     def config(self):
  54.         return self._config
  55.  
  56.     @property
  57.     def parent(self):
  58.         return self._parent
  59.  
  60.     @parent.setter
  61.     def parent(self, value):
  62.         self._parent = value
  63.  
  64.     @property
  65.     def nodes(self):
  66.         kids = {}
  67.         for _id, node in self.__dict__.items():
  68.             if isinstance(node, _BaseObject) and _id == node.id:
  69.                 kids[_id] = node
  70.         return kids
  71.  
  72.     @property
  73.     def has_nodes(self):
  74.         return len(self.nodes)
  75.  
  76.     def get(self, *args):
  77.         if args[0] is None:
  78.             return self
  79.  
  80.         def walk(_parent, target):
  81.             uri_parts = target.split('/')
  82.             _id = uri_parts[0]
  83.  
  84.             if len(uri_parts) == 1 and f'{_parent.uri}/{_id}' == uri and hasattr(_parent, _id):
  85.                 return getattr(_parent, _id)
  86.             elif hasattr(_parent, _id):
  87.                 node = getattr(_parent, _id)
  88.                 if node.uri == uri:
  89.                     return node
  90.                 else:
  91.                     uri_parts.pop(0)
  92.                     return walk(node, '/'.join(uri_parts).lstrip('/'))
  93.             else:
  94.                 return default
  95.  
  96.         uri = args[0].lstrip('/')
  97.  
  98.         if not hasattr(self.parent, 'parent'):
  99.             parent = self
  100.         else:
  101.             uri = f'{self.uri}/{uri}'
  102.             parent = self.get_window().parent
  103.  
  104.         parts = uri.split('/', 1)
  105.         default = None if len(args) < 2 else args[1]
  106.  
  107.         if len(parts) == 1:
  108.             if parts[0] in self.nodes:
  109.                 return self.nodes[parts[0]]
  110.             else:
  111.                 raise KeyError(f'Object with id = "{parts[0]}", could not be found.')
  112.  
  113.         if not parts[0] in parent.nodes:
  114.             raise KeyError(f'Object with id = "{parts[0]}", could not be found.')
  115.  
  116.         return walk(parent.nodes[parts[0]], parts[1])
  117.  
  118.     def set(self, key, value):
  119.         parts = key.split('/')
  120.         if len(parts) > 1:
  121.             attribute = parts.pop()
  122.             uri = f'{self.uri}/{"/".join(parts)}'
  123.             parent = self.get_window().parent.get(uri)
  124.         else:
  125.             parent = self
  126.             attribute = key
  127.  
  128.         setattr(parent, attribute, value)
  129.  
  130.     def dump(self, indent=None):
  131.         indent = indent if indent else ''
  132.  
  133.         def walkit(nodes, count=0):
  134.             for node in nodes.values():
  135.                 if isinstance(node, _BaseObject):
  136.                     print(indent * count, node.id, node)
  137.                     walkit(node.nodes, count+1)
  138.  
  139.         walkit(self.nodes)
  140.  
  141.     def get_group(self):
  142.         def walk(node):
  143.             if hasattr(node, 'parent'):
  144.                 if 'Group' in node.type:
  145.                     return node
  146.                 return walk(node.parent)
  147.  
  148.         return walk(self)
  149.  
  150.     def get_widget(self):
  151.         def walk(node):
  152.             if hasattr(node, 'parent'):
  153.                 if 'Widget' in node.type:
  154.                     return node
  155.                 return walk(node.parent)
  156.  
  157.         return walk(self)
  158.  
  159.     def get_window(self):
  160.         def walk(node):
  161.             if 'Window' in node.type:
  162.                 return node
  163.             return walk(node.parent)
  164.         return walk(self)
  165.  
  166.     def get_attribute(self, *args):
  167.         if not args:
  168.             return
  169.  
  170.         if hasattr(self, args[0]):
  171.             return getattr(self, args[0])
  172.         elif len(args) > 1:
  173.             return args[1]
  174.  
  175.         return None
  176.  
  177.     def set_attribute(self, attribute, value):
  178.         setattr(self, attribute, value)
  179.  
  180.  
  181. class MyObject(_BaseObject):
  182.     def __init__(self, uri='', **config):
  183.         super().__init__(uri, **config)
  184.  
  185.         def walk(parent):
  186.             for i, j in parent.nodes.items():
  187.                 j.parent = parent
  188.                 if j.has_nodes:
  189.                     walk(j)
  190.         walk(self)
  191.  
  192.  
  193. def main():
  194.     config = {
  195.         'main': {
  196.             'title': 'My Window',
  197.             'type': 'Window',
  198.             'bd': 10,
  199.             'relief': 'raised',
  200.             'themed': True,
  201.             'bg': 'green',
  202.             'sticky': 'nsew',
  203.             'tooltip': 'Testing 123...',
  204.  
  205.             'top': {
  206.                 'type': 'LabelGroup',
  207.                 'text': ' Location ',
  208.                 'bg': 'gray',
  209.                 'widget': {
  210.                     'type': 'Widget',
  211.                     'label': {
  212.                         'type': 'Label',
  213.                         'bg': 'gray',
  214.                         'text': 'Entry Label ',
  215.                         'sticky': 'ne',
  216.                         'tooltip': 'Tooltip Combobox Label'
  217.                     },
  218.                     'group': {
  219.                         'type': 'LabelGroup',
  220.                         'text': ' Location ',
  221.                         'bg': 'gray',
  222.                         'widget': {
  223.                             'type': 'Widget',
  224.                             'label': {
  225.                                 'text': 'Entry Label ',
  226.                                 'sticky': 'ne',
  227.                                 'tooltip': 'Tooltip Combobox Label'
  228.                             },
  229.                         },
  230.                     },
  231.                 },
  232.             },
  233.         },
  234.     }
  235.  
  236.     obj = MyObject(**config)
  237.  
  238.     print()
  239.     obj.dump(indent='..')
  240.     print()
  241.  
  242.     e = obj.get('/main')
  243.     print('Window Title:', e.get('title'))
  244.  
  245.     e = obj.get('/main/top/widget/group/widget/label')
  246.  
  247.     print('color before', e.get_attribute('bg'))
  248.     e.set_attribute('bg', 'orange')
  249.     print('color after', e.get_attribute('bg'))
  250.  
  251.     print('color accessed by dot notation >', obj.main.top.widget.group.widget.label.bg)
  252.     print('access top level window by dot notation >', e.parent.parent.parent.parent.parent.id)
  253.     print('access top level window by property method >', e.get_window().id, e.get_window().parent.id)
  254.     print('access parent group by property method >', e.get_group().id, e.get_group().type)
  255.     print('access parent widget by property method >', e.get_widget().id, e.get_widget().type)
  256.     print()
  257.     print('Target:', e.id, e.type, e.uri)
  258.     print('Background:', e.get_attribute('bg'))
  259.  
  260.     e.set('bg', 'green')
  261.     print('Background:', e.get_attribute('bg'))
  262.  
  263.     e = obj.get('/main/top/widget/group')
  264.     e.set('widget/label/bg', 'brown')
  265.  
  266.     print('Get background from URI method:', e.get('widget/label/bg'))
  267.     print('Get background from Dot method:', obj.main.top.widget.group.widget.label.bg)
  268.  
  269.  
  270. if __name__ == '__main__':
  271.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement