import md5 import os import sys import time debug = 1 app = ".metadata" cache_directory = ["/tmp/ajax-proxy-cache",] default_request_keys = ["url",] def makeDefaultCache(): dir = cache_directory[0] if not os.path.exists(dir): try: os.makedirs(dir) except IOError: raise IOError, "Permissions denied to write to the cache, the cache will not function until it is allowed to write to %s" % dir def requestToMD5(request, config): """ For a given request, calculate the MD5 """ request_keys = config.get("cache-headers", default_request_keys) hash = md5.new() for key in request_keys: value = getattr(request, key, None) if value is None: continue hash.update(value) return hash.hexdigest() def getPath(filename): """ For a filenmae, break it down into directories """ path = [] start = 0 for num in range(2, 6, 2): path.append(filename[start:num]) start = num path.insert(0, cache_directory[0]) path = os.path.join(*path) return path, filename[start:] def deleteCached(file): """ Delete the cached file """ os.remove(file) os.remove(file + app) def getCached(request, config): """ Figure out if the cached file exists, if it does check that is up to date, otherwise delete the file """ # figure out where the cache data would go temp = requestToMD5(request, config) directory, filename = getPath(temp) if os.path.exists(directory): file = os.path.join(directory, filename) mdfile = file + app if os.path.exists(file) and os.path.exists(mdfile): # check expiry mdfile = open(file + app, "rb").read() mddata = eval(mdfile) # if this is out of data, nuke the cache now = time.time() if now > mddata["expiry"]: deleteCached(file) return file = open(file, "rb").read() return file, mddata def setCached(request, config, data): """ Set the cached data into the cache """ # figure out the path temp = requestToMD5(request, config) directory, filename = getPath(temp) if not os.path.exists(directory): os.makedirs(directory) file = os.path.join(directory, filename) open(file, "wb").write(data) mdfile = file + app # write out all the remaining headers metadata = {} length = int(config.get('cache-length', 3600)) metadata["expiry"] = time.time() + length open(mdfile, "wb").write(str(metadata)) def clean(): """ Clean out the cache """ walked = os.walk(cache_directory) cleaned = 0 kept = 0 for root, dir, files in walked: for file in files: if file.endswith(app): file = os.path.join(root, file) mdfile = open(file, "rb").read() mddata = eval(mdfile) if mddata["expiry"] < time.time(): cleaned += 1 deleteCached(file[:-len(app)]) else: kept += 1 print "Kept:", kept print "Cleaned:", cleaned def delete(): """ Delete all the cache entries """ dirs = os.path.listdir(cache_directory) for dir in dirs: os.rmdirs(os.path.join(cache_directory, dir)) if __name__=='__main__': if len(sys.argv) < 2: print """Usage: cache.py clean|delete clean: This will clean the cache of all objects that are out of date. Run this is as a cron job every few hours to clean out the junk. delete: Will remove all cache entries """ elif sys.argv[1] == "clean": clean()