add a 'clear cache' button in the settings
[mevemon] / package / src / apicache.py
1 import time
2 import cPickle
3 import zlib
4 import os
5 from os.path import join, exists
6
7 from constants import APICACHE_PATH
8
9 class cache_handler( object ):
10     # adapted from http://home.wanadoo.nl/ntt/eve/library/files/api/apitest.py (does this satisfy the terms of the license?), will need work, but we need basic cache functionality... I feel guilty for abusing the server. FIXME --danny
11     
12     def __init__( self, debug = False ):
13         self.debug = debug
14         self.count = 0
15         self.cache = {}
16         self.tempdir = APICACHE_PATH
17         if not exists(self.tempdir):
18             os.makedirs(self.tempdir)
19             
20     # remove this later --danny
21     def log( self, what ):
22         if self.debug:
23             print "[%d] %s" % (self.count, what)
24
25     def retrieve(self, host, path, params):
26         # eveapi asks if we have this request cached
27         key = hash((host, path, frozenset( params.items())))
28
29         # for logging
30         self.count += 1
31         
32         # see if we have the requested page cached...
33         cached = self.cache.get(key, None)
34         if cached:
35             cacheFile = None
36         else:
37             # not in memory, maybe on disk --danny
38             cacheFile = join(self.tempdir, str(key) + ".cache")
39             if exists(cacheFile):
40                 self.log("%s: retreiving from disk." % path)
41                 f = open(cacheFile, "rb")
42                 cached = self.cache[key] = cPickle.loads(zlib.decompress(f.read()))
43                 f.close()
44
45         if cached:
46             # check if the cached object is fresh enough
47             if time.time() < cached[0]:
48                 self.log("%s: returning cached document." % path)
49                 # return the cached object
50                 return cached[1]
51
52                 # if it's stale, purge it --danny
53                 self.log("%s: cache expired, purging!" % path)
54                 del self.cache[key]
55                 if cacheFile:
56                     os.remove(cacheFile)
57
58             self.log("%s: not cached, fetching from server..." % path)
59             # We didn't get a cache hit so return None to indicate that the data should be requested from server
60             return None
61     
62     def store(self, host, path, params, doc, obj):
63         # eveapi is asking us to cache an item
64         if not exists(self.tempdir):
65             os.makedirs(self.tempdir)
66         
67         key = hash((host, path, frozenset( params.items())))
68         
69         cachedFor = obj.cachedUntil - obj.currentTime
70         if cachedFor:
71             self.log("%s: cached (%d seconds)." % (path, cachedFor))
72             
73             cachedUntil = time.time() + cachedFor
74
75             # store in memory
76             cached = self.cache[key] = (cachedUntil, obj)
77             
78             # store in cache folder
79             cacheFile = join(self.tempdir, str(key) + ".cache")
80             f = open(cacheFile, "wb")
81             f.write(zlib.compress(cPickle.dumps(cached, -1)))
82             f.close
83
84