Advertisement
Uno-Dan

Updated cache code.

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