def open(self, path, mode='r', **kwargs): self._log(INFO, 'Opening file %s in mode %s' % (path, mode)) newfile = False if not self.exists(path): if 'w' in mode or 'a' in mode: newfile = True else: self._log(DEBUG, "File %s not found while opening for reads" % path) raise errors.ResourceNotFoundError(path) elif self.isdir(path): self._log(DEBUG, "Path %s is directory, not a file" % path) raise errors.ResourceInvalidError(path) elif 'w' in mode: newfile = True if newfile: self._log(DEBUG, 'Creating empty file %s' % path) if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') self.setcontents(path, b('')) handler = NullFile() else: self._log(DEBUG, 'Opening existing file %s for reading' % path) handler = self.getrange(path,0) return RemoteFileBuffer(self, path, mode, handler, write_on_flush=False)
def setcontents(self, path, file, chunk_size=64 * 1024): self._log(INFO, 'Uploading file %s' % path) size = None if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') # Workaround for large files: # First create zero file placeholder, then # upload final content. if self.largefilesize != None and getattr(file, 'read', None): # As 'file' can be also a string, need to check, # if 'file' looks like duck. Sorry, file. file.seek(0, SEEK_END) size = file.tell() file.seek(0) if size > self.largefilesize: self.connection.put( u'/uri/%s%s' % (self.dircap, path), "PyFilesystem.TahoeLAFS: Upload started, final size %d" % size) self.connection.put(u'/uri/%s%s' % (self.dircap, path), file, size=size)
def move(self, src, dst, overwrite=False): self._log(INFO, "Moving file from %s to %s" % (src, dst)) if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') src = _fixpath(src) dst = _fixpath(dst) if not self.exists(dirname(dst)): raise errors.ParentDirectoryMissingError(dst) if not overwrite and self.exists(dst): raise errors.DestinationExistsError(dst) self.tahoeutil.move(self.dircap, src, dst)
def copydir(self, src, dst, overwrite=False, ignore_errors=False, chunk_size=16384): if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') # FIXME: this is out of date; how to do native tahoe copy? # FIXME: Workaround because isfile() not exists on _TahoeLAFS FS.copydir(self, src, dst, overwrite, ignore_errors, chunk_size)
def makedir(self, path, recursive=False, allow_recreate=False): self._log(INFO, "Creating directory %s" % path) if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') if self.exists(path): if not self.isdir(path): raise errors.ResourceInvalidError(path) if not allow_recreate: raise errors.DestinationExistsError(path) if not recursive and not self.exists(dirname(path)): raise errors.ParentDirectoryMissingError(path) self.tahoeutil.mkdir(self.dircap, path)
def remove(self, path): self._log(INFO, 'Removing file %s' % path) if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') if not self.isfile(path): if not self.isdir(path): raise errors.ResourceNotFoundError(path) raise errors.ResourceInvalidError(path) try: self.tahoeutil.unlink(self.dircap, path) except Exception, e: raise errors.ResourceInvalidError(path)
def removedir(self, path, recursive=False, force=False): self._log(INFO, "Removing directory %s" % path) if self.getmeta("read_only"): raise errors.UnsupportedError('read only filesystem') if not self.isdir(path): if not self.isfile(path): raise errors.ResourceNotFoundError(path) raise errors.ResourceInvalidError(path) if not force and self.listdir(path): raise errors.DirectoryNotEmptyError(path) self.tahoeutil.unlink(self.dircap, path) if recursive and path != '/': try: self.removedir(dirname(path), recursive=True) except errors.DirectoryNotEmptyError: pass
def _get_headers(self, f, size=None): ''' Retrieve length of string or file object and prepare HTTP headers. ''' if isinstance(f, basestring): # Just set up content length size = len(f) elif getattr(f, 'read', None): if size == None: # When size is already known, skip this f.seek(0, SEEK_END) size = f.tell() f.seek(0) else: raise errors.UnsupportedError("Cannot handle type %s" % type(f)) headers = {'Content-Length': size} headers.update(self.headers) return headers
def move(self, dircap, src, dst): if src == '/' or dst == '/': raise errors.UnsupportedError("Too dangerous operation, aborting") src = self.fixwinpath(src, False) dst = self.fixwinpath(dst, False) src_tuple = pathsplit(src) dst_tuple = pathsplit(dst) if src_tuple[0] == dst_tuple[0]: # Move inside one directory self.connection.post("/uri/%s%s" % (dircap, src_tuple[0]), data={ 't': 'rename', 'from_name': src_tuple[1], 'to_name': dst_tuple[1] }) return # Move to different directory. Firstly create link on dst, then remove from src try: self.info(dircap, dst) except errors.ResourceNotFoundError: pass else: self.unlink(dircap, dst) uri = self.info(dircap, src)['uri'] self.connection.put("/uri/%s%s" % (dircap, dst), data=uri, params={'t': 'uri'}) if uri != self.info(dircap, dst)['uri']: raise errors.OperationFailedError('Move failed') self.unlink(dircap, src)