async def browse_file(self, path): """ Download file """ with suppress_fs_exceptions(): if not self.home.isfile(path): raise FileExpected(path) path = self.home.getospath(path).decode('utf-8') return FileResponse(path)
def openbin(self, path: str, mode: str = "r", buffering: int = -1, **options): """Open file from filesystem. :param path: Path to file on filesystem :param mode: Mode to open file in :param buffering: TBD returns: `BinaryIO` stream """ path = self.validatepath(path) if 'w' in mode: self.create(path) try: info = self.getinfo(path) except ResourceNotFound: raise ResourceNotFound(path) else: if info.is_dir: raise FileExpected(path) return FatIO(self.fs, path, mode)
def openbin(self, path: str, mode: str = "r", buffering: int = -1, **options): """Open file from filesystem. :param path: Path to file on filesystem :param mode: Mode to open file in :param buffering: TBD returns: `BinaryIO` stream """ path = self.validatepath(path) mode = Mode(mode + 'b') if mode.create: if mode.exclusive: try: self.getinfo(path) except ResourceNotFound: pass else: raise FileExists(path) self.create(path) if "t" in mode: raise ValueError('Text-mode not allowed in openbin') try: info = self.getinfo(path) except ResourceNotFound: raise ResourceNotFound(path) else: if info.is_dir: raise FileExpected(path) return FatIO(self.fs, path, mode)
def openbin(self, path, mode='r', buffering=-1, **options): _log.info(f'openbin({path}, {mode}, {buffering}, {options})') path = self.validatepath(path) with self._lock: parsedMode = Mode(mode) idsFromPath = self._itemsFromPath(path) item = idsFromPath.get(path) if parsedMode.exclusive and item is not None: raise FileExists(path) if parsedMode.reading and not parsedMode.create and item is None: raise ResourceNotFound(path) if item is not None and item['mimeType'] == _folderMimeType: raise FileExpected(path) parentDir = dirname(path) _log.debug( f'looking up id for {parentDir} in {list(idsFromPath.keys())}') parentDirItem = idsFromPath.get(parentDir) # make sure that the parent directory exists if we're writing if parsedMode.writing and parentDirItem is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, thisMetadata=item, parentMetadata=parentDirItem, parsedMode=parsedMode, **options)
def openbin(self, path, mode="r", buffering=-1, **options): # pylint: disable=unused-argument _CheckPath(path) with self._lock: _log.info(f"openbin: {path}, {mode}, {buffering}") parsedMode = Mode(mode) idsFromPath = self._itemsFromPath(path) item = idsFromPath.get(path) if parsedMode.exclusive and item is not None: raise FileExists(path) if parsedMode.reading and not parsedMode.create and item is None: raise ResourceNotFound(path) if item is not None and item["mimeType"] == _folderMimeType: raise FileExpected(path) parentDir = dirname(path) _log.debug(f"looking up id for {parentDir}") parentDirItem = idsFromPath.get(parentDir) # make sure that the parent directory exists if we're writing if parsedMode.writing and parentDirItem is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, thisMetadata=item, parentMetadata=parentDirItem, parsedMode=parsedMode, **options)
def copy(self, src_path, dst_path, overwrite=False): info(f"copy: {src_path} -> {dst_path}, {overwrite}") _CheckPath(src_path) _CheckPath(dst_path) with self._lock: parentDir = dirname(dst_path) parentDirItem = self._itemFromPath(parentDir) if parentDirItem is None: raise ResourceNotFound(parentDir) dstItem = self._itemFromPath(dst_path) if overwrite is False and dstItem is not None: raise DestinationExists(dst_path) srcItem = self._itemFromPath(src_path) if srcItem is None: raise ResourceNotFound(src_path) if srcItem["mimeType"] == _folderMimeType: raise FileExpected(src_path) # TODO - we should really replace the contents of the existing file with the new contents, so that the history is correct if dstItem is not None: self.drive.files().delete(fileId=dstItem["id"]).execute(num_retries=self.retryCount) newMetadata = {"parents": [parentDirItem["id"]], "name": basename(dst_path)} self.drive.files().copy(fileId=srcItem["id"], body=newMetadata).execute(num_retries=self.retryCount)
def add_shortcut(self, shortcut_path, target_path): _log.info(f"add_shortcut: {shortcut_path}, {target_path}") _CheckPath(shortcut_path) _CheckPath(target_path) with self._lock: idsFromTargetPath = self._itemsFromPath(target_path) if target_path not in idsFromTargetPath: raise ResourceNotFound(path=target_path) targetItem = idsFromTargetPath[target_path] if targetItem["mimeType"] == _folderMimeType: raise FileExpected(target_path) idsFromShortcutPath = self._itemsFromPath(shortcut_path) if shortcut_path in idsFromShortcutPath: raise DestinationExists(shortcut_path) shortcutParentDir, shortcutName = split(shortcut_path) shortcutParentDirItem = idsFromShortcutPath.get(shortcutParentDir) if shortcutParentDirItem is None: raise ResourceNotFound(shortcutParentDir) metadata = { "name": shortcutName, "parents": [shortcutParentDirItem["id"]], "mimeType": _shortcutMimeType, "shortcutDetails": { "targetId": targetItem["id"] }, "enforceSingleParent": self.enforceSingleParent } _ = self.drive.files().create(body=metadata, fields="id").execute(num_retries=self.retryCount)
def openbin(self, path, mode="r", buffering=-1, **options): _CheckPath(path) with self._lock: if "t" in mode: raise ValueError("Text mode is not allowed in openbin") parsedMode = Mode(mode) exists = self.exists(path) if parsedMode.exclusive and exists: raise FileExists(path) if parsedMode.reading and not parsedMode.create and not exists: raise ResourceNotFound(path) if self.isdir(path): raise FileExpected(path) if parsedMode.writing: # make sure that the parent directory exists parentDir = dirname(path) response = self.session.get(_PathUrl(parentDir, "")) if response.status_code == 404: raise ResourceNotFound(parentDir) response.raise_for_status() itemId = None if exists: response = self.session.get(_PathUrl(path, "")) response.raise_for_status() itemId = response.json()["id"] return _UploadOnClose(session=self.session, path=path, itemId=itemId, mode=parsedMode)
def openbin(self, path, mode="r", buffering=-1, **options): parsedMode = Mode(mode) if parsedMode.exclusive and self.exists(path): raise FileExists(path) elif parsedMode.reading and not parsedMode.create and not self.exists(path): raise ResourceNotFound(path) elif self.isdir(path): raise FileExpected(path) return UploadOnClose(client=self.client, path=path, mode=parsedMode)
def remove(self, path): _CheckPath(path) with self._lock: info(f"remove: {path}") metadata = self._itemFromPath(path) if metadata is None: raise ResourceNotFound(path=path) if metadata["mimeType"] == _folderMimeType: raise FileExpected(path=path) self.drive.files().delete(fileId=metadata["id"]).execute()
def remove(self, path): _CheckPath(path) with self._lock: response = self.session.get(_PathUrl(path, "")) if response.status_code == 404: raise ResourceNotFound(path) response.raise_for_status() itemData = response.json() if "folder" in itemData: raise FileExpected(path=path) response = self.session.delete(_PathUrl(path, "")) response.raise_for_status()
def move(self, src_path, dst_path, overwrite=False): _CheckPath(src_path) _CheckPath(dst_path) with self._lock: if not overwrite and self.exists(dst_path): raise DestinationExists(dst_path) driveItemResponse = self.session.get(_PathUrl(src_path, "")) if driveItemResponse.status_code == 404: raise ResourceNotFound(src_path) driveItemResponse.raise_for_status() driveItem = driveItemResponse.json() if "folder" in driveItem: raise FileExpected(src_path) itemUpdate = {} newFilename = basename(dst_path) if not self.isdir(dst_path) and newFilename != basename(src_path): itemUpdate["name"] = newFilename parentDir = dirname(dst_path) if parentDir != dirname(src_path): parentDirItem = self.session.get(_PathUrl(parentDir, "")) if parentDirItem.status_code == 404: raise ResourceNotFound(parentDir) parentDirItem.raise_for_status() itemUpdate["parentReference"] = { "id": parentDirItem.json()["id"] } itemId = driveItem["id"] response = self.session.patch(_ItemUrl(itemId, ""), json=itemUpdate) if response.status_code == 409 and overwrite is True: # delete the existing version and then try again response = self.session.delete(_PathUrl(dst_path, "")) response.raise_for_status() # try again response = self.session.patch(_ItemUrl(itemId, ""), json=itemUpdate) response.raise_for_status() return if response.status_code == 409 and overwrite is False: debug( "Retrying move in case it's an erroneous error (see issue #7)" ) response = self.session.patch(_ItemUrl(itemId, ""), json=itemUpdate) response.raise_for_status() return response.raise_for_status()
def remove(self, path): if path == '/': raise RemoveRootError() _CheckPath(path) with self._lock: _log.info(f"remove: {path}") metadata = self._itemFromPath(path) if metadata is None: raise ResourceNotFound(path=path) if metadata["mimeType"] == _folderMimeType: raise FileExpected(path=path) self.drive.files().delete(fileId=metadata["id"]).execute(num_retries=self.retryCount)
def remove(self, path: str): """Remove a file from the filesystem. :param path: `str`: Path of file to remove """ dir_entry = self._get_dir_entry(path) # Check for file if dir_entry.is_directory() or dir_entry.is_special(): raise FileExpected(path) base = dir_entry.get_parent_dir() self._remove(base, dir_entry)
def openbin(self, path, mode="r", buffering=-1, **options): _mode = Mode(mode) _mode.validate_bin() self.check() _path = self.validatepath(path) if _path == "/": raise FileExpected(path) with convert_os_errors("openbin", path): fd = self._fs.open(_path, os.O_RDONLY) fdict = self._fs.openFiles[path] self._fs._ensure_region_available(path, fdict, fd, 0, fdict["obj"]["size"]) return open(fdict["path"], "r+b")
def copy(self, src_path, dst_path, overwrite=False): _CheckPath(src_path) _CheckPath(dst_path) with self._lock: if not overwrite and self.exists(dst_path): raise DestinationExists(dst_path) driveItemResponse = self.session.get(_PathUrl(src_path, "")) if driveItemResponse.status_code == 404: raise ResourceNotFound(src_path) driveItemResponse.raise_for_status() driveItem = driveItemResponse.json() if "folder" in driveItem: raise FileExpected(src_path) newParentDir = dirname(dst_path) newFilename = basename(dst_path) parentDirResponse = self.session.get(_PathUrl(newParentDir, "")) if parentDirResponse.status_code == 404: raise ResourceNotFound(src_path) parentDirResponse.raise_for_status() parentDirItem = parentDirResponse.json() # This just asynchronously starts the copy response = self.session.post( _ItemUrl(driveItem["id"], "/copy"), json={ "parentReference": { "driveId": parentDirItem["parentReference"]["driveId"], "id": parentDirItem["id"] }, "name": newFilename }) response.raise_for_status() assert response.status_code == 202, "Response code should be 202 (Accepted)" monitorUri = response.headers["Location"] while True: # monitor uris don't require authentication # (https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/long-running-actions?view=odsp-graph-online) jobStatusResponse = get(monitorUri) jobStatusResponse.raise_for_status() jobStatus = jobStatusResponse.json() assert jobStatus[ "operation"] == "ItemCopy", f"Unexpected status: {jobStatus}" assert jobStatus["status"] in [ "inProgress", "completed", "notStarted" ], f"Unexpected status: {jobStatus}" if jobStatus["status"] == "completed": break
def move(self, src_path, dst_path, overwrite=False, preserve_time=False): _log.info( f'move({src_path}, {dst_path}, {overwrite}, {preserve_time})') src_path = self.validatepath(src_path) dst_path = self.validatepath(dst_path) with self._lock: dstItem = self._itemFromPath(dst_path) if overwrite is False and dstItem is not None: raise DestinationExists(dst_path) srcParentItem = self._itemFromPath(dirname(src_path)) if srcParentItem is None: raise ResourceNotFound(src_path) # TODO - it would be more efficient to go directly from srcParentItem to it's child here srcItem = self._itemFromPath(src_path) if srcItem is None: raise ResourceNotFound(src_path) if srcItem['mimeType'] == _folderMimeType: raise FileExpected(src_path) dstParentDir = dirname(dst_path) dstParentDirItem = self._itemFromPath(dstParentDir) if dstParentDirItem is None: raise ResourceNotFound(dstParentDir) if dstItem is not None: assert overwrite is True self._drive.files().delete( fileId=dstItem['id'], **self._file_kwargs, ).execute(num_retries=self.retryCount) metadata = { 'name': basename(dst_path), 'enforceSingleParent': True } if preserve_time is True: metadata['modifiedTime'] = srcItem['modifiedTime'] self._drive.files().update( fileId=srcItem['id'], addParents=dstParentDirItem['id'], removeParents=srcParentItem['id'], body=metadata, **self._file_kwargs, ).execute(num_retries=self.retryCount)
def remove(self, path): _log.info(f'remove({path})') path = self.validatepath(path) if path == '/': raise RemoveRootError() with self._lock: metadata = self._itemFromPath(path) if metadata is None: raise ResourceNotFound(path=path) if metadata['mimeType'] == _folderMimeType: raise FileExpected(path=path) self._drive.files().delete( fileId=metadata['id'], **self._file_kwargs, ).execute(num_retries=self.retryCount)
def openbin(self, path, mode="r", buffering=-1, **options): mode = Mode(mode) exists = True isDir = False try: isDir = self.getinfo(path).is_dir except ResourceNotFound: exists = False if mode.exclusive and exists: raise FileExists(path) elif mode.reading and not mode.create and not exists: raise ResourceNotFound(path) elif isDir: raise FileExpected(path) return DropboxFile(self.dropbox, path, mode)
def openbin(self, path, mode="r", buffering=-1, **options): # pylint: disable=unused-argument _CheckPath(path) with self._lock: info(f"openbin: {path}, {mode}, {buffering}") parsedMode = Mode(mode) exists = self.exists(path) if parsedMode.exclusive and exists: raise FileExists(path) elif parsedMode.reading and not parsedMode.create and not exists: raise ResourceNotFound(path) elif self.isdir(path): raise FileExpected(path) if parsedMode.writing: # make sure that the parent directory exists parentDir = dirname(path) if self._itemFromPath(parentDir) is None: raise ResourceNotFound(parentDir) return _UploadOnClose(fs=self, path=path, parsedMode=parsedMode)
def copy(self, src_path, dst_path, overwrite=False, preserve_time=False): _log.info( f'copy({src_path}, {dst_path}, {overwrite}, {preserve_time})') src_path = self.validatepath(src_path) dst_path = self.validatepath(dst_path) with self._lock: parentDir = dirname(dst_path) parentDirItem = self._itemFromPath(parentDir) if parentDirItem is None: raise ResourceNotFound(parentDir) dstItem = self._itemFromPath(dst_path) if overwrite is False and dstItem is not None: raise DestinationExists(dst_path) srcItem = self._itemFromPath(src_path) if srcItem is None: raise ResourceNotFound(src_path) if srcItem['mimeType'] == _folderMimeType: raise FileExpected(src_path) # TODO - we should really replace the contents of the existing file with the new contents, so that the history is correct if dstItem is not None: self._drive.files().delete( fileId=dstItem['id'], **self._file_kwargs, ).execute(num_retries=self.retryCount) newMetadata = { 'parents': [parentDirItem['id']], 'name': basename(dst_path), 'enforceSingleParent': True } if preserve_time is True: newMetadata['modifiedTime'] = srcItem['modifiedTime'] self._drive.files().copy( fileId=srcItem['id'], body=newMetadata, **self._file_kwargs, ).execute(num_retries=self.retryCount)
def remove(self, path: str) -> None: """Remove a file from the filesystem. Arguments: path (str): Path of the file to remove. Raises: fs.errors.FileExpected: If the path is a directory. fs.errors.ResourceNotFound: If the path does not exist. """ full_path = self._make_full_path(path) if self._get_type(path) != ResourceType.file: raise FileExpected(full_path) try: self._delete_object(path) except ClientException as e: if e.http_status == 404: raise ResourceNotFound(full_path)
def openbin( self, path: str, mode: str = "r", buffering: int = -1, **options: Any ) -> BinaryIO: path = self.validatepath(path) info = self.getinfo(path) if not info.is_file: raise FileExpected(path) if "w" in mode: raise Unsupported(msg="cannot modify pyfs") if "x" in mode: raise Unsupported(msg="cannot get exclusive control of resource") _, resource = self._get_file_at_path(path) return BytesIO( bytes( cast(Scope, resource).get_code( include_prefix=self._include_prefix ), encoding="utf-8", ) )
def add_shortcut(self, shortcut_path, target_path): _log.info(f'add_shortcut({shortcut_path}, {target_path})') shortcut_path = self.validatepath(shortcut_path) target_path = self.validatepath(target_path) with self._lock: idsFromTargetPath = self._itemsFromPath(target_path) if target_path not in idsFromTargetPath: raise ResourceNotFound(path=target_path) targetItem = idsFromTargetPath[target_path] if targetItem['mimeType'] == _folderMimeType: raise FileExpected(target_path) idsFromShortcutPath = self._itemsFromPath(shortcut_path) if shortcut_path in idsFromShortcutPath: raise DestinationExists(shortcut_path) shortcutParentDir, shortcutName = split(shortcut_path) shortcutParentDirItem = idsFromShortcutPath.get(shortcutParentDir) if shortcutParentDirItem is None: raise ResourceNotFound(shortcutParentDir) metadata = { 'name': shortcutName, 'parents': [shortcutParentDirItem['id']], 'mimeType': _shortcutMimeType, 'shortcutDetails': { 'targetId': targetItem['id'] }, 'enforceSingleParent': True } _ = self._drive.files().create( body=metadata, fields='id', **self._file_kwargs, ).execute(num_retries=self.retryCount)
def move(self, src_path, dst_path, overwrite=False): _log.info(f"move: {src_path} -> {dst_path}, {overwrite}") _CheckPath(src_path) _CheckPath(dst_path) with self._lock: dstItem = self._itemFromPath(dst_path) if overwrite is False and dstItem is not None: raise DestinationExists(dst_path) srcParentItem = self._itemFromPath(dirname(src_path)) if srcParentItem is None: raise ResourceNotFound(src_path) # TODO - it would be more efficient to go directly from srcParentItem to it's child here srcItem = self._itemFromPath(src_path) if srcItem is None: raise ResourceNotFound(src_path) if srcItem["mimeType"] == _folderMimeType: raise FileExpected(src_path) dstParentDir = dirname(dst_path) dstParentDirItem = self._itemFromPath(dstParentDir) if dstParentDirItem is None: raise ResourceNotFound(dstParentDir) if dstItem is not None: assert overwrite is True self.drive.files().delete(fileId=dstItem["id"]).execute( num_retries=self.retryCount) self.drive.files().update(fileId=srcItem["id"], addParents=dstParentDirItem["id"], removeParents=srcParentItem["id"], body={ "name": basename(dst_path) }).execute(num_retries=self.retryCount)
def remove(self, path): try: self.dropbox.files_delete(path) except ApiError as e: raise FileExpected(path=path, exc=e)
def remove(self, path): itemRequest = self.client.item(path=path) if itemRequest.get().folder is not None: raise FileExpected(path=path) itemRequest.delete()
def remove(self, path): metadata = self._itemFromPath(path) if metadata is None: raise FileExpected(path=path) self.drive.files().delete(fileId=metadata["id"]).execute()