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)