Commits

Andrew Godwin committed 414533f

Fully working when hanging off of a subdirectory, using hydra.

Comments (0)

Files changed (7)

heechee/tests/base.py

             os.mkdir(self.source_dir)
             self.init_repo()
             self.server = subprocess.Popen(
-                ["python", "-m", "heechee.webdav.hydra", "^/([^/]+)/", path_pattern],
+                ["python", "-m", "heechee.webdav.hydra", "^/([^/]+)", path_pattern],
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
             )

heechee/webdav/__init__.py

 from heechee.webdav.report import ReportMixin
 from heechee.webdav.commit import CommitMixin
 from heechee.webdav.read import ReaderMixin
+from heechee.webdav.storage import FileStorage
 
 
 class DAVRequest(Request):
     
     def __init__(self, repo):
         self.repo = repo
-        self.activities = {}
+        self.storage = FileStorage()
     
     def authorization_check(self, username, password, access_type):
         """

heechee/webdav/commit.py

     def MKACTIVITY(self, request):
         "Part of the commit workflow - the client makes the activity first."
         act_id = request.path.split("/")[3]
-        self.activities[act_id] = {}
+        self.storage.set(act_id, {})
         return Response("", status=201)
     
     def CHECKOUT(self, request):
         path_type = path_parts[1]
         # Is it the baseline (i.e. they're submitting the log message?)
         if path_type == "bln":
-            self.activities[activity_set]['!svnrev'] = {"base_version": int(path_parts[-1])}
+            activity_data = self.storage.get(activity_set)
+            activity_data['!svnrev'] = {"base_version": int(path_parts[-1])}
+            self.storage.set(activity_set, activity_data)
             filename = "!svnrev"
         # Otherwise, they're checking out a file. We currently ignore this.
         else:
             # Get the log message
             activity_set = path_parts[2]
             log_message = request.xml_body.find(DAV_NS+"set").find(DAV_NS+"prop").find(SVN_SVN_NS+"log").text
-            self.activities[activity_set]['!svnrev']['log_message'] = log_message
+            activity_data = self.storage.get(activity_set)
+            activity_data['!svnrev']['log_message'] = log_message
+            self.storage.set(activity_set, activity_data)
         
         return Response(self._propstat_response([(request.path, {"log": None})]), status=207)
     
         activity_set = path_parts[2]
         filename = "/".join(path_parts[3:])
         # Store the svndiff against the file
-        self.activities[activity_set][filename] = {'svndiff': request.data}
+        activity_data = self.storage.get(activity_set)
+        activity_data[filename] = {'svndiff': request.data}
+        self.storage.set(activity_set, activity_data)
         # Done.
         return Response("", status=204)
     
         activity_set = source_url.split("/")[-1]
         
         # Work out what revision that is being committed against
-        activity_info = self.activities[activity_set]
+        activity_info = self.storage.get(activity_set)
         base_version = activity_info['!svnrev']['base_version']
         log_message = activity_info['!svnrev']['log_message']
         
             filename = "/".join(path_parts[3:])
             # Mark the file as deleted. This will trigger recursive deletion
             # inside the repo backend if it's a directory.
-            self.activities[activity_set][filename] = {'svndiff': False}
+            activity_data = self.storage.get(activity_set)
+            activity_data[filename] = {'svndiff': False}
+            self.storage.set(activity_set, activity_data)
         else:
             # Deleting the activity set.
             activity_set = request.path.strip("/").split("/")[2]
-            del self.activities[activity_set]
+            self.storage.delete(activity_set)
         
         return Response("", status=204)
 
         activity_set = path_parts[2]
         filename = "/".join(path_parts[3:]) + "/.heechee-empty"
         # Make an empty file
-        self.activities[activity_set][filename] = {'svndiff': make_cheap_diff("")}
+        activity_data = self.storage.get(activity_set)
+        activity_data[filename] = {'svndiff': make_cheap_diff("")}
+        self.storage.set(activity_set, activity_data)
         # Done.
         return Response("", status=201)
     

heechee/webdav/hydra.py

         try:
             repo_path = self.path_pattern % match.groups()
         except AttributeError:
-            return NotFound("Path not valid.")
+            return NotFound("Path not valid.")(environ, start_response)
         # Make a repository app for that
         app = RepositoryServer(get_repository(repo_path))
         # Delegate

heechee/webdav/props.py

         """
         # Find out what properties they want
         tree = request.xml_body
-                        
+        
         try:
             props = [x.tag.split("}")[-1] for x in tree.find(DAV_NS+"prop").getchildren()]
         except AttributeError:
         # Basically, tell them the paths of the top revision.
         elif request.path == "/!svn/vcc/default":
             answers = self._props_for_file(request, "", props, top_revision)
-            href_path = None
-            if "baseline-collection" in props:
-                href_path = "/!svn/bln/%s/" % top_revision
             response = self._propstat_response([(request.path, answers)])
         
         # This is the "BLN", which I think means 'Baseline'.

heechee/webdav/report.py

             return Response(tostring(up_rep))
         
         elif tree.tag == SVN_NS + "log-report":
-            
             assert "!svn" in request.path, "Log report on non-special directory!"
             
             # Get the start/end revision, and path

heechee/webdav/storage.py

+
+import os
+
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+
+class FileStorage(object):
+    """
+    Stores activity sets on-disk in /tmp.
+    """
+    
+    storage_dir = "/tmp/"
+    
+    def get_path(self, key):
+        return os.path.join(self.storage_dir, key + ".heechee-commit")
+    
+    def get(self, key):
+        path = self.get_path(key)
+        if not os.path.exists(path):
+            raise KeyError("No such commit state %r" % key)
+        fh = open(path, "rb")
+        data = pickle.load(fh)
+        fh.close()
+        return data
+    
+    def set(self, key, value):
+        path = self.get_path(key)
+        fh = open(path, "wb")
+        pickle.dump(value, fh)
+        fh.close()
+    
+    def delete(self, key):
+        os.remove(self.get_path(key))