Advertisement
Uno-Dan

Untitled

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