66
67
if hasattr(e, 'errno'):
67
68
if e.errno in (errno.ENOENT, errno.ENOTDIR):
68
69
raise errors.NoSuchFile(path, extra=e)
70
# I would rather use errno.EFOO, but there doesn't seem to be
71
# any matching for 267
72
# This is the error when doing a listdir on a file:
73
# WindowsError: [Errno 267] The directory name is invalid
74
if sys.platform == 'win32' and e.errno in (errno.ESRCH, 267):
75
raise errors.NoSuchFile(path, extra=e)
69
76
if e.errno == errno.EEXIST:
70
77
raise errors.FileExists(path, extra=e)
71
78
if e.errno == errno.EACCES:
219
226
yield self.get(relpath)
222
def put(self, relpath, f):
229
def put(self, relpath, f, mode=None):
223
230
"""Copy the file-like or string object into the location.
225
232
:param relpath: Location to put the contents, relative to base.
226
233
:param f: File-like or string object.
234
:param mode: The mode for the newly created file,
235
None means just use the default
228
237
raise NotImplementedError
230
def put_multi(self, files, pb=None):
239
def put_multi(self, files, mode=None, pb=None):
231
240
"""Put a set of files into the location.
233
242
:param files: A list of tuples of relpath, file object [(path1, file1), (path2, file2),...]
234
243
:param pb: An optional ProgressBar for indicating percent done.
244
:param mode: The mode for the newly created files
235
245
:return: The number of files copied.
237
return self._iterate_over(files, self.put, pb, 'put', expand=True)
248
self.put(path, f, mode=mode)
249
return self._iterate_over(files, put, pb, 'put', expand=True)
239
def mkdir(self, relpath):
251
def mkdir(self, relpath, mode=None):
240
252
"""Create a directory at the given path."""
241
253
raise NotImplementedError
243
def mkdir_multi(self, relpaths, pb=None):
255
def mkdir_multi(self, relpaths, mode=None, pb=None):
244
256
"""Create a group of directories"""
245
return self._iterate_over(relpaths, self.mkdir, pb, 'mkdir', expand=False)
258
self.mkdir(path, mode=mode)
259
return self._iterate_over(relpaths, mkdir, pb, 'mkdir', expand=False)
247
261
def append(self, relpath, f):
248
262
"""Append the text in the file-like or string object to
276
290
# implementors don't have to implement everything.
277
291
return self._iterate_over(relpaths, self.copy, pb, 'copy', expand=True)
279
def copy_to(self, relpaths, other, pb=None):
293
def copy_to(self, relpaths, other, mode=None, pb=None):
280
294
"""Copy a set of entries from self into another Transport.
282
296
:param relpaths: A list/generator of entries to be copied.
297
:param mode: This is the target mode for the newly created files
283
298
TODO: This interface needs to be updated so that the target location
284
299
can be different from the source location.
286
301
# The dummy implementation just does a simple get + put
287
302
def copy_entry(path):
288
other.put(path, self.get(path))
303
other.put(path, self.get(path), mode=mode)
290
305
return self._iterate_over(relpaths, copy_entry, pb, 'copy_to', expand=False)