Advertisement
Uno-Dan

Latest Version

Sep 8th, 2019
312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.17 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.  
  7. class Cache:
  8.     def __init__(self, *args, **kwargs):
  9.         self.nodes = args[0] if args else kwargs
  10.         self.indent = '.'
  11.  
  12.     def __eq__(self, other):
  13.         if self.nodes == other.nodes:
  14.             return True
  15.         return False
  16.  
  17.     def __str__(self):
  18.         return str(self.nodes.items())
  19.  
  20.     def __repr__(self):
  21.         data = "**{'key': 'value'}"
  22.         return f"{self.__class__.__name__}({data})"
  23.  
  24.     def get(self, uri=None):
  25.         if not uri:
  26.             return self.nodes
  27.  
  28.         def walk(_uri, nodes):
  29.             parts = _uri.split('/', 1)
  30.             key = parts.pop(0)
  31.  
  32.             if key in nodes:
  33.                 node = nodes[key]
  34.  
  35.                 if not parts:
  36.                     return node
  37.                 else:
  38.                     return walk(parts[0], node)
  39.  
  40.         return walk(uri, self.nodes)
  41.  
  42.     def set(self, uri, *args, **kwargs):
  43.  
  44.         def walk(_uri, nodes):
  45.             parts = _uri.split('/', 1)
  46.             key = parts.pop(0)
  47.  
  48.             if key in nodes and parts:
  49.                 return walk(parts[0], nodes[key])
  50.             elif len(_uri.split('/')) == 1:
  51.                 nodes[key] = args[0] if args else kwargs
  52.  
  53.         return walk(uri, self.nodes)
  54.  
  55.     def dump(self, indent=None):
  56.         """ Dumps the contents of the cache to the screen.
  57.        The output from dump goes stdout and is used to view the cache contents.
  58.        Default indentation is a dot for each level.
  59.        :param indent:
  60.            indent (str): String to be use for indenting levels.
  61.        :return:
  62.            Nothing.
  63.        """
  64.         indent = indent if indent else '.'
  65.  
  66.         print('-------------------------------------------------------------------------------------------------------')
  67.         print('id =', id(self), '\nnodes =', self)
  68.         if self.nodes:
  69.             def walk(_cfg, count):
  70.                 count += 1
  71.                 for key, value in _cfg.items():
  72.                     if isinstance(value, dict):
  73.                         print(indent * count, key)
  74.                         walk(value, count)
  75.                     else:
  76.                         if isinstance(value, str):
  77.                             value = f'"{value}"'
  78.                         print(indent * count, key, f'value={value}')
  79.             walk(self.nodes, 0)
  80.         else:
  81.             print(' (No Data)')
  82.  
  83.         print('-------------------------------------------------------------------------------------------------------')
  84.  
  85.     def save(self, file=None):
  86.         if file:
  87.             dirname = path.dirname(file)
  88.  
  89.             if dirname and not path.exists(dirname):
  90.                 makedirs(dirname)
  91.  
  92.             with open(file, 'w') as f:
  93.                 dump(self.nodes, f, indent=3)
  94.  
  95.     def load(self, file=None):
  96.         file_type = path.splitext(file)[1].lstrip('.').lower()
  97.  
  98.         if file_type == 'py' and path.exists(file):
  99.             spec = spec_from_file_location("module.name", file)
  100.             module = module_from_spec(spec)
  101.             spec.loader.exec_module(module)
  102.             self.nodes = module.config
  103.  
  104.         if file_type == 'json' and path.exists(file):
  105.             with open(file) as f:
  106.                 self.nodes = load(f)
  107.  
  108.     def copy(self):
  109.         return Cache(**deepcopy(self.nodes))
  110.  
  111.     def remove(self, uri):
  112.         """ Remove entree from cache.
  113.        Removes an entree from the cache if it exists.
  114.        :param uri:
  115.            uri (str): URI that points to the entree to remove.
  116.        :return:
  117.            Nothing.
  118.        """
  119.  
  120.         uri = uri.lstrip('/')
  121.         if self.exists(uri):
  122.             node = self.get('/'.join(uri.split('/')[:-1]))
  123.             del node[uri.split('/')[-1]]
  124.  
  125.     def exists(self, uri):
  126.         """ Test if URI exists in the cache.
  127.  
  128.        :param uri:
  129.        :return:
  130.        """
  131.         return True if self.get(uri) else False
  132.  
  133.     def destroy(self):
  134.         """ Destroy cache.
  135.        Deletes all entries in the cache.
  136.        :return:
  137.            Nothing.
  138.        """
  139.         del self.nodes
  140.         self.nodes = {}
  141.  
  142.     def has_nodes(self):
  143.         if len(self.nodes):
  144.             return True
  145.         return False
  146.  
  147.  
  148. cache = Cache()
  149. cache.load('data.py')
  150. cache.dump()
  151.  
  152. print('\nlevel_1/level_2/item2 = ', cache.get('level_1/level_2/item2'))
  153. cache.set('level_1/level_2/item2', 200)
  154. print('level_1/level_2/item2 = ', cache.get('level_1/level_2/item2'))
  155.  
  156. level_4 = {
  157.     'level_4': {
  158.         'item3': 10,
  159.         'item4': 20,
  160.     }
  161. }
  162. cache.set('level_1/level_2/level_3', level_4)
  163. cache.get('level_1/level_2/level_3').update({'level_5': {'name': 'Dan'}})
  164.  
  165. if cache.exists('level_1/level_2/level_3'):
  166.     print('level_1/level_2/level_3 =', cache.get('level_1/level_2/level_3'), '\n')
  167.  
  168. cache.save('data.json')
  169. cache.dump()
  170.  
  171. my_cache = cache.copy()
  172. my_cache.dump()
  173.  
  174. cache.destroy()
  175. cache.set('p1', {'first_name': 'Dan', 'last_name': 'Huckson'})
  176. cache.set('p2', {'first_name': 'Geoff', 'last_name': 'Skerlan'})
  177. cache.dump()
  178.  
  179. my_cache.remove('level_1/level_2/item1')
  180. my_cache.remove('level_1/level_2/level_3')
  181. my_cache.dump()
  182.  
  183. your_cache = Cache()
  184. your_cache.load('data.json')
  185. your_cache.dump()
  186.  
  187. # Test equality code below.
  188. my_cache2 = my_cache.copy()
  189.  
  190. # uncomment the line below to test inequality.
  191. # my_cache.set('level_1/level_2/item2', 201)
  192. if my_cache == my_cache2:
  193.     print('\nThe contents of both caches are the same!')
  194.  
  195.     if my_cache is my_cache2:
  196.         print('my_cache2 is the same instance as my_cache.')
  197.     else:
  198.         print('my_cache2 is not the same instance as my_cache, but the contents are the same.')
  199.  
  200. else:
  201.     print('\nThe contents of both caches are not exactly same!')
  202.  
  203. my_cache.dump()
  204. my_cache2.dump()
  205.  
  206. print()
  207. my_cache3 = my_cache2
  208. if my_cache3 is my_cache2:
  209.     print('my_cache3 is the same instance as my_cache2, notice ids.')
  210.     my_cache3.dump()
  211.  
  212. print()
  213. print('your_cache =', str(your_cache))
  214. print('your_cache =', repr(your_cache))
  215. print()
  216.  
  217. x = Cache(abc={'item': 123}, xyx={'item': 456})
  218. x.dump()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement