Commits

Andrew Godwin committed e225f72

Caching framework correctly weaved into PROPFIND, now needs a non-noop cache and tests.

Comments (0)

Files changed (6)

heechee/repo/git.py

 """
 
 import os
+import time
+
 from ConfigParser import RawConfigParser
 from heechee.repo import File, Directory, RepositoryBase
 from heechee.exceptions import *
     def commit(self, branch_name, parent, message, author, changes, deletions):
         raise NotImplementedError
     
+    def mtime(self):
+        return time.time()
     
     ########### Private functions (git -> svn mapping) ###########
     

heechee/repo/hg.py

 import datetime
 import time
 import tempfile
+import os
 
 try:
     from cStringIO import StringIO
         # Commit!
         self.hg_repo.commitctx(ctx)
     
+    def mtime(self):
+        """
+        Returns effective mtime of the repo. This is just the max() of all
+        changeable files in .hg.
+        """
+        important_files = ["store/00changelog.i", "store/00manifest.i"]
+        return max([
+            os.stat(os.path.join(self.hg_repo.path, file_path)).st_mtime
+            for file_path in important_files
+        ])
     
     ########### Private functions (hg -> svn mapping) ###########
     

heechee/webdav/__init__.py

 
 import logging
 
+try:
+    from hashlib import md5
+except ImportError:
+    from md5 import md5
+
 from lxml.etree import fromstring, tostring, Element, SubElement
 
 from werkzeug import Request, Response, cached_property
     """
     Overridden request object which has an xml_body function.
     """
+    
+    @cached_property
+    def raw_body(self):
+        return self.input_stream.read(self.content_length)
 
     @cached_property
     def xml_body(self):
         # would be nicer to have fromstring(self.data) but that requires
         # an unreleased version of Werkzeug.
-        return fromstring(self.input_stream.read(self.content_length))
+        return fromstring(self.raw_body)
 
 
 class RepositoryServer(PropsMixin, ReportMixin, CommitMixin, ReaderMixin):
         except HTTPException, e:
             return e
     
+    def _cache_key(self, request):
+        """
+        Uses the request and the repo to make a cache key.
+        """
+        return "%s:%s:%s" % (request.method, str(self.repo.mtime()), md5(request.path + ":" + request.raw_body).hexdigest())
+    
     def access_check(self, request, accesss_type):
         # Get their status
         if request.authorization is None:

heechee/webdav/caching/noop.py

     """
     
     def __getitem__(self, key):
-        return KeyError("Key %r not found (noop)" % key)
+        raise KeyError("Key %r not found (noop)" % key)
     
     def __setitem__(self, key, value):
         return

heechee/webdav/props.py

         Responds to SVN's PROPFIND requests, which usually detail finding out
         various things about the repo.
         """
+        # Try getting a cached copy
+        cache_key = self._cache_key(request)
+        try:
+            return self.cache[cache_key]
+        except KeyError:
+            pass
+        
         # Find out what properties they want
         tree = request.xml_body
         
         else:
             raise BadRequest()
         
+        # Cache the response
+        self.cache[cache_key] = response
+        
         return Response(response, status = 207)
 
     

heechee/webdav/report.py

             
             # Send back the messages
             log_rep = Element(SVN_NS+"log-report")
-            for info in reversed(self.repo.logs_for_revisions(start_rev, end_rev, path)):
+            for info in reversed(list(self.repo.logs_for_revisions(start_rev, end_rev, path))):
                 item = SubElement(log_rep, SVN_NS+"log-item")
                 rev = SubElement(item, DAV_NS+"version-name")
                 rev.text = str(info['rev'])