summaryrefslogtreecommitdiff
path: root/addons/document_webdav
diff options
context:
space:
mode:
authorHarry (OpenERP) <hmo@tinyerp.com>2010-07-20 18:35:13 +0530
committerHarry (OpenERP) <hmo@tinyerp.com>2010-07-20 18:35:13 +0530
commit77f62a88a314a905e5ffc73cffd72d68ddfe33db (patch)
treeedc70351000fba9ea5a4ab27a3f680c5844e9e82 /addons/document_webdav
parent90234707dc901a81935570274c52a5327940b66e (diff)
parent1eea693ecadd3829fa729a727a154c23a1df6ab6 (diff)
[MERGE] merged new api of document module
bzr revid: hmo@tinyerp.com-20100720130513-3t2cbyvns3hlj6qn
Diffstat (limited to 'addons/document_webdav')
-rw-r--r--addons/document_webdav/dav_fs.py118
-rw-r--r--addons/document_webdav/webdav.py4
-rw-r--r--addons/document_webdav/webdav_server.py17
3 files changed, 99 insertions, 40 deletions
diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py
index 880074173ea..ab9d3a75ae4 100644
--- a/addons/document_webdav/dav_fs.py
+++ b/addons/document_webdav/dav_fs.py
@@ -46,6 +46,15 @@ CACHE_SIZE=20000
urlparse.uses_netloc.append('webdav')
urlparse.uses_netloc.append('webdavs')
+class DAV_NotFound2(DAV_NotFound):
+ """404 exception, that accepts our list uris
+ """
+ def __init__(self, *args):
+ if len(args) and isinstance(args[0], (tuple, list)):
+ path = ''.join([ '/' + x for x in args[0]])
+ args = (path, )
+ DAV_NotFound.__init__(self, *args)
+
class openerp_dav_handler(dav_interface):
"""
This class models a OpenERP interface for the DAV server
@@ -74,6 +83,38 @@ class openerp_dav_handler(dav_interface):
cr.close()
return props
+ def _try_function(self, funct, args, opname='run function', cr=None,
+ default_exc=DAV_Forbidden):
+ """ Try to run a function, and properly convert exceptions to DAV ones.
+
+ @objname the name of the operation being performed
+ @param cr if given, the cursor to close at exceptions
+ """
+
+ try:
+ funct(*args)
+ except DAV_Error:
+ if cr: cr.close()
+ raise
+ except NotImplementedError, e:
+ if cr: cr.close()
+ import traceback
+ self.parent.log_error("Cannot %s: %s", opname, str(e))
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ # see par 9.3.1 of rfc
+ raise DAV_Error(403, str(e) or 'Not supported at this path')
+ except EnvironmentError, err:
+ if cr: cr.close()
+ import traceback
+ self.parent.log_error("Cannot %s: %s", opname, err.strerror)
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ raise default_exc(err.strerror)
+ except Exception,e:
+ import traceback
+ self.parent.log_error("Cannot create %s: %s", opname, str(e))
+ self.parent.log_message("Exc: %s",traceback.format_exc())
+ raise default_exc("Operation failed")
+
def _get_dav_lockdiscovery(self, uri):
raise DAV_NotFound
@@ -192,7 +233,7 @@ class openerp_dav_handler(dav_interface):
if not node:
if cr: cr.close()
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
else:
fp = node.full_path()
if fp and len(fp):
@@ -255,26 +296,25 @@ class openerp_dav_handler(dav_interface):
raise DAV_Error, 409
node = self.uri2object(cr, uid, pool, uri2)
if not node:
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
try:
if rrange:
self.parent.log_error("Doc get_data cannot use range")
raise DAV_Error(409)
datas = node.get_data(cr)
except TypeError,e:
- import traceback
- self.parent.log_error("GET typeError: %s", str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
+ # for the collections that return this error, the DAV standard
+ # says we'd better just return 200 OK with empty data
+ return ''
except IndexError,e :
self.parent.log_error("GET IndexError: %s", str(e))
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
except Exception,e:
import traceback
self.parent.log_error("GET exception: %s",str(e))
self.parent.log_message("Exc: %s", traceback.format_exc())
raise DAV_Error, 409
- return datas
+ return str(datas) # FIXME!
finally:
if cr: cr.close()
@@ -288,7 +328,7 @@ class openerp_dav_handler(dav_interface):
return COLLECTION
node = self.uri2object(cr,uid,pool, uri2)
if not node:
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
if node.type in ('collection','database'):
return COLLECTION
return OBJECT
@@ -304,7 +344,7 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
cr.close()
return node.displayname
@@ -320,7 +360,7 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
result = node.content_length or 0
cr.close()
return str(result)
@@ -337,7 +377,7 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
result = node.get_etag(cr)
cr.close()
return str(result)
@@ -352,7 +392,7 @@ class openerp_dav_handler(dav_interface):
try:
node = self.uri2object(cr, uid, pool, uri2)
if not node:
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
if node.write_date:
return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
else:
@@ -369,7 +409,7 @@ class openerp_dav_handler(dav_interface):
try:
node = self.uri2object(cr, uid, pool, uri2)
if not node:
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
if node.create_date:
result = time.mktime(time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S'))
else:
@@ -387,7 +427,7 @@ class openerp_dav_handler(dav_interface):
try:
node = self.uri2object(cr, uid, pool, uri2)
if not node:
- raise DAV_NotFound(uri2)
+ raise DAV_NotFound2(uri2)
result = str(node.mimetype)
return result
#raise DAV_NotFound, 'Could not find %s' % path
@@ -395,20 +435,28 @@ class openerp_dav_handler(dav_interface):
if cr: cr.close()
def mkcol(self,uri):
- """ create a new collection """
+ """ create a new collection
+ see par. 9.3 of rfc4918
+ """
self.parent.log_message('MKCOL: %s' % uri)
- uri = self.uri2local(uri)[1:]
- if uri[-1]=='/':uri=uri[:-1]
- parent = '/'.join(uri.split('/')[:-1])
- parent = self.baseuri + parent
- uri = self.baseuri + uri
- cr, uid, pool,dbname, uri2 = self.get_cr(uri)
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ if not uri2[-1]:
+ cr.close()
+ raise DAV_Error(409, "Cannot create nameless collection")
if not dbname:
+ cr.close()
raise DAV_Error, 409
node = self.uri2object(cr,uid,pool, uri2[:-1])
- if node:
- node.create_child_collection(cr, uri2[-1])
- cr.commit()
+ if not node:
+ cr.close()
+ raise DAV_Error(409, "Parent path %s does not exist" % uri2[:-1])
+ nc = node.child(cr, uri2[-1])
+ if nc:
+ cr.close()
+ raise DAV_Error(405, "Path already exists")
+ self._try_function(node.create_child_collection, (cr, uri2[-1]),
+ "create col %s" % uri2[-1], cr=cr)
+ cr.commit()
cr.close()
return True
@@ -430,22 +478,13 @@ class openerp_dav_handler(dav_interface):
if not node:
dir_node = self.uri2object(cr, uid, pool, uri2[:-1])
if not dir_node:
+ cr.close()
raise DAV_NotFound('Parent folder not found')
- try:
- dir_node.create_child(cr, objname, data)
- except Exception,e:
- import traceback
- self.parent.log_error("Cannot create %s: %s", objname, str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
+
+ self._try_function(dir_node.create_child, (cr, objname, data),
+ "create %s" % objname, cr=cr)
else:
- try:
- node.set_data(cr, data)
- except Exception,e:
- import traceback
- self.parent.log_error("Cannot save %s: %s", objname, str(e))
- self.parent.log_message("Exc: %s",traceback.format_exc())
- raise DAV_Forbidden
+ self._try_function(node.set_data, (cr, data), "save %s" % objname, cr=cr)
cr.commit()
cr.close()
@@ -618,7 +657,6 @@ class openerp_dav_handler(dav_interface):
advanced systems we might also have to copy properties from
the source to the destination.
"""
- print " copy a collection."
return self.mkcol(dst)
diff --git a/addons/document_webdav/webdav.py b/addons/document_webdav/webdav.py
index e904d2ecfb7..f2f57c77730 100644
--- a/addons/document_webdav/webdav.py
+++ b/addons/document_webdav/webdav.py
@@ -48,6 +48,8 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
# write href information
uparts=urlparse.urlparse(uri)
fileloc=uparts[2]
+ if isinstance(fileloc, unicode):
+ fileloc = fileloc.encode('utf-8')
href=doc.createElement("D:href")
davpath = self._dataclass.parent.get_davpath()
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
@@ -126,6 +128,8 @@ def mk_propname_response(self,uri,propnames,doc):
# write href information
uparts=urlparse.urlparse(uri)
fileloc=uparts[2]
+ if isinstance(fileloc, unicode):
+ fileloc = fileloc.encode('utf-8')
href=doc.createElement("D:href")
davpath = self._dataclass.parent.get_davpath()
hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py
index 610e51a0f07..9f9f2733a68 100644
--- a/addons/document_webdav/webdav_server.py
+++ b/addons/document_webdav/webdav_server.py
@@ -78,6 +78,18 @@ class DAVHandler(FixSendError,DAVRequestHandler):
self.baseuri = "http://%s:%d/"% (self.server.server_name, self.server.server_port)
self.IFACE_CLASS = openerp_dav_handler(self, self.verbose)
+ def copymove(self, CLASS):
+ """ Our uri scheme removes the /webdav/ component from there, so we
+ need to mangle the header, too.
+ """
+ dest = self.headers['Destination']
+ up = urlparse.urlparse(urllib.unquote(self.headers['Destination']))
+ if up.path.startswith(self.davpath):
+ self.headers['Destination'] = up.path[len(self.davpath):]
+ else:
+ raise DAV_Forbidden("Not allowed to copy/move outside webdav path")
+ DAVRequestHandler.copymove(self, CLASS)
+
def get_davpath(self):
return self.davpath
@@ -175,6 +187,11 @@ class DAVHandler(FixSendError,DAVRequestHandler):
self.send_body(None, '201', 'Created', '', headers=headers)
+ def do_DELETE(self):
+ try:
+ DAVRequestHandler.do_DELETE(self)
+ except DAV_Error, (ec, dd):
+ return self.send_status(ec)
from service.http_server import reg_http_service,OpenERPAuthProvider