/usr/share/pyshared/pywebdav/lib/utils.py is in python-webdav 0.9.8-7.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | import time
import re
from xml.dom import minidom
import urlparse
from string import lower, split, atoi, joinfields
from StringIO import StringIO
from constants import RT_ALLPROP, RT_PROPNAME, RT_PROP
from BaseHTTPServer import BaseHTTPRequestHandler
def gen_estring(ecode):
""" generate an error string from the given code """
ec=atoi(str(ecode))
if BaseHTTPRequestHandler.responses.has_key(ec):
return "HTTP/1.1 %s %s" %(ec, BaseHTTPRequestHandler.responses[ec][0])
else:
return "HTTP/1.1 %s" %(ec)
def parse_propfind(xml_doc):
"""
Parse an propfind xml file and return a list of props
"""
doc = minidom.parseString(xml_doc)
request_type=None
props={}
namespaces=[]
if doc.getElementsByTagNameNS("DAV:", "allprop"):
request_type = RT_ALLPROP
elif doc.getElementsByTagNameNS("DAV:", "propname"):
request_type = RT_PROPNAME
else:
request_type = RT_PROP
for i in doc.getElementsByTagNameNS("DAV:", "prop"):
for e in i.childNodes:
if e.nodeType != minidom.Node.ELEMENT_NODE:
continue
ns = e.namespaceURI
ename = e.localName
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 = minidom.getDOMImplementation().createDocument(None, "multistatus", None)
doc.documentElement.setAttribute("xmlns:D","DAV:")
doc.documentElement.tagName = "D:multistatus"
for el,ec in result.items():
re=doc.createElementNS("DAV:","response")
hr=doc.createElementNS("DAV:","href")
st=doc.createElementNS("DAV:","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)
doc.documentElement.appendChild(re)
return doc.toxml(encoding="utf-8")
# taken from App.Common
weekday_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
weekday_full = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
def rfc1123_date(ts=None):
# Return an RFC 1123 format date string, required for
# use in HTTP Date headers per the HTTP 1.1 spec.
# 'Fri, 10 Nov 2000 16:21:09 GMT'
if ts is None: ts=time.time()
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts)
return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekday_abbr[wd],
day, monthname[month],
year,
hh, mm, ss)
def iso8601_date(ts=None):
# Return an ISO 8601 formatted date string, required
# for certain DAV properties.
# '2000-11-10T16:21:09-08:00
if ts is None: ts=time.time()
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts))
def rfc850_date(ts=None):
# Return an HTTP-date formatted date string.
# 'Friday, 10-Nov-00 16:21:09 GMT'
if ts is None: ts=time.time()
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts)
return "%s, %02d-%3s-%2s %02d:%02d:%02d GMT" % (
weekday_full[wd],
day, monthname[month],
str(year)[2:],
hh, mm, ss)
### If: header handling support. IfParser returns a sequence of
### TagList objects in the order they were parsed which can then
### be used in WebDAV methods to decide whether an operation can
### proceed or to raise HTTP Error 412 (Precondition failed)
IfHdr = re.compile(
r"(?P<resource><.+?>)?\s*\((?P<listitem>[^)]+)\)"
)
ListItem = re.compile(
r"(?P<not>not)?\s*(?P<listitem><[a-zA-Z]+:[^>]*>|\[.*?\])",
re.I)
class TagList:
def __init__(self):
self.resource = None
self.list = []
self.NOTTED = 0
def IfParser(hdr):
out = []
i = 0
while 1:
m = IfHdr.search(hdr[i:])
if not m: break
i = i + m.end()
tag = TagList()
tag.resource = m.group('resource')
if tag.resource: # We need to delete < >
tag.resource = tag.resource[1:-1]
listitem = m.group('listitem')
tag.NOTTED, tag.list = ListParser(listitem)
out.append(tag)
return out
def tokenFinder(token):
# takes a string like '<opaquelocktoken:afsdfadfadf> and returns the token
# part.
if not token: return None # An empty string was passed in
if token[0] == '[': return None # An Etag was passed in
if token[0] == '<': token = token[1:-1]
return token[token.find(':')+1:]
def ListParser(listitem):
out = []
NOTTED = 0
i = 0
while 1:
m = ListItem.search(listitem[i:])
if not m: break
i = i + m.end()
out.append(m.group('listitem'))
if m.group('not'): NOTTED = 1
return NOTTED, out
|