Menu

[r3]: / python_webdav / connection.py  Maximize  Restore  History

Download this file

242 lines (219 with data), 9.0 kB

  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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
""" Connection Module
"""
import httplib2
import xml.dom.minidom
class Connection(object):
""" Connection object
"""
def __init__(self, settings):
""" Set up the object
"""
# Get network settings
self.username = settings['username']
self.password = settings['password']
self.realm = settings['realm']
self.host = settings['host']
self.path = settings['path']
self.port = settings['port']
# Make an http object for this connection
self.httpcon = httplib2.Http()
self.httpcon.add_credentials(self.username, self.password)
def _send_request(self, request_method, path, body='', headers=None):
""" Send a request over http to the webdav server
"""
if not headers:
headers = {}
uri = httplib2.urlparse.urljoin(self.host, path)
try:
resp, content = self.httpcon.request(uri, request_method,
body=body, headers=headers)
except httplib2.ServerNotFoundError:
raise
return resp, content
def send_delete(self, path):
""" Send a DELETE request
"""
try:
resp, content = self._send_request('DELETE', path)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_get(self, path):
""" Send a GET request
"""
try:
resp, content = self._send_request('GET', path)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_put(self, path, body):
""" This PUT request will put data files onto a webdav server.
However, please note that due to the way in which httplib2 sends
files, it is not currently possible to break a file up into chunks
and read it in. In other words, the whole file has to be read into
memory for sending. This could be problematic for large files.
"""
try:
resp, content = self._send_request('PUT', path, body=body)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_propfind(self, path):
""" Send a PROPFIND request
"""
try:
headers = {'Depth':'1'}
resp, content = self._send_request('PROPFIND', path,
headers=headers)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_lock(self, path):
""" Send a LOCK request
"""
try:
body = '<?xml version="1.0" encoding="utf-8" ?>'
body += '<D:lockinfo xmlns:D="DAV:"><D:lockscope><D:exclusive/>'
body += '</D:lockscope><D:locktype><D:write/></D:locktype><D:owner>'
body += '<D:href>MyWebDAV/test_file1.txt</D:href>'
body += '</D:owner></D:lockinfo>'
resp, content = self._send_request('LOCK', path, body=body)
lock_token = LockToken(resp['lock-token'])
return resp, content, lock_token
except httplib2.ServerNotFoundError:
raise
def send_unlock(self, path, lock_token):
""" Send an UNLOCK request
"""
try:
headers = {'Lock-Token': lock_token.token}
body = '<?xml version="1.0" encoding="utf-8" ?>'
body += '<D:lockinfo xmlns:D="DAV:"><D:lockscope><D:exclusive/>'
body += '</D:lockscope><D:locktype><D:write/></D:locktype><D:owner>'
body += '<D:href>MyWebDAV/test_file1.txt</D:href>'
body += '</D:owner></D:lockinfo>'
resp, content = self._send_request('UNLOCK', path, headers=headers,
body=body)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_mkcol(self, path):
""" Send a MKCOL request
"""
try:
resp, content = self._send_request('MKCOL', path)
return resp, content
except httplib2.ServerNotFoundError, err:
print "Oops, server not found!", err
raise
def send_rmcol(self, path):
""" Send an RMCOL request
"""
try:
resp, content = self._send_request('DELETE', path)
return resp, content
except httplib2.ServerNotFoundError:
raise
def send_copy(self, path, destination):
""" Send a COPY request
"""
try:
full_destination = httplib2.urlparse.urljoin(self.host, destination)
headers = {'Destination': full_destination}
resp, content = self._send_request('COPY', path, headers=headers)
return resp, content
except httplib2.ServerNotFoundError:
raise
class LockToken(object):
""" LockToken object
"""
def __init__(self, lock_token):
""" Make a lock token
"""
self.token = lock_token
class Property(object):
""" Property object for storing information about WebDAV properties
"""
def set_property(self, property_name, property_value=None):
""" Set property names
"""
self.__dict__[property_name] = property_value
class Client(object):
""" This class is a mid-level class for accessing webdav things
"""
def __init__(self):
""" Init with minidom
"""
self.dom = xml.dom.minidom
self.all_nodes = None
self.resource_nodes = None
def get_properties(self, url):
""" Get a list of property objects
@url - the path of the resource / collection minus the host section
"""
def parse_xml_prop(self, xml):
""" Parse the property XML
"""
self.all_nodes = []
#child_nodes = []
self.resource_nodes = []
xml_dom = self.dom.parseString(xml)
#child_nodes = xml_dom.childNodes[0].childNodes
self.get_nodes(xml_dom.childNodes)
resources_all = self.make_resources(self.resource_nodes)
return resources_all
def get_nodes(self, nodes):
""" Get any DAV nodes
"""
for child in nodes:
for cur_node in child.childNodes:
try:
#print cur_node.
if cur_node.namespaceURI == u'DAV:' and cur_node.tagName \
== u'D:response':
self.resource_nodes.append(cur_node)
except AttributeError:
pass
self.get_nodes(child.childNodes)
self.all_nodes.append(child)
def make_resources(self, element_list):
""" Make any resources
"""
prop_list = []
for element in element_list:
for node in element.childNodes:
try:
if node.localName == u'href':
href = node.childNodes[0].data
elif node.localName == u'propstat':
for item in node.childNodes:
if item.localName == u'prop':
this_property = Property()
this_property.set_property(u'href', href)
for cn1 in item.childNodes:
if cn1.localName != None:
try:
# Try and get the data from the
# element
this_property.set_property(
cn1.localName,
cn1.childNodes[0].data)
except AttributeError:
# No data, so see if there are any
# child nodes
if cn1.childNodes:
this_property.set_property(
cn1.localName,
cn1.childNodes[0].localName)
else:
this_property.set_property(
cn1.localName,
cn1.localName)
except IndexError:
# Add in some handling for locks
print "Index Error!"
continue
prop_list.append(this_property)
except AttributeError:
pass
return prop_list