7 - parse a propfind request body into a list of props
11 from xml.dom import ext
12 from xml.dom.Document import Document
13 from xml.dom.ext.reader import PyExpat
14 from xml.dom import Node
15 from xml.dom import NodeIterator, NodeFilter
17 from string import lower, split, atoi, joinfields
19 from StringIO import StringIO
21 from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP
22 from status import STATUS_CODES
25 AUTHOR = 'Simon Pamies <s.pamies@banality.de>'
28 def gen_estring(ecode):
29 """ generate an error string from the given code """
31 if STATUS_CODES.has_key(ec):
32 return "HTTP/1.1 %s %s" %(ec,STATUS_CODES[ec])
34 return "HTTP/1.1 %s" %(ec)
36 def parse_propfind(xml_doc):
37 """ parse an propfind xml file and return a list of props
41 request_type -- ALLPROP, PROPNAME, PROP
42 proplist -- list of properties found
43 namespaces -- list of namespaces found
46 doc = PyExpat.Reader().fromString(xml_doc)
47 snit = doc.createNodeIterator(doc, NodeFilter.NodeFilter.SHOW_ELEMENT, None, None)
54 curr_elem = snit.nextNode()
55 if not curr_elem: break
56 ename=fname=lower(curr_elem.nodeName)
58 ename=split(fname,":")[1]
59 if ename=="prop": request_type=RT_PROP; continue
60 if ename=="propfind": continue
61 if ename=="allprop": request_type=RT_ALLPROP; continue
62 if ename=="propname": request_type=RT_PROPNAME; continue
64 # rest should be names of attributes
66 ns = curr_elem.namespaceURI
68 props[ns].append(ename)
73 return request_type,props,namespaces
76 def create_treelist(dataclass,uri):
77 """ create a list of resources out of a tree
79 This function is used for the COPY, MOVE and DELETE methods
81 uri - the root of the subtree to flatten
83 It will return the flattened tree as list
90 if dataclass.is_collection(element):
91 childs=dataclass.get_childs(element)
102 def is_prefix(uri1,uri2):
103 """ returns 1 of uri1 is a prefix of uri2 """
104 if uri2[:len(uri1)]==uri1:
110 """ quote an URL but not the protocol part """
114 up=urlparse.urlparse(uri)
115 np=urllib.quote(up[2])
116 return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5]))
118 def get_uriparentpath(uri):
119 """ extract the uri path and remove the last element """
120 up=urlparse.urlparse(uri)
121 return joinfields(split(up[2],"/")[:-1],"/")
123 def get_urifilename(uri):
124 """ extract the uri path and return the last element """
125 up=urlparse.urlparse(uri)
126 return split(up[2],"/")[-1]
128 def get_parenturi(uri):
129 """ return the parent of the given resource"""
130 up=urlparse.urlparse(uri)
131 np=joinfields(split(up[2],"/")[:-1],"/")
132 return urlparse.urlunparse((up[0],up[1],np,up[3],up[4],up[5]))
136 def make_xmlresponse(result):
137 """ construct a response from a dict of uri:error_code elements """
138 doc = Document.Document(None)
139 ms=doc.createElement("D:multistatus")
140 ms.setAttribute("xmlns:D","DAV:")
143 for el,ec in result.items():
144 re=doc.createElement("D:response")
145 hr=doc.createElement("D:href")
146 st=doc.createElement("D:status")
147 huri=doc.createTextNode(quote_uri(el))
148 t=doc.createTextNode(gen_estring(ec))
156 ext.PrettyPrint(doc,stream=sfile)