Advertisement
Uno-Dan

Production Version

Sep 7th, 2019
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.78 KB | None | 0 0
  1. from os import path, makedirs
  2. from json import load, dump
  3. from copy import deepcopy
  4. from importlib.util import module_from_spec, spec_from_file_location
  5.  
  6. more_cfg = {
  7.     'level_3': {
  8.         'level_4': {
  9.             'item3': 10,
  10.             'item4': 20,
  11.         }
  12.     }
  13. }
  14.  
  15.  
  16. class Cache:
  17.     def __init__(self, *args, **kwargs):
  18.         self.nodes = args[0] if args else kwargs
  19.         self.indent = '.'
  20.  
  21.     def __str__(self):
  22.         return str(self.nodes.items())
  23.  
  24.     def __repr__(self):
  25.         data = "**{'key': 'value'}"
  26.         return f"{self.__class__.__name__}({data})"
  27.  
  28.     def get(self, uri=None):
  29.         if not uri:
  30.             return self.nodes
  31.  
  32.         def walk(_uri, nodes):
  33.             parts = _uri.split('/', 1)
  34.             key = parts.pop(0)
  35.  
  36.             if key in nodes:
  37.                 node = nodes[key]
  38.  
  39.                 if not parts:
  40.                     return node
  41.                 else:
  42.                     return walk(parts[0], node)
  43.  
  44.         return walk(uri, self.nodes)
  45.  
  46.     def set(self, uri, *args, **kwargs):
  47.  
  48.         def walk(_uri, nodes):
  49.             parts = _uri.split('/', 1)
  50.             key = parts.pop(0)
  51.  
  52.             if key in nodes and parts:
  53.                 return walk(parts[0], nodes[key])
  54.             elif len(_uri.split('/')) == 1:
  55.                 value = args[0] if args else kwargs
  56.                 nodes[key] = value
  57.  
  58.         return walk(uri, self.nodes)
  59.  
  60.     def dump(self, indent=None):
  61.         """ Dumps the contents of the cache to the screen.
  62.        The output from dump goes stdout and is used to view the cache contents.
  63.        Default indentation is a dot for each level.
  64.        :param indent:
  65.            indent (str): String to be use for indenting levels.
  66.        :return:
  67.            Nothing.
  68.        """
  69.         indent = indent if indent else '.'
  70.  
  71.         print('-------------------------------------------------------------------------------------------------------')
  72.         print('id =', id(self), '\nnodes =', self)
  73.         if self.nodes:
  74.             def walk(_cfg, count):
  75.                 count += 1
  76.                 for key, value in _cfg.items():
  77.                     if isinstance(value, dict):
  78.                         print(indent * count, key)
  79.                         walk(value, count)
  80.                     else:
  81.                         if isinstance(value, str):
  82.                             value = f'"{value}"'
  83.                         print(indent * count, key, f'value={value}')
  84.             walk(self.nodes, 0)
  85.         else:
  86.             print(' (No Data)')
  87.  
  88.         print('-------------------------------------------------------------------------------------------------------')
  89.  
  90.     def save(self, file=None):
  91.         if file:
  92.             dirname = path.dirname(file)
  93.  
  94.             if dirname and not path.exists(dirname):
  95.                 makedirs(dirname)
  96.  
  97.             with open(file, 'w') as f:
  98.                 dump(self.nodes, f, indent=3)
  99.  
  100.     def load(self, file=None):
  101.         file_type = path.splitext(file)[1].lstrip('.').lower()
  102.  
  103.         if file_type == 'py' and path.exists(file):
  104.             spec = spec_from_file_location("module.name", file)
  105.             module = module_from_spec(spec)
  106.             spec.loader.exec_module(module)
  107.             self.nodes = module.config
  108.  
  109.         if file_type == 'json' and path.exists(file):
  110.             with open(file) as f:
  111.                 self.nodes = load(f)
  112.  
  113.     def copy(self):
  114.         return Cache(deepcopy(self.nodes))
  115.  
  116.     def remove(self, uri):
  117.         """ Remove entree from cache.
  118.        Removes an entree from the cache if it exists.
  119.        :param uri:
  120.            uri (str): URI that points to the entree to remove.
  121.        :return:
  122.            Nothing.
  123.        """
  124.  
  125.         uri = uri.lstrip('/')
  126.         if self.exists(uri):
  127.             node = self.get('/'.join(uri.split('/')[:-1]))
  128.             del node[uri.split('/')[-1]]
  129.  
  130.     def exists(self, uri):
  131.         """ Test if URI exists in the cache.
  132.  
  133.        :param uri:
  134.        :return:
  135.        """
  136.         return True if self.get(uri) else False
  137.  
  138.     def destroy(self):
  139.         """ Destroy cache.
  140.        Deletes all entries in the cache.
  141.        :return:
  142.            Nothing.
  143.        """
  144.         del self.nodes
  145.         self.nodes = {}
  146.  
  147.  
  148. c = Cache()
  149. c.load('data.py')
  150.  
  151. print(c.get('level_1/level_2/item2'))
  152.  
  153. c.set('level_1/level_2/more_cfg', more_cfg)
  154.  
  155. if c.exists('level_1/level_2/more_cfg'):
  156.     print(c.get('level_1/level_2/more_cfg'))
  157.  
  158. c.save('data.json')
  159.  
  160. cache_copy = c.copy()
  161. cache_copy.dump()
  162.  
  163. c.remove('level_1/level_2/item1')
  164. c.remove('level_1/level_2/more_cfg')
  165. c.dump()
  166.  
  167. cache_copy.dump()
  168.  
  169. my_cache = Cache()
  170. my_cache.load('data.json')
  171. my_cache.dump()
  172.  
  173. print('my_cache =', str(my_cache))
  174. print('my_cache =', repr(my_cache))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement