diff options
| author | Harry (OpenERP) <hmo@tinyerp.com> | 2010-07-20 18:35:13 +0530 |
|---|---|---|
| committer | Harry (OpenERP) <hmo@tinyerp.com> | 2010-07-20 18:35:13 +0530 |
| commit | 77f62a88a314a905e5ffc73cffd72d68ddfe33db (patch) | |
| tree | edc70351000fba9ea5a4ab27a3f680c5844e9e82 /addons/document_webdav | |
| parent | 90234707dc901a81935570274c52a5327940b66e (diff) | |
| parent | 1eea693ecadd3829fa729a727a154c23a1df6ab6 (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.py | 118 | ||||
| -rw-r--r-- | addons/document_webdav/webdav.py | 4 | ||||
| -rw-r--r-- | addons/document_webdav/webdav_server.py | 17 |
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 |
