"""
Core facilites for Bucket
"""
import os
import shelve
import pickle
import time
#import sha
import hashlib
class Drop(object):
"""A Drop in the Bucket"""
name = None
filename = None
change_time = None
def __init__(self, name, change_time):
self.name = name
self.filename = sha1.new(name).hexdigest()
if change_time.__class__ is tuple:
change_time = time.mktime(change_time)
self.change_time = change_time
class Bucket(object):
"""Main cache manager class"""
_cachedir = None
_cachemap = None
verbose = False
@classmethod
def setup(self, cachedir=""):
"""Setup Bucket class
Initialize class variables
"""
self._cachedir = str(cachedir).strip()
self._cachemap = shelve.open(os.path.join(self._cachedir, "_cache.db"), "c", None, True)
@classmethod
def kill(self):
"""Close the cachemap and update it on disk"""
self._cachemap.close()
@classmethod
def _get_data(self, name):
"""Get raw data from cache"""
ret = ""
try:
path = os.path.join(self._cachedir, self.get_drop(name).filename)
f = file(path, "rb")
ret = pickle.load(f)
f.close()
except:
pass
return ret
@classmethod
def _put_data(self, name, in_data):
"""Put raw data into cache"""
path = os.path.join(self._cachedir, self.get_drop(name).filename)
ret = ""
try:
f = file(path, "wb")
ret = pickle.dump(in_data, f)
f.close()
except:
pass
return ret
@classmethod
def check(self, name, in_data):
"""Determines cache-object vitality
Also compares cached and input data to verify this
"""
fresh = False
d = self._cachemap
if name in d.keys():
data = self._get_data(name)
if data == in_data:
fresh = True
return fresh
@classmethod
def check_time(self, name, in_timestruct):
"""Determines cache-object vitality
Also compares modification times (based on in_timestruct)
"""
fresh = False
d = self._cachemap
if name in d.keys():
ts = d[name].change_time
if ts == time.mktime(in_timestruct):
fresh = True
return fresh
@classmethod
def put(self, name, in_data):
"""Put an object into bucket when check function indicates"""
insert = self.check(name, in_data)
if not insert:
item = Drop(name, time.gmtime())
d = self._cachemap
d[name] = item
d.sync()
self._put_data(name, in_data)
self._cachemap = d
stdprint("[put] data (re)written!")
else:
stdprint("[put] no update.")
return insert
@classmethod
def put_time(self, name, in_timestruct):
"""Put an object into bucket when check_time function indicates"""
insert = self.check_time(name, in_timestruct)
if not insert:
item = Drop(name, time.gmtime())
d = self._cachemap
d[name] = item
d.sync()
self._put_data(name, in_data)
self._cachemap = d
stdprint("[put] data (re)written!")
else:
stdprint("[put] no update.")
return insert
@classmethod
def get(self, name):
"""Get an object from bucket"""
d = self._cachemap
ret = None
if name in d.keys():
ret = self._get_data(name)
return ret
@classmethod
def get_drop(self, name):
"""Get a drop from the bucket
Drops contain cache-object metadata like mod. time
"""
d = self._cachemap
ret = None
if name in d.keys():
ret = d[name]
return ret
@classmethod
def get_drops(self):
"""Get all the drops"""
d = self._cachemap
return d
def stdprint(s):
if Bucket.verbose:
print s