mirror of
https://github.com/nikdoof/evestandings.git
synced 2025-12-15 20:42:19 +00:00
121 lines
4.0 KiB
Python
121 lines
4.0 KiB
Python
from hashlib import sha1
|
|
import logging
|
|
import sqlite3
|
|
import redis
|
|
import zlib
|
|
|
|
SQLITE_PATH = '/tmp/eveapicache.sqlite3'
|
|
|
|
class DbCacheHandler:
|
|
"""
|
|
Database backed cache handler for Entity's eveapi module
|
|
"""
|
|
|
|
def __init__(self, conn=SQLITE_PATH):
|
|
self._conn_url = conn
|
|
|
|
@property
|
|
def log(self):
|
|
if not hasattr(self, '_log'):
|
|
self._log = logging.getLogger(self.__class__.__name__)
|
|
return self._log
|
|
|
|
@property
|
|
def conn(self):
|
|
if not hasattr(self, '_conn') or not self._conn:
|
|
self._conn = sqlite3.connect(self._conn_url)
|
|
self.setup()
|
|
return self._conn
|
|
|
|
@property
|
|
def cursor(self):
|
|
if not hasattr(self, '_cursor') or not self._cursor:
|
|
self._cursor = self.conn.cursor()
|
|
return self._cursor
|
|
|
|
def setup(self):
|
|
if not hasattr(self, '_setupchecked'):
|
|
self.cursor.execute('CREATE TABLE IF NOT EXISTS api_cache(docid TEXT PRIMARY KEY, xml TEXT, cacheduntil TEXT)')
|
|
self._setupchecked = True
|
|
|
|
def disconnect(self):
|
|
if hasattr(self, '_cursor'):
|
|
self._cursor.close()
|
|
self._cursor = None
|
|
if hasattr(self, '_conn'):
|
|
self._conn.close()
|
|
self._conn = None
|
|
|
|
@staticmethod
|
|
def _gen_docid(host, path, params):
|
|
return sha1("%s%s?%s" % (host, path, params)).hexdigest()
|
|
|
|
def retrieve(self, host, path, params):
|
|
docid = self._gen_docid(host, path, params)
|
|
self.log.debug("Retrieving document: %s" % docid)
|
|
try:
|
|
self.cursor.execute("SELECT xml FROM api_cache WHERE docid = ? and datetime(cacheduntil, 'unixepoch') >= current_timestamp", (docid,))
|
|
res = self.cursor.fetchone()
|
|
self.disconnect()
|
|
except sqlite3.Error as e:
|
|
self.log.error("Error retrieving document: %s", e.args[0])
|
|
else:
|
|
if res:
|
|
self.log.debug("Found %s documents for ID %s" % (len(res), docid))
|
|
return res[0]
|
|
return None
|
|
|
|
def store(self, host, path, params, doc, obj):
|
|
docid = self._gen_docid(host, path, params)
|
|
self.log.debug("Storing document: %s (%s)" % (docid, path))
|
|
try:
|
|
self.cursor.execute('REPLACE INTO api_cache (docid, xml, cacheduntil) VALUES (?, ?, ?)', (docid, doc, obj.cachedUntil))
|
|
self.conn.commit()
|
|
self.disconnect()
|
|
except sqlite3.Error as e:
|
|
self.log.error("Error storing document: %s", e.args[0])
|
|
|
|
def purge_stale(self):
|
|
self.log.info("Purging stale cached documents")
|
|
try:
|
|
self.cursor.execute("DELETE FROM api_cache WHERE datetime(cacheduntil, 'unixepoch') >= current_timestamp")
|
|
self.conn.commit()
|
|
self.disconnect()
|
|
except sqlite3.Error as e:
|
|
self.log.error("Error purging document cache: %s", e.args[0])
|
|
|
|
|
|
class EVEAPIRedisCache(object):
|
|
|
|
def __init__(self, redis):
|
|
self.redis = redis
|
|
|
|
@staticmethod
|
|
def gen_key(host, path, params):
|
|
params = ''.join(['{}={}'.format(x, y) for x, y in params.items()])
|
|
key_hash = ''.join((host, path, params))
|
|
return 'eveapi_cache_{}'.format(sha1(key_hash).hexdigest())
|
|
|
|
def retrieve(self, host, path, params):
|
|
key = self.gen_key(host, path, params)
|
|
try:
|
|
val = self.redis.get(key)
|
|
except redis.RedisError:
|
|
logging.exception('Error retrieving an EVE API call to Redis')
|
|
val = None
|
|
pass
|
|
if val:
|
|
return zlib.decompress(val)
|
|
|
|
def store(self, host, path, params, doc, obj):
|
|
key = self.gen_key(host, path, params)
|
|
cache_time = obj.cachedUntil - obj.currentTime
|
|
if cache_time > 0:
|
|
val = zlib.compress(doc, 9)
|
|
try:
|
|
self.redis.set(key, val)
|
|
self.redis.expire(key, cache_time)
|
|
except redis.RedisError:
|
|
logging.exception('Error storing an EVE API call to Redis')
|
|
pass
|