From 6429cbe667c1a0b8ec4147315b175b39f57b6603 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Sun, 27 Jun 2010 23:18:42 +0300 Subject: Doc WebDAV: fix for unicode names in paths. example, when exporiting dynamic folders with unicode names. bzr revid: p_christ@hol.gr-20100627201842-bor8tt5jk4vtgv6s --- addons/document_webdav/webdav.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'addons/document_webdav') 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)) -- cgit v1.2.3 From 136398f1755d46d8dc306ce0d3335e1cc688a065 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Mon, 12 Jul 2010 22:28:19 +0300 Subject: Doc Webdav: One more workaround for python-webdav. bzr revid: p_christ@hol.gr-20100712192819-7lr9zfogs6jjqq74 --- addons/document_webdav/webdav_server.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'addons/document_webdav') diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py index 610e51a0f07..b4cac5ffc70 100644 --- a/addons/document_webdav/webdav_server.py +++ b/addons/document_webdav/webdav_server.py @@ -175,6 +175,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 -- cgit v1.2.3 From 3fe8bf10a8e7353db08cba69a9a2969ab6530832 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Mon, 12 Jul 2010 22:29:30 +0300 Subject: Doc WebDAV: More consistent exceptions The NotFound one should properly parse the list uri2. Define a helper function that will wrap around usual calls and handle their exceptions. bzr revid: p_christ@hol.gr-20100712192930-necdd0z9d2j6w4ut --- addons/document_webdav/dav_fs.py | 80 ++++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 24 deletions(-) (limited to 'addons/document_webdav') diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 880074173ea..3805566f79d 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,36 @@ 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()) + raise DAV_Error(405, 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, e.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 +231,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,7 +294,7 @@ 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") @@ -268,7 +307,7 @@ class openerp_dav_handler(dav_interface): raise DAV_Forbidden 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)) @@ -288,7 +327,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 +343,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 +359,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 +376,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 +391,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 +408,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 +426,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 @@ -398,6 +437,8 @@ class openerp_dav_handler(dav_interface): """ create a new collection """ self.parent.log_message('MKCOL: %s' % uri) uri = self.uri2local(uri)[1:] + if not uri: + raise DAV_Error(409, "Cannot create nameless collection") if uri[-1]=='/':uri=uri[:-1] parent = '/'.join(uri.split('/')[:-1]) parent = self.baseuri + parent @@ -430,22 +471,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() -- cgit v1.2.3 From 83ff0d67573a6f921cc9736c750cfb6f487b7a8a Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Mon, 12 Jul 2010 22:32:36 +0300 Subject: Document webdav: fix mkcol, rename, get_data (temp) Conflicts: document_webdav/dav_fs.py document_webdav/webdav_server.py bzr revid: p_christ@hol.gr-20100712193236-8xde2tpmmxfp004n --- addons/document_webdav/dav_fs.py | 30 +++++++++++++++++------------- addons/document_webdav/webdav_server.py | 12 ++++++++++++ 2 files changed, 29 insertions(+), 13 deletions(-) (limited to 'addons/document_webdav') diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 3805566f79d..f6dc92caf20 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -313,7 +313,7 @@ class openerp_dav_handler(dav_interface): 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() @@ -434,22 +434,27 @@ 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 not 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 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) 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 @@ -650,7 +655,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_server.py b/addons/document_webdav/webdav_server.py index b4cac5ffc70..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 -- cgit v1.2.3 From 403a71fbaab7a8b607934347ccf6e7309f875f1a Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Tue, 13 Jul 2010 13:29:46 +0300 Subject: Document webdav: fix errors for get_data, mkcol bzr revid: p_christ@hol.gr-20100713102946-peksq27q3bxzgtnx --- addons/document_webdav/dav_fs.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'addons/document_webdav') diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index f6dc92caf20..4dba174d0a5 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -83,7 +83,8 @@ 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): + 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 @@ -100,7 +101,8 @@ class openerp_dav_handler(dav_interface): import traceback self.parent.log_error("Cannot %s: %s", opname, str(e)) self.parent.log_message("Exc: %s",traceback.format_exc()) - raise DAV_Error(405, str(e) or 'Not supported at this path') + # 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 @@ -301,10 +303,9 @@ class openerp_dav_handler(dav_interface): 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_NotFound2(uri2) @@ -453,7 +454,8 @@ class openerp_dav_handler(dav_interface): 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) + self._try_function(node.create_child_collection, (cr, uri2[-1]), + "create col %s" % uri2[-1], cr=cr) cr.commit() cr.close() return True -- cgit v1.2.3