diff --git a/addons/document/nodes.py b/addons/document/nodes.py
index de2a83285f9..228f104574d 100644
--- a/addons/document/nodes.py
+++ b/addons/document/nodes.py
@@ -314,6 +314,14 @@ class node_class(object):
logger.debug('Property %s not supported' % prop, exc_info=True)
return None
+ def get_dav_resourcetype(self, cr):
+ """ Get the DAV resource type.
+
+ Is here because some nodes may exhibit special behaviour, like
+ CalDAV/GroupDAV collections
+ """
+ raise NotImplementedError
+
def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False):
""" Move this node to a new parent directory.
@param ndir_node the collection that this node should be moved under
@@ -456,6 +464,9 @@ class node_database(node_class):
def _get_ttag(self,cr):
return 'db-%s' % cr.dbname
+ def get_dav_resourcetype(self, cr):
+ return ('collection', 'DAV:')
+
def mkdosname(company_name, default='noname'):
""" convert a string to a dos-like name"""
if not company_name:
@@ -778,6 +789,9 @@ class node_res_dir(node_class):
def _get_ttag(self,cr):
return 'rdir-%d' % self.dir_id
+ def get_dav_resourcetype(self, cr):
+ return ('collection', 'DAV:')
+
class node_res_obj(node_class):
""" A special sibling to node_dir, which does only contain dynamically
created folders foreach resource in the foreign model.
@@ -1034,6 +1048,9 @@ class node_res_obj(node_class):
def _get_ttag(self,cr):
return 'rodir-%d-%d' % (self.dir_id, self.res_id)
+ def get_dav_resourcetype(self, cr):
+ return ('collection', 'DAV:')
+
class node_file(node_class):
our_type = 'file'
def __init__(self, path, parent, context, fil):
@@ -1168,6 +1185,9 @@ class node_file(node_class):
def _get_ttag(self,cr):
return 'file-%d' % self.file_id
+ def get_dav_resourcetype(self, cr):
+ return ''
+
def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False):
if ndir_node.context != self.context:
raise NotImplementedError("Cannot move files between contexts")
@@ -1313,6 +1333,8 @@ class node_content(node_class):
def _get_ttag(self,cr):
return 'cnt-%d%s' % (self.cnt_id,(self.act_id and ('-' + str(self.act_id))) or '')
+ def get_dav_resourcetype(self, cr):
+ return ''
class nodefd_content(StringIO, node_descriptor):
""" A descriptor to content nodes
diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py
index 78812ff8cf5..af8738ef0da 100644
--- a/addons/document_webdav/dav_fs.py
+++ b/addons/document_webdav/dav_fs.py
@@ -370,19 +370,22 @@ class openerp_dav_handler(dav_interface):
if cr: cr.close()
@memoize(CACHE_SIZE)
- def _get_dav_resourcetype(self,uri):
+ def _get_dav_resourcetype(self, uri):
""" return type of object """
self.parent.log_message('get RT: %s' % uri)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
try:
if not dbname:
return COLLECTION
- node = self.uri2object(cr,uid,pool, uri2)
+ node = self.uri2object(cr, uid, pool, uri2)
if not node:
raise DAV_NotFound2(uri2)
- if node.type in ('collection','database'):
- return COLLECTION
- return OBJECT
+ try:
+ return node.get_dav_resourcetype(cr)
+ except NotImplementedError:
+ if node.type in ('collection','database'):
+ return ('collection', 'DAV:')
+ return ''
finally:
if cr: cr.close()
@@ -739,6 +742,17 @@ class openerp_dav_handler(dav_interface):
@memoize(CACHE_SIZE)
def is_collection(self, uri):
""" test if the given uri is a collection """
- return self._get_dav_resourcetype(uri)==COLLECTION
+ cr, uid, pool, dbname, uri2 = self.get_cr(uri)
+ try:
+ if not dbname:
+ return True
+ node = self.uri2object(cr,uid,pool, uri2)
+ if not node:
+ raise DAV_NotFound2(uri2)
+ if node.type in ('collection','database'):
+ return True
+ return False
+ finally:
+ if cr: cr.close()
#eof
diff --git a/addons/document_webdav/webdav.py b/addons/document_webdav/webdav.py
index 1502ff204f8..1fd530cbdca 100644
--- a/addons/document_webdav/webdav.py
+++ b/addons/document_webdav/webdav.py
@@ -48,6 +48,70 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
re.setAttribute("xmlns:ns"+str(nsnum),nsname)
nsnum=nsnum+1
+ def _prop_child(xnode, ns, prop, value):
+ """Append a property xml node to xnode, with value
+
+ And a little smarter than that, it will consider namespace and
+ also allow nested properties etc.
+
+ :param ns the namespace of the node
+ :param prop the name of the property
+ :param value the value. Can be:
+ string: text node
+ tuple ('elem', 'ns') for empty sub-node
+ tuple ('elem', 'ns', sub-elems) for sub-node with elements
+ list, of above tuples
+ """
+ if ns == 'DAV:':
+ ns_prefix = 'D:'
+ else:
+ ns_prefix="ns"+str(namespaces.index(ns))+":"
+
+ pe=doc.createElement(ns_prefix+str(prop))
+ if hasattr(value, '__class__') and value.__class__.__name__ == 'Element':
+ pe.appendChild(value)
+ else:
+ if ns == 'DAV:' and prop=="resourcetype" and isinstance(value, int):
+ # hack, to go..
+ if value == 1:
+ ve=doc.createElement("D:collection")
+ pe.appendChild(ve)
+ else:
+ _prop_elem_child(pe, ns, value, ns_prefix)
+
+ xnode.appendChild(pe)
+
+ def _prop_elem_child(pnode, pns, v, pns_prefix):
+
+ if isinstance(v, list):
+ for vit in v:
+ _prop_elem_child(pnode, pns, vit, pns_prefix)
+ elif isinstance(v,tuple):
+ need_ns = False
+ if v[1] == pns:
+ ns_prefix = pns_prefix
+ elif v[1] == 'DAV:':
+ ns_prefix = 'D:'
+ elif v[1] in namespaces:
+ ns_prefix="ns"+str(namespaces.index(v[1]))+":"
+ else:
+ # namespaces.append(v[1])
+ # nsnum += 1
+ ns_prefix="ns"+str(nsnum)+":"
+ need_ns = True
+
+ ve=doc.createElement(ns_prefix+v[0])
+ if need_ns:
+ ve.setAttribute("xmlns:ns"+str(nsnum), v[1])
+ if len(v) > 2 and isinstance(v[2], list):
+ # support nested elements like:
+ # ( 'elem', 'ns:', [('sub-elem1', 'ns1'), ...]
+ _prop_elem_child(ve, v[1], v[2], ns_prefix)
+ pnode.appendChild(ve)
+ else:
+ ve=doc.createTextNode(tools.ustr(v))
+ pnode.appendChild(ve)
+
# write href information
uparts=urlparse.urlparse(uri)
fileloc=uparts[2]
@@ -74,22 +138,7 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
for p,v in good_props[ns].items():
if not v:
continue
- pe=doc.createElement(ns_prefix+str(p))
- if hasattr(v, '__class__') and v.__class__.__name__ == 'Element':
- pe.appendChild(v)
- else:
- if ns == 'DAV:' and p=="resourcetype":
- if v == 1:
- ve=doc.createElement("D:collection")
- pe.appendChild(ve)
- elif isinstance(v,tuple) and v[1] == ns:
- ve=doc.createElement(ns_prefix+v[0])
- pe.appendChild(ve)
- else:
- ve=doc.createTextNode(tools.ustr(v))
- pe.appendChild(ve)
-
- gp.appendChild(pe)
+ _prop_child(gp, ns, p, v)
ps.appendChild(gp)
s=doc.createElement("D:status")