Advertisement
Uno-Dan

The Monster Cache

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