1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 # Copyright (c) 1999 Christian Scholz (ruebe@aachen.heimat.de)
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as
10 # published by the Free Software Foundation, either version 3 of the
11 # License, or (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
23 import xml.dom.minidom
24 domimpl = xml.dom.minidom.getDOMImplementation()
28 from DAV.propfind import PROPFIND
32 super_mk_prop_response = PROPFIND.mk_prop_response
33 def mk_prop_response(self, uri, good_props, bad_props, doc):
34 """ make a new <prop> result element
36 We differ between the good props and the bad ones for
37 each generating an extra <propstat>-Node (for each error
41 re=doc.createElement("D:response")
42 # append namespaces to response
44 namespaces = self.namespaces
45 if 'DAV:' in namespaces:
46 namespaces.remove('DAV:')
47 for nsname in namespaces:
48 re.setAttribute("xmlns:ns"+str(nsnum),nsname)
51 def _prop_child(xnode, ns, prop, value):
52 """Append a property xml node to xnode, with <prop>value</prop>
54 And a little smarter than that, it will consider namespace and
55 also allow nested properties etc.
57 :param ns the namespace of the <prop/> node
58 :param prop the name of the property
59 :param value the value. Can be:
61 tuple ('elem', 'ns') for empty sub-node <ns:elem />
62 tuple ('elem', 'ns', sub-elems) for sub-node with elements
68 ns_prefix="ns"+str(namespaces.index(ns))+":"
70 pe=doc.createElement(ns_prefix+str(prop))
71 if hasattr(value, '__class__') and value.__class__.__name__ == 'Element':
74 if ns == 'DAV:' and prop=="resourcetype" and isinstance(value, int):
77 ve=doc.createElement("D:collection")
80 _prop_elem_child(pe, ns, value, ns_prefix)
84 def _prop_elem_child(pnode, pns, v, pns_prefix):
86 if isinstance(v, list):
88 _prop_elem_child(pnode, pns, vit, pns_prefix)
89 elif isinstance(v,tuple):
92 ns_prefix = pns_prefix
95 elif v[1] in namespaces:
96 ns_prefix="ns"+str(namespaces.index(v[1]))+":"
98 # namespaces.append(v[1])
100 ns_prefix="ns"+str(nsnum)+":"
103 ve=doc.createElement(ns_prefix+v[0])
105 ve.setAttribute("xmlns:ns"+str(nsnum), v[1])
106 if len(v) > 2 and isinstance(v[2], list):
107 # support nested elements like:
108 # ( 'elem', 'ns:', [('sub-elem1', 'ns1'), ...]
109 _prop_elem_child(ve, v[1], v[2], ns_prefix)
110 pnode.appendChild(ve)
112 ve=doc.createTextNode(tools.ustr(v))
113 pnode.appendChild(ve)
115 # write href information
116 uparts=urlparse.urlparse(uri)
118 if isinstance(fileloc, unicode):
119 fileloc = fileloc.encode('utf-8')
120 href=doc.createElement("D:href")
121 davpath = self._dataclass.parent.get_davpath()
122 hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
123 huri=doc.createTextNode(hurl)
124 href.appendChild(huri)
127 # write good properties
128 ps=doc.createElement("D:propstat")
132 gp=doc.createElement("D:prop")
133 for ns in good_props.keys():
137 ns_prefix="ns"+str(namespaces.index(ns))+":"
138 for p,v in good_props[ns].items():
141 _prop_child(gp, ns, p, v)
144 s=doc.createElement("D:status")
145 t=doc.createTextNode("HTTP/1.1 200 OK")
150 # now write the errors!
151 if len(bad_props.items()):
153 # write a propstat for each error code
154 for ecode in bad_props.keys():
155 ps=doc.createElement("D:propstat")
157 bp=doc.createElement("D:prop")
160 for ns in bad_props[ecode].keys():
164 ns_prefix="ns"+str(self.namespaces.index(ns))+":"
166 for p in bad_props[ecode][ns]:
167 pe=doc.createElement(ns_prefix+str(p))
170 s=doc.createElement("D:status")
171 t=doc.createTextNode(utils.gen_estring(ecode))
176 # return the new response element
180 def mk_propname_response(self,uri,propnames,doc):
181 """ make a new <prop> result element for a PROPNAME request
183 This will simply format the propnames list.
184 propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...}
187 re=doc.createElement("D:response")
189 # write href information
190 uparts=urlparse.urlparse(uri)
192 if isinstance(fileloc, unicode):
193 fileloc = fileloc.encode('utf-8')
194 href=doc.createElement("D:href")
195 davpath = self._dataclass.parent.get_davpath()
196 hurl = '%s://%s%s%s' % (uparts[0], uparts[1], davpath, urllib.quote(fileloc))
197 huri=doc.createTextNode(hurl)
198 href.appendChild(huri)
201 ps=doc.createElement("D:propstat")
204 for ns,plist in propnames.items():
206 pr=doc.createElement("D:prop")
211 ps.setAttribute("xmlns:"+nsp,ns)
214 # write propertynames
216 pe=doc.createElement(nsp+":"+p)
225 PROPFIND.mk_prop_response = mk_prop_response
226 PROPFIND.mk_propname_response = mk_propname_response