63
64
if hasattr(e, 'errno'):
64
65
if e.errno in (errno.ENOENT, errno.ENOTDIR):
65
66
raise errors.NoSuchFile(path, extra=e)
67
# I would rather use errno.EFOO, but there doesn't seem to be
68
# any matching for 267
69
# This is the error when doing a listdir on a file:
70
# WindowsError: [Errno 267] The directory name is invalid
71
if sys.platform == 'win32' and e.errno in (errno.ESRCH, 267):
72
raise errors.NoSuchFile(path, extra=e)
66
73
if e.errno == errno.EEXIST:
67
74
raise errors.FileExists(path, extra=e)
68
75
if e.errno == errno.EACCES:
214
221
yield self.get(relpath)
217
def put(self, relpath, f):
224
def put(self, relpath, f, mode=None):
218
225
"""Copy the file-like or string object into the location.
220
227
:param relpath: Location to put the contents, relative to base.
221
228
:param f: File-like or string object.
229
:param mode: The mode for the newly created file,
230
None means just use the default
223
232
raise NotImplementedError
225
def put_multi(self, files, pb=None):
234
def put_multi(self, files, mode=None, pb=None):
226
235
"""Put a set of files or strings into the location.
228
237
:param files: A list of tuples of relpath, file object [(path1, file1), (path2, file2),...]
229
238
:param pb: An optional ProgressBar for indicating percent done.
239
:param mode: The mode for the newly created files
230
240
:return: The number of files copied.
232
return self._iterate_over(files, self.put, pb, 'put', expand=True)
243
self.put(path, f, mode=mode)
244
return self._iterate_over(files, put, pb, 'put', expand=True)
234
def mkdir(self, relpath):
246
def mkdir(self, relpath, mode=None):
235
247
"""Create a directory at the given path."""
236
248
raise NotImplementedError
238
def mkdir_multi(self, relpaths, pb=None):
250
def mkdir_multi(self, relpaths, mode=None, pb=None):
239
251
"""Create a group of directories"""
240
return self._iterate_over(relpaths, self.mkdir, pb, 'mkdir', expand=False)
253
self.mkdir(path, mode=mode)
254
return self._iterate_over(relpaths, mkdir, pb, 'mkdir', expand=False)
242
256
def append(self, relpath, f):
243
257
"""Append the text in the file-like or string object to
267
281
# implementors don't have to implement everything.
268
282
return self._iterate_over(relpaths, self.copy, pb, 'copy', expand=True)
270
def copy_to(self, relpaths, other, pb=None):
284
def copy_to(self, relpaths, other, mode=None, pb=None):
271
285
"""Copy a set of entries from self into another Transport.
273
287
:param relpaths: A list/generator of entries to be copied.
288
:param mode: This is the target mode for the newly created files
274
289
TODO: This interface needs to be updated so that the target location
275
290
can be different from the source location.
277
292
# The dummy implementation just does a simple get + put
278
293
def copy_entry(path):
279
other.put(path, self.get(path))
294
other.put(path, self.get(path), mode=mode)
281
296
return self._iterate_over(relpaths, copy_entry, pb, 'copy_to', expand=False)