All pastes #1691978 Raw Edit

xrogaan

public text v1 · immutable
#1691978 ·published 2009-11-29 04:02 UTC
rendered paste body
"""
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