~openerp-commiter/openobject-addons/extra-6.0

« back to all changes in this revision

Viewing changes to document_webdav_old/webdav/DAV/utils.py

  • Committer: Fabien Pinckaers
  • Date: 2008-12-12 09:09:57 UTC
  • Revision ID: fp@tinyerp.com-20081212090957-cson0n0jove7dt7i
document_webdav

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
"""
 
4
 
 
5
UTILITIES
 
6
 
 
7
- parse a propfind request body into a list of props
 
8
 
 
9
"""
 
10
 
 
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
 
16
 
 
17
from string import lower, split, atoi, joinfields
 
18
import urlparse
 
19
from StringIO import StringIO
 
20
 
 
21
from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP
 
22
from status import STATUS_CODES
 
23
 
 
24
VERSION = '0.6'
 
25
AUTHOR  = 'Simon Pamies <s.pamies@banality.de>'
 
26
 
 
27
 
 
28
def gen_estring(ecode):
 
29
    """ generate an error string from the given code """
 
30
    ec=atoi(str(ecode))
 
31
    if STATUS_CODES.has_key(ec):
 
32
        return "HTTP/1.1 %s %s" %(ec,STATUS_CODES[ec])
 
33
    else:
 
34
        return "HTTP/1.1 %s" %(ec)
 
35
 
 
36
def parse_propfind(xml_doc):
 
37
    """ parse an propfind xml file and return a list of props
 
38
 
 
39
    returns:
 
40
 
 
41
        request_type            -- ALLPROP, PROPNAME, PROP
 
42
        proplist            -- list of properties found
 
43
        namespaces            -- list of namespaces found
 
44
 
 
45
    """
 
46
    doc = PyExpat.Reader().fromString(xml_doc)
 
47
    snit = doc.createNodeIterator(doc, NodeFilter.NodeFilter.SHOW_ELEMENT, None, None)
 
48
 
 
49
    request_type=None
 
50
    props={}
 
51
    namespaces=[]
 
52
 
 
53
    while 1:
 
54
        curr_elem = snit.nextNode()
 
55
        if not curr_elem: break
 
56
        ename=fname=lower(curr_elem.nodeName)
 
57
        if ":" in fname:
 
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
 
63
 
 
64
        # rest should be names of attributes
 
65
 
 
66
        ns = curr_elem.namespaceURI
 
67
        if props.has_key(ns):
 
68
            props[ns].append(ename)
 
69
        else:
 
70
            props[ns]=[ename]
 
71
            namespaces.append(ns)
 
72
 
 
73
    return request_type,props,namespaces
 
74
 
 
75
 
 
76
def create_treelist(dataclass,uri):
 
77
    """ create a list of resources out of a tree
 
78
 
 
79
    This function is used for the COPY, MOVE and DELETE methods
 
80
 
 
81
    uri - the root of the subtree to flatten
 
82
 
 
83
    It will return the flattened tree as list
 
84
 
 
85
    """
 
86
    queue=[uri]
 
87
    list=[uri]
 
88
    while len(queue):
 
89
        element=queue[-1]
 
90
        if dataclass.is_collection(element):
 
91
            childs=dataclass.get_childs(element)
 
92
        else:
 
93
            childs=[]
 
94
        if len(childs):
 
95
            list=list+childs
 
96
        # update queue
 
97
        del queue[-1]
 
98
        if len(childs):
 
99
            queue=queue+childs
 
100
    return list
 
101
 
 
102
def is_prefix(uri1,uri2):
 
103
    """ returns 1 of uri1 is a prefix of uri2 """
 
104
    if uri2[:len(uri1)]==uri1:
 
105
        return 1
 
106
    else:
 
107
        return None
 
108
 
 
109
def quote_uri(uri):
 
110
    """ quote an URL but not the protocol part """
 
111
    import urlparse
 
112
    import urllib
 
113
 
 
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]))
 
117
 
 
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],"/")
 
122
 
 
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]
 
127
 
 
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]))
 
133
 
 
134
### XML utilities
 
135
 
 
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:")
 
141
    doc.appendChild(ms)
 
142
 
 
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))
 
149
        st.appendChild(t)
 
150
        hr.appendChild(huri)
 
151
        re.appendChild(hr)
 
152
        re.appendChild(st)
 
153
        ms.appendChild(re)
 
154
 
 
155
    sfile=StringIO()
 
156
    ext.PrettyPrint(doc,stream=sfile)
 
157
    s=sfile.getvalue()
 
158
    sfile.close()
 
159
    return s
 
160