summaryrefslogtreecommitdiff
path: root/addons/document_webdav/DAV/davcmd.py
diff options
context:
space:
mode:
Diffstat (limited to 'addons/document_webdav/DAV/davcmd.py')
-rw-r--r--addons/document_webdav/DAV/davcmd.py218
1 files changed, 218 insertions, 0 deletions
diff --git a/addons/document_webdav/DAV/davcmd.py b/addons/document_webdav/DAV/davcmd.py
new file mode 100644
index 00000000000..5c6be3ff9f7
--- /dev/null
+++ b/addons/document_webdav/DAV/davcmd.py
@@ -0,0 +1,218 @@
+"""
+
+davcmd.py
+---------
+
+containts commands like copy, move, delete for normal
+resources and collections
+
+"""
+
+from string import split,replace,joinfields
+import urlparse
+
+from utils import create_treelist, is_prefix
+from errors import *
+
+def deltree(dc,uri,exclude={}):
+ """ delete a tree of resources
+
+ dc -- dataclass to use
+ uri -- root uri to delete
+ exclude -- an optional list of uri:error_code pairs which should not
+ be deleted.
+
+ returns dict of uri:error_code tuples from which
+ another method can create a multistatus xml element.
+
+ Also note that we only know Depth=infinity thus we don't have
+ to test for it.
+
+ """
+
+ tlist=create_treelist(dc,uri)
+ result={}
+
+ for i in range(len(tlist),0,-1):
+ problem_uris=result.keys()
+ element=tlist[i-1]
+
+ # test here, if an element is a prefix of an uri which
+ # generated an error before.
+ # note that we walk here from childs to parents, thus
+ # we cannot delete a parent if a child made a problem.
+ # (see example in 8.6.2.1)
+ ok=1
+ for p in problem_uris:
+ if is_prefix(element,p):
+ ok=None
+ break
+
+ if not ok: continue
+
+ # here we test for the exclude list which is the other way round!
+ for p in exclude.keys():
+ if is_prefix(p,element):
+ ok=None
+ break
+
+ if not ok: continue
+
+ # now delete stuff
+ try:
+ delone(dc,element)
+ except DAV_Error, (ec,dd):
+ result[element]=ec
+
+ return result
+
+def delone(dc,uri):
+ """ delete a single object """
+ if dc.is_collection(uri):
+ dc.rmcol(uri) # should be empty
+ else:
+ dc.rm(uri)
+
+###
+### COPY
+###
+
+# helper function
+
+def copy(dc,src,dst):
+ """ only copy the element
+
+ This is just a helper method factored out from copy and
+ copytree. It will not handle the overwrite or depth header.
+
+ """
+
+ # destination should have been deleted before
+ if dc.exists(dst): raise DAV_Error, 412
+
+ # source should exist also
+ if not dc.exists(src): raise DAV_NotFound
+
+ if dc.is_collection(src):
+ dc.copycol(src,dst) # an exception will be passed thru
+ else:
+ dc.copy(src,dst) # an exception will be passed thru
+
+
+# the main functions
+
+def copyone(dc,src,dst,overwrite=None):
+ """ copy one resource to a new destination """
+
+ if overwrite and dc.exists(dst):
+ delres=deltree(dc,dst)
+ else:
+ delres={}
+
+ # if we cannot delete everything, then do not copy!
+ if delres: return delres
+
+ try:
+ copy(dc,src,dst) # pass thru exceptions
+ except DAV_Error, (ec,dd):
+ return ec
+
+def copytree(dc,src,dst,overwrite=None):
+ """ copy a tree of resources to another location
+
+ dc -- dataclass to use
+ src -- src uri from where to copy
+ dst -- dst uri
+ overwrite -- if 1 then delete dst uri before
+
+ returns dict of uri:error_code tuples from which
+ another method can create a multistatus xml element.
+
+ """
+
+
+ # first delete the destination resource
+ if overwrite and dc.exists(dst):
+ delres=deltree(dc,dst)
+ else:
+ delres={}
+
+ # if we cannot delete everything, then do not copy!
+ if delres: return delres
+
+ # get the tree we have to copy
+ tlist=create_treelist(dc,src)
+ result={}
+
+ # prepare destination URIs (get the prefix)
+ dpath=urlparse.urlparse(dst)[2]
+
+ for element in tlist:
+ problem_uris=result.keys()
+
+ # now URIs get longer and longer thus we have
+ # to test if we had a parent URI which we were not
+ # able to copy in problem_uris which is the prefix
+ # of the actual element. If it is, then we cannot
+ # copy this as well but do not generate another error.
+ ok=1
+ for p in problem_uris:
+ if is_prefix(p,element):
+ ok=None
+ break
+
+ if not ok: continue
+
+ # now create the destination URI which corresponds to
+ # the actual source URI. -> actual_dst
+ # ("subtract" the base src from the URI and prepend the
+ # dst prefix to it.)
+ esrc=replace(element,src,"")
+ actual_dst=dpath+esrc
+
+ # now copy stuff
+ try:
+ copy(dc,element,actual_dst)
+ except DAV_Error, (ec,dd):
+ result[element]=ec
+
+ return result
+
+
+
+###
+### MOVE
+###
+
+
+def moveone(dc,src,dst,overwrite=None):
+ """ move a single resource
+
+ This is done by first copying it and then deleting
+ the original.
+ """
+
+ # first copy it
+ copyone(dc,src,dst,overwrite)
+
+ # then delete it
+ dc.rm(src)
+
+def movetree(dc,src,dst,overwrite=None):
+ """ move a collection
+
+ This is done by first copying it and then deleting
+ the original.
+
+ PROBLEM: if something did not copy then we have a problem
+ when deleting as the original might get deleted!
+ """
+
+ # first copy it
+ res=copytree(dc,src,dst,overwrite)
+
+ # then delete it
+ res=deltree(dc,src,exclude=res)
+
+ return res
+