changeset 3865:4ffd618f2826

caching: support file-like content for update(), new size() function. cache action: use file-like api of caching
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Wed, 16 Jul 2008 22:09:12 +0200
parents 6dbeb3669091
children 44275a3436eb
files MoinMoin/action/cache.py MoinMoin/caching.py
diffstat 2 files changed, 31 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/cache.py	Wed Jul 16 19:26:04 2008 +0200
+++ b/MoinMoin/action/cache.py	Wed Jul 16 22:09:12 2008 +0200
@@ -120,18 +120,9 @@
         content_type = 'application/octet-stream'
 
     data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
-    data_cache_fname = data_cache._filename()
-
-    if hasattr(data, 'read'):
-        import shutil
-        data_cache_file = open(data_cache_fname, 'wb')
-        shutil.copyfileobj(data, data_cache_file)
-        data_cache_file.close()
-    else:
-        data_cache.update(data)
-
-    content_length = content_length or os.path.getsize(data_cache_fname)
-    last_modified = last_modified or os.path.getmtime(data_cache_fname)
+    data_cache.update(data)
+    content_length = content_length or data_cache.size()
+    last_modified = last_modified or data_cache.mtime()
 
     last_modified = timefuncs.formathttpdate(int(last_modified))
     headers = ['Content-Type: %s' % content_type,
@@ -196,8 +187,8 @@
 def _get_datafile(request, key):
     """ get an open data file for the data cached for key """
     data_cache = caching.CacheEntry(request, cache_arena, key+'.data', cache_scope, do_locking=do_locking)
-    data_file = open(data_cache._filename(), 'rb')
-    return data_file
+    data_cache.open(mode='r')
+    return data_cache
 
 
 def _do_get(request, key):
--- a/MoinMoin/caching.py	Wed Jul 16 19:26:04 2008 +0200
+++ b/MoinMoin/caching.py	Wed Jul 16 22:09:12 2008 +0200
@@ -9,6 +9,7 @@
 """
 
 import os
+import shutil
 import tempfile
 
 from MoinMoin import log
@@ -100,6 +101,12 @@
         except (IOError, OSError):
             return 0
 
+    def size(self):
+        try:
+            return os.path.getsize(self._fname)
+        except (IOError, OSError):
+            return 0
+
     def uid(self):
         """ Return a value that likely changes when the on-disk cache was updated.
 
@@ -217,16 +224,26 @@
 
     def update(self, content):
         try:
-            if self.use_pickle:
-                content = pickle.dumps(content, PICKLE_PROTOCOL)
-            elif self.use_encode:
-                content = content.encode(config.charset)
+            if hasattr(content, 'read'):
+                # content is file-like
+                assert not (self.use_pickle or self.use_encode), 'caching: use_pickle and use_encode not supported with file-like api'
+                try:
+                    self.open(mode='w')
+                    shutil.copyfileobj(content, self)
+                finally:
+                    self.close()
+            else:
+                # content is a string
+                if self.use_pickle:
+                    content = pickle.dumps(content, PICKLE_PROTOCOL)
+                elif self.use_encode:
+                    content = content.encode(config.charset)
 
-            try:
-                self.open(mode='w')
-                self.write(content)
-            finally:
-                self.close()
+                try:
+                    self.open(mode='w')
+                    self.write(content)
+                finally:
+                    self.close()
         except (pickle.PicklingError, OSError, IOError, ValueError), err:
             raise CacheError(str(err))