Added basic caching functionality, stole it from apitest.py (definitely still needs...
authorDanny Campbell <danny.campbell@gmail.com>
Sat, 17 Apr 2010 07:12:58 +0000 (01:12 -0600)
committerDanny Campbell <danny.campbell@gmail.com>
Sat, 17 Apr 2010 07:12:58 +0000 (01:12 -0600)
apicache.py [new file with mode: 0644]
mevemon.py

diff --git a/apicache.py b/apicache.py
new file mode 100644 (file)
index 0000000..a8f4e18
--- /dev/null
@@ -0,0 +1,80 @@
+import time
+import tempfile
+import cPickle
+import zlib
+import os
+from os.path import join, exists
+
+class cache_handler( object ):
+    # 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
+    
+    def __init__( self, debug = False ):
+        self.debug = debug
+        self.count = 0
+        self.cache = {}
+        self.tempdir = join( tempfile.gettempdir(), "eveapi" )
+        if not exists( self.tempdir ):
+            os.makedirs( self.tempdir )
+            
+    # remove this later --danny
+    def log( self, what ):
+        if self.debug:
+            print "[%d] %s" % ( self.count, what )
+
+    def retrieve( self, host, path, params ):
+        # eveapi asks if we have this request cached
+        key = hash( ( host, path, frozenset( params.items() ) ) )
+
+        # for logging
+        self.count += 1
+        
+        # see if we have the requested page cached...
+        cached = self.cache.get( key, None )
+        if cached:
+            cacheFile = None
+        else:
+            # not in memory, maybe on disk --danny
+            cacheFile = join( self.tempdir, str( key ) + ".cache" )
+            if exists( cacheFile ):
+                self.log( "%s: retreiving from disk." % path )
+                f = open( cacheFile, "rb" )
+                cached = self.cache[key] = cPickle.loads( zlib.decompress( f.read() ) )
+                f.close()
+
+        if cached:
+            # check if the cached doc is fresh enough
+            if time.time() < cached[0]:
+                self.log( "%s: returning cached document." % path )
+                # return the cached XML doc
+                return cached[1]
+
+                # if it's stale, purge it --danny
+                self.log( "%s: cache expired, purging!" % path )
+                del self.cache[key]
+                if cacheFile:
+                    os.remove( cacheFile )
+
+            self.log( "%s: not cached, fetching from server..." % path )
+            # We didn't get a cache hit so return None to indicate that the data should be requested from server
+            return None
+    
+    def store( self, host, path, params, doc, obj ):
+        # eveapi is asking us to cache an item
+        key = hash( ( host, path, frozenset( params.items() ) ) )
+        
+        cachedFor = obj.cachedUntil - obj.currentTime
+        if cachedFor:
+            self.log( "%s: cached (%d seconds)." % ( path, cachedFor ) )
+            
+            cachedUntil = time.time() + cachedFor
+
+            # store in memory
+            cached = self.cache[key] = ( cachedUntil, doc )
+            
+            # store in cache folder
+            cacheFile = join( self.tempdir, str( key ) + ".cache" )
+            f = open( cacheFile, "wb" )
+            f.write( zlib.compress( cPickle.dumps( cached, -1 ) ) )
+            f.close
+
+
index a84715d..0650ca2 100644 (file)
@@ -2,6 +2,7 @@ import hildon
 import gtk
 from eveapi import eveapi
 import fetchimg
+import apicache
 
 # we will store our preferences in gconf
 import gnome.gconf
@@ -44,12 +45,12 @@ class mEveMon():
         ui_char_list = []
         # error message --danny
         placeholder_chars = [("Please check your API settings.", "imgs/error.jpg")]
-        api = eveapi.EVEAPIConnection()
+        cached_api = eveapi.EVEAPIConnection( cacheHandler = apicache.cache_handler( debug = False ) )
         uid = self.get_uid()
         api_key = self.get_api_key()
         # if they are entered into gconf, try getting api data --danny
         if ( uid and api_key ):
-            auth = api.auth( userID = uid, apiKey = api_key )
+            auth = cached_api.auth( userID = uid, apiKey = api_key )
             try:
                 api_char_list = auth.account.Characters()
             except eveapi.Error, e:
@@ -57,7 +58,8 @@ class mEveMon():
                 return placeholder_chars
             except Exception, e:
                 # unknown exception, dunno if this needs to be here if I just ignore it... probably a bad idea, but it was in the apitest.py example... --danny
-                return placeholder_chars
+                ##return placeholder_chars
+                raise
             # append each char we get to the list we'll return to the UI --danny
             for character in api_char_list.characters:
                 ui_char_list.append( ( character.name, fetchimg.portrait_filename( character.characterID, 64 ) ) )
@@ -65,7 +67,7 @@ class mEveMon():
         # if not entered into gconf, error message --danny
         else:
             return placeholder_chars
-        
+
 if __name__ == "__main__":
     app = mEveMon()
     app.run()