]> kaliko git repositories - mpd-sima.git/blob - sima/lib/httpcli/cache.py
22c751d90baae593c81516373154634a2985ae7f
[mpd-sima.git] / sima / lib / httpcli / cache.py
1 """
2 The cache object API for implementing caches. The default is just a
3 dictionary, which in turns means it is not threadsafe for writing.
4 """
5
6 import os
7 import base64
8 import codecs
9
10 from hashlib import md5
11 from pickle import load, dump
12 from threading import Lock
13
14 from .filelock import FileLock
15
16
17 class BaseCache:
18
19     def get(self, key):
20         raise NotImplemented()
21
22     def set(self, key, value):
23         raise NotImplemented()
24
25     def delete(self, key):
26         raise NotImplemented()
27
28
29 class DictCache(BaseCache):
30
31     def __init__(self, init_dict=None):
32         self.lock = Lock()
33         self.data = init_dict or {}
34
35     def get(self, key):
36         return self.data.get(key, None)
37
38     def set(self, key, value):
39         with self.lock:
40             self.data.update({key: value})
41
42     def delete(self, key):
43         with self.lock:
44             if key in self.data:
45                 self.data.pop(key)
46
47
48 class FileCache:
49
50     def __init__(self, directory, forever=False):
51         self.directory = directory
52         self.forever = forever
53
54         if not os.path.isdir(self.directory):
55             os.mkdir(self.directory)
56
57     def encode(self, x):
58         return md5(x.encode('utf-8')).hexdigest()
59
60     def _fn(self, name):
61         return os.path.join(self.directory, self.encode(name))
62
63     def get(self, key):
64         name = self._fn(key)
65         if os.path.exists(name):
66             return load(codecs.open(name, 'rb'))
67
68     def set(self, key, value):
69         name = self._fn(key)
70         with FileLock(name):
71             with codecs.open(name, 'w+b') as fh:
72                 dump(value, fh)
73
74     def delete(self, key):
75         if not self.forever:
76             os.remove(self._fn(key))