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