diff options
Diffstat (limited to 'addons/document_webdav/DAV/utils.py')
| -rwxr-xr-x | addons/document_webdav/DAV/utils.py | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/addons/document_webdav/DAV/utils.py b/addons/document_webdav/DAV/utils.py new file mode 100755 index 00000000000..a764a6d96c9 --- /dev/null +++ b/addons/document_webdav/DAV/utils.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +""" + +UTILITIES + +- parse a propfind request body into a list of props + +""" + +from xml.dom import ext +from xml.dom.Document import Document +from xml.dom.ext.reader import PyExpat +from xml.dom import Node +from xml.dom import NodeIterator, NodeFilter + +from string import lower, split, atoi, joinfields +import urlparse +from StringIO import StringIO + +from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP +from status import STATUS_CODES + +VERSION = '0.6' +AUTHOR = 'Simon Pamies <s.pamies@banality.de>' + + +def gen_estring(ecode): + """ generate an error string from the given code """ + ec=atoi(str(ecode)) + if STATUS_CODES.has_key(ec): + return "HTTP/1.1 %s %s" %(ec,STATUS_CODES[ec]) + else: + return "HTTP/1.1 %s" %(ec) + +def parse_propfind(xml_doc): + """ parse an propfind xml file and return a list of props + + returns: + + request_type -- ALLPROP, PROPNAME, PROP + proplist -- list of properties found + namespaces -- list of namespaces found + + """ + doc = PyExpat.Reader().fromString(xml_doc) + snit = doc.createNodeIterator(doc, NodeFilter.NodeFilter.SHOW_ELEMENT, None, None) + + request_type=None + props={} + namespaces=[] + + while 1: + curr_elem = snit.nextNode() + if not curr_elem: break + ename=fname=lower(curr_elem.nodeName) + if ":" in fname: + ename=split(fname,":")[1] + if ename=="prop": request_type=RT_PROP; continue + if ename=="propfind": continue + if ename=="allprop": request_type=RT_ALLPROP; continue + if ename=="propname": request_type=RT_PROPNAME; continue + + # rest should be names of attributes + + ns = curr_elem.namespaceURI + if props.has_key(ns): + props[ns].append(ename) + else: + props[ns]=[ename] + namespaces.append(ns) + + return request_type,props,namespaces + + +def create_treelist(dataclass,uri): + """ create a list of resources out of a tree + + This function is used for the COPY, MOVE and DELETE methods + + uri - the root of the subtree to flatten + + It will return the flattened tree as list + + """ + queue=[uri] + list=[uri] + while len(queue): + element=queue[-1] + if dataclass.is_collection(element): + childs=dataclass.get_childs(element) + else: + childs=[] + if len(childs): + list=list+childs + # update queue + del queue[-1] + if len(childs): + queue=queue+childs + return list + +def is_prefix(uri1,uri2): + """ returns 1 of uri1 is a prefix of uri2 """ + if uri2[:len(uri1)]==uri1: + return 1 + else: + return None + +def quote_uri(uri): + """ quote an URL but not the protocol part """ + import urlparse + import urllib + + up=urlparse.urlparse(uri) + np=urllib.quote(up[2]) + return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) + +def get_uriparentpath(uri): + """ extract the uri path and remove the last element """ + up=urlparse.urlparse(uri) + return joinfields(split(up[2],"/")[:-1],"/") + +def get_urifilename(uri): + """ extract the uri path and return the last element """ + up=urlparse.urlparse(uri) + return split(up[2],"/")[-1] + +def get_parenturi(uri): + """ return the parent of the given resource""" + up=urlparse.urlparse(uri) + np=joinfields(split(up[2],"/")[:-1],"/") + return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5])) + +### XML utilities + +def make_xmlresponse(result): + """ construct a response from a dict of uri:error_code elements """ + doc = Document.Document(None) + ms=doc.createElement("D:multistatus") + ms.setAttribute("xmlns:D","DAV:") + doc.appendChild(ms) + + for el,ec in result.items(): + re=doc.createElement("D:response") + hr=doc.createElement("D:href") + st=doc.createElement("D:status") + huri=doc.createTextNode(quote_uri(el)) + t=doc.createTextNode(gen_estring(ec)) + st.appendChild(t) + hr.appendChild(huri) + re.appendChild(hr) + re.appendChild(st) + ms.appendChild(re) + + sfile=StringIO() + ext.PrettyPrint(doc,stream=sfile) + s=sfile.getvalue() + sfile.close() + return s + |
