Doc, webdav: new API for the DAV:resourcetype property.
This property is used in DAV folders, CalDAV, GroupDAV and CardDAV, with different extensions at each one. So, it needs an extensible API for the value it may return. Typical response in a calendar dir: <D:resourcetype> <D:collection> <ns0:vevent-collection xmlns:ns0="http://groupdav.org"/> <ns1:calendar xmlns:ns1="urn:ietf:params:xml:ns:caldav" /> </D:resourcetype> The last two elements have to be added by subclassing the node in the caldav module. Conflicts: document_webdav/dav_fs.py bzr revid: p_christ@hol.gr-20100801083722-nh4ty58fy0hobrgk
This commit is contained in:
parent
313ffd1550
commit
2289282c8b
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <prop>value</prop>
|
||||
|
||||
And a little smarter than that, it will consider namespace and
|
||||
also allow nested properties etc.
|
||||
|
||||
:param ns the namespace of the <prop/> node
|
||||
:param prop the name of the property
|
||||
:param value the value. Can be:
|
||||
string: text node
|
||||
tuple ('elem', 'ns') for empty sub-node <ns:elem />
|
||||
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")
|
||||
|
|
Loading…
Reference in New Issue