Commit bd10e62e authored by Taddeus Kroes's avatar Taddeus Kroes

Finished first complete version of Cache object, tested only in live environment.

parent d991026e
import web
import cPickle as pickle
from time import gmtime
from datetime import datetime, timedelta
from os import mkdir
from os.path import getmtime, exists
from cPickle import load, dump
from hashlib import md5
from copy import copy
ADMINISTRATION_FILE = 'administration.py'
......@@ -29,7 +31,7 @@ def assert_file_exists(path):
def seconds_to_datetime(seconds):
return datetime(gmtime(seconds)[:7])
return datetime(*gmtime(seconds)[:7])
class Cache:
......@@ -59,6 +61,10 @@ class Cache:
def assert_files_exist(self):
map(assert_file_exists, self.files)
def __str__(self):
return '<Cache filename=%s files=[%s]>' \
% (self.filename(), ','.join(self.files))
def add(self, path, absolute=False):
"""
Add a file to the cache object. Requires the full path to the file,
......@@ -101,18 +107,35 @@ class Cache:
if not exists(self.cached):
mkdir(self.cached)
def save_administration(self):
def save_administration(self, old_admin={}):
"""
Generate a Python file containing the modification dates of the cached
file list.
file list. The old_admin paramter can contain additional files which
are not in this cache object, but do need to be kept in the
administration for other cache objects.
"""
self.assert_modification_dates_exist()
self.assert_cached_folder_exist()
admin = copy(old_admin)
admin.update(self.modified)
f = open(self.cached + ADMINISTRATION_FILE, 'w')
dump(self.modified, f)
pickle.dump(self.modified, f)
f.close()
def load_administration(self):
path = self.cached + ADMINISTRATION_FILE
if not exists(path):
return {}
f = open(path, 'r')
modified = pickle.load(f)
f.close()
return modified
def last_modified(self):
self.assert_modification_dates_exist()
......@@ -123,10 +146,16 @@ class Cache:
Generate an Etag for the cache object, using the names of the files
included and the latest modification date.
"""
return self.filename() + str(self.last_modified())
h = md5()
h.update(','.join(self.files) + str(self.last_modified()))
return h.hexdigest()
def filename(self):
return ','.join(self.files)
h = md5()
h.update(','.join(self.files))
return self.cached + h.hexdigest()
def concatenate(self):
contents = ''
......@@ -143,27 +172,45 @@ class Cache:
# Update cached file
last_modified = self.last_modified()
path = self.filename()
server_modified = not exists(path) or getmtime(path) < last_modified
admin = self.load_administration()
if not exists(path):
web.debug('Cached file "%s" does not exist yet, generating it...')
server_modified = True
else:
server_modified = False
for f_path, f_modified in self.modified.iteritems():
if f_path not in admin:
web.debug('File "%s" has been added.' % f_path)
server_modified = True
elif f_modified > admin[f_path]:
web.debug('File "%s" has been updated.' % f_path)
server_modified = True
if server_modified:
content = self.concatenate()
self.save_administration(admin)
content = self.concatenate()
f = open(path, 'w')
f.write(content)
f.close()
#try:
web.http.modified(seconds_to_datetime(last_modified), self.etag())
web.http.expires(timedelta(**self.expires))
web.header('Cache-Control', 'private')
if not server_modified:
# Concatenated content has not been loaded yet, read the cached
# file
f = open(path, 'r')
content = f.read()
f.close()
return content
#except web.NotModified as e:
# web.header('Status', e.message)
try:
web.http.modified(seconds_to_datetime(last_modified), self.etag())
web.http.expires(timedelta(**self.expires))
web.header('Cache-Control', 'private')
if not server_modified:
# Concatenated content has not been loaded yet, read the cached
# file
web.debug('Cached file "%s" already exists, sending content...')
f = open(path, 'r')
content = f.read()
f.close()
return content
except web.NotModified as e:
web.debug('Cached file "%s" not modified, setting 304 header...' \
% path)
raise e
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment