def build_ui_caps(self): dirr = self.dirr with OSFS(dirr) as f: data = make_temp_fs(f) self.vfs = data capsmap = {} vfs = self.vfs # vfs.tree() for path, _, files in vfs.walk(): for i in files: dd = {} nn = i.name pp = rename(nn) dd['fixname'] = nn dd['cap'] = pp.episode dd['season'] = pp.season opth = vfs.gettext(join(path, nn)) oon = split(opth)[1] dd['original'] = oon dd['ext'] = pp.ext.lower() dd['vpath'] = join(path, nn) dd['state'] = True dd['fold'] = split(path)[1] capsmap[oon] = dd self.capsmap = capsmap nonly = self.move.checkedId() == 3 li = self.li lic = li.count() cps = list(capsmap.values()) cpl = len(cps) if cpl <= lic: for n, i in enumerate(cps): name = i['fixname'] if nonly: name = i['cap'] + i['ext'] ll = li.item(n) ll.setText(name + "\t" + i['original']) for i in range(lic - cpl): ll = li.takeItem(0) del ll else: for i in range(lic): name = cps[i]['fixname'] if nonly: name = i['cap'] + i['ext'] ll = li.item(i) ll.setText(name + "\t" + cps[i]['original']) for i in range(cpl - lic): name = cps[lic + i]['fixname'] if nonly: name = i['cap'] + i['ext'] li.addItem(name + "\t" + cps[lic + i]['original'])
def copy(self, src_path, dst_path, overwrite=False): # type: (Text, Text, bool) -> None """Copy file contents from ``src_path`` to ``dst_path``. Arguments: src_path (str): Path of source file. dst_path (str): Path to destination file. overwrite (bool): If `True`, overwrite the destination file if it exists (defaults to `False`). Raises: fs.errors.DestinationExists: If ``dst_path`` exists, and ``overwrite`` is `False`. fs.errors.ResourceNotFound: If a parent directory of ``dst_path`` does not exist. """ _src_path = self.validatepath(src_path) _dst_path = self.validatepath(dst_path) with self._lock: if not overwrite and self.exists(dst_path): raise errors.DestinationExists(dst_path) dir_path, file_name = split(_dst_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.is_collection: raise errors.ResourceNotFound(dst_path) _src_res = self._getresource(src_path) if not _src_res: raise errors.ResourceNotFound(src_path) if _src_res.is_collection: raise errors.FileExpected(src_path) _src_res.copy_move_single(_dst_path, False)
def _get_directory(self, path, content, format, *, type=None): self.log.debug('_get_directory(%s)', path) path = self.fs.validatepath(path) d = self.fs.getdetails(path) if not d.is_dir: raise HTTPError(404, '"%s" not a directory', path) model = _base_model(*fspath.split(path)) model['type'] = 'directory' model['size'] = None model['format'] = None model['created'], model['last_modified'] = _created_modified(d) if content: model['content'] = [] model['format'] = 'json' for item in self.fs.scandir(path, ['basic', 'details']): child_path = fspath.join(path, item.name) if item.is_dir: model['content'].append( self._get_directory(child_path, False, None)) if item.is_file: model['content'].append( self._get_file(child_path, False, format)) return model
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 writebytes(self, path, contents): # type: (Text, bytes) -> None # FIXME(@althonos): accept bytearray and memoryview as well ? """Copy binary data to a file. Arguments: path (str): Destination path on the filesystem. contents (bytes): Data to be written. Raises: TypeError: if contents is not bytes. """ if not isinstance(contents, bytes): raise TypeError("contents must be bytes") with self._lock: _res = self._getresource(path) if _res: if not _res.isfile(): raise errors.FileExpected(path) _res.truncate(0) else: _path = self.validatepath(path) dir_path, file_name = split(_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.isdir(): raise errors.ResourceNotFound(path) _res = fire_fs.mkfile(self._prep_path(_path)) _res.put_content(contents)
def create_notebook_checkpoint(self, nb, path): self.log.debug('create_notebook_checkpoint(%s)', path) cp_path = self._checkpoint_path(0, path) self._ensure_checkpoint_dir(cp_path) model = _base_model(*fspath.split(cp_path)) model['content'] = nb f = self.parent._save_notebook(cp_path, model, False) return self._checkpoint_model(0, f)
def create_file_checkpoint(self, content, format, path): self.log.debug('create_file_checkpoint(%s)', path) cp_path = self._checkpoint_path(0, path) self._ensure_checkpoint_dir(cp_path) model = _base_model(*fspath.split(cp_path)) model['content'] = content model['format'] = format f = self.parent._save_file(cp_path, model) return self._checkpoint_model(0, f)
def _file_model(self, path, f, content, format): model = _base_model(*fspath.split(path)) model['type'] = self.guess_type(path) model['created'], model['last_modified'] = _created_modified(f) model['size'] = f.size if content: model['content'], model['format'] = self._read_file(path, format) model['mimetype'] = mimetypes.guess_type(model['path'])[0] return model
def _checkpoint_path(self, checkpoint_id, path): """find the path to a checkpoint""" path = self.parent.fs.validatepath(path) parent, name = fspath.split(path) basename, ext = fspath.splitext(name) cp_path = fspath.join( parent, self.checkpoint_dir, self.checkpoint_template.format(basename=basename, id=checkpoint_id, ext=ext)) return cp_path
def makedir( self, path, # type: Text permissions=None, # type: Optional[Permissions] recreate=False, # type: bool ): # type: (...) -> SubFS[FS] """Make a directory. Arguments: path (str): Path to directory from root. permissions (~fs.permissions.Permissions, optional): a `Permissions` instance, or `None` to use default. recreate (bool): Set to `True` to avoid raising an error if the directory already exists (defaults to `False`). Returns: ~fs.subfs.SubFS: a filesystem whose root is the new directory. Raises: fs.errors.DirectoryExists: If the path already exists. fs.errors.ResourceNotFound: If the path is not found. """ # mode = Permissions.get_mode(permissions) _path = self.validatepath(path) with self._lock: if _path == "/": if recreate: return self.opendir(path) else: raise errors.DirectoryExists(path) if _path.endswith("/"): _path = _path[:-1] dir_path, dir_name = split(_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.is_collection: raise errors.ResourceNotFound(path) if dir_name in _dir_res.get_member_names(): if not recreate: raise errors.DirectoryExists(path) _res = self._getresource(path) if _res and _res.is_collection: return self.opendir(path) _dir_res.create_collection(dir_name) return self.opendir(path)
def test_pathsplit(self): tests = [ ("a/b", ("a", "b")), ("a/b/c", ("a/b", "c")), ("a", ("", "a")), ("", ("", "")), ("/", ("/", "")), ("/foo", ("/", "foo")), ("foo/bar", ("foo", "bar")), ("foo/bar/baz", ("foo/bar", "baz")), ] for path, result in tests: self.assertEqual(split(path), result)
def upload(self, path, file, chunk_size=None, **options): # type: (Text, BinaryIO, Optional[int], **Any) -> None """Set a file to the contents of a binary file object. This method copies bytes from an open binary file to a file on the filesystem. If the destination exists, it will first be truncated. Arguments: path (str): A path on the filesystem. file (io.IOBase): a file object open for reading in binary mode. chunk_size (int, optional): Number of bytes to read at a time, if a simple copy is used, or `None` to use sensible default. **options: Implementation specific options required to open the source file. Note that the file object ``file`` will *not* be closed by this method. Take care to close it after this method completes (ideally with a context manager). Example: >>> with open('~/movies/starwars.mov', 'rb') as read_file: ... my_fs.upload('starwars.mov', read_file) """ with self._lock: _res = self._getresource(path) if _res: if not _res.isfile(): raise errors.FileExpected(path) _res.truncate(0) else: _path = self.validatepath(path) dir_path, file_name = split(_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.isdir(): raise errors.ResourceNotFound(path) _res = fire_fs.mkfile(self._prep_path(_path)) # Note: we always read in chunks here, regardless of the chunk_size _res.upload(file)
def move(self, src_path, dst_path, overwrite=False): # type: (Text, Text, bool) -> None """Move a file from ``src_path`` to ``dst_path``. Arguments: src_path (str): A path on the filesystem to move. dst_path (str): A path on the filesystem where the source file will be written to. overwrite (bool): If `True`, destination path will be overwritten if it exists. Raises: fs.errors.FileExpected: If ``src_path`` maps to a directory instead of a file. fs.errors.DestinationExists: If ``dst_path`` exists, and ``overwrite`` is `False`. fs.errors.ResourceNotFound: If a parent directory of ``dst_path`` does not exist. """ _src_path = self.validatepath(src_path) _dst_path = self.validatepath(dst_path) with self._lock: if not overwrite and self.exists(dst_path): raise errors.DestinationExists(dst_path) dir_path, file_name = split(_dst_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.is_collection: raise errors.ResourceNotFound(dst_path) _src_res = self._getresource(src_path) if not _src_res: raise errors.ResourceNotFound(src_path) if _src_res.is_collection: raise errors.FileExpected(src_path) if not overwrite and _src_res.support_recursive_move(_dst_path): _src_res.move_recursive(_dst_path) else: # CHECKME: this doesn't actually seem to delete _src_res in DAV Provider _src_res.copy_move_single(_dst_path, True) try: _src_res.delete() except: pass
def is_in_wallet(fpath): """ Checks whether a specified path points to a document in the wallet. This function only checks whether the path is within the :data:`tendril.utils.config.DOCUMENT_WALLET_ROOT`, and not whether the document is defined in the :data:`tendril.utils.config.DOCUMENT_WALLET` dictionary. The intended use of this function is alongside PDF merge operations after which the sources are deleted. Documents in the wallet should not be deleted. Code performing the deletion can use this function to check whether the document is in the wallet. :param fpath: The path to the file. :return: True if the document is in the wallet, False if not. """ if DOCUMENT_WALLET_ROOT in path.split(fpath)[0]: return True
def _renamef(self, path): with OSFS(path) as ff: for data in self.capsmap.values(): if not data['state']: continue if data['fixname'] == data['original']: continue path = '/' path2 = join(path, data['fixname']) opth = join(path, data['original']) self.loggin.emit( "Renombrando: " + data['original'] + ' a ' + data['fixname'], INFORMATION) try: ff.move(opth, path2, overwrite=True) except Exception as e: self.loggin.emit("Error en archivo: " + split(opth)[1] + '<br>' + str(e), ERROR) self.loggin.emit("Renombrar finalizado.", DEBUG) self.build_ui_caps() self.allf()
def edititem(self, item): cpsm = self.capsmap txt = item.text().split("\t") text, ok = QInputDialog.getText(None, "Editar", "Nombre:", QLineEdit.Normal, txt[0]) if ok and text != '' and not(text is None): if text == txt[0]: return pth = cpsm[txt[1]]['vpath'] pth2 = join(split(pth)[0], text) try: self.vfs.move(pth, pth2) except fs.errors.DestinationExists: self.loggin.emit( 'Ya existe otro fichero que tiene este posible nombre', ERROR) return cpsm[txt[1]]['vpath'] = pth2 cpsm[txt[1]]['fixname'] = text item.setText(text + '\t' + txt[1]) item.setCheckState(Qt.Checked) cpsm[txt[1]]['state'] = True
def create(self, path, wipe=False): # type: (Text, bool) -> bool """Create an empty file. The default behavior is to create a new file if one doesn't already exist. If ``wipe`` is `True`, any existing file will be truncated. Arguments: path (str): Path to a new file in the filesystem. wipe (bool): If `True`, truncate any existing file to 0 bytes (defaults to `False`). Returns: bool: `True` if a new file had to be created. """ with self._lock: _res = self._getresource(path) if _res: if _res.is_collection: raise errors.FileExpected(path) if not wipe: return False fp = _res.begin_write() fp.close() else: _path = self.validatepath(path) dir_path, file_name = split(_path) _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.is_collection: raise errors.ResourceNotFound(path) _res = _dir_res.create_empty_resource(file_name) return True
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 openbin( self, path, # type: Text mode="r", # type: Text buffering=-1, # type: int **options # type: Any ): # type: (...) -> BinaryIO """Open a binary file-like object. Arguments: path (str): A path on the filesystem. mode (str): Mode to open file (must be a valid non-text mode, defaults to *r*). Since this method only opens binary files, the ``b`` in the mode string is implied. buffering (int): Buffering policy (-1 to use default buffering, 0 to disable buffering, or any positive integer to indicate a buffer size). **options: keyword arguments for any additional information required by the filesystem (if any). Returns: io.IOBase: a *file-like* object. Raises: fs.errors.FileExpected: If the path is not a file. fs.errors.FileExists: If the file exists, and *exclusive mode* is specified (``x`` in the mode). fs.errors.ResourceNotFound: If the path does not exist. """ _mode = Mode(mode) _mode.validate_bin() _path = self.validatepath(path) dir_path, file_name = split(_path) if not file_name: raise errors.FileExpected(path) with self._lock: _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.is_collection: raise errors.ResourceNotFound(path) if _mode.create: if file_name in _dir_res.get_member_names(): if _mode.exclusive: raise errors.FileExists(path) _res = self._getresource(path) if not _res or _res.is_collection: raise errors.FileExpected(path) stream = io.BufferedWriter(_res.begin_write()) io_object = RawWrapper(stream, mode=mode, name=path) return io_object _res = _dir_res.create_empty_resource(file_name) stream = io.BufferedWriter(_res.begin_write()) io_object = RawWrapper(stream, mode=mode, name=path) return io_object if file_name not in _dir_res.get_member_names(): raise errors.ResourceNotFound(path) _res = self._getresource(path) if not _res or _res.is_collection: raise errors.FileExpected(path) if _mode.appending: # stream.seek(0, 2) # io.SEEK_END raise NotImplementedError("Appending is not supported") if _mode.updating: raise NotImplementedError("Updating is not supported") if _mode.reading: stream = io.BufferedReader(_res.get_content()) io_object = RawWrapper(stream, mode=mode, name=path) return io_object stream = io.BufferedWriter(_res.begin_write()) io_object = RawWrapper(stream, mode=mode, name=path) return io_object
def _ensure_checkpoint_dir(self, cp_path): dirname, basename = fspath.split(cp_path) if not self.parent.dir_exists(dirname): self.parent._save_directory(dirname, None)
def filename(self): return path.splitext(path.split(self.path)[1])[0]
def openbin( self, path, # type: Text mode="r", # type: Text buffering=-1, # type: int **options # type: Any ): # type: (...) -> BinaryIO """Open a binary file-like object. Arguments: path (str): A path on the filesystem. mode (str): Mode to open file (must be a valid non-text mode, defaults to *r*). Since this method only opens binary files, the ``b`` in the mode string is implied. buffering (int): Buffering policy (-1 to use default buffering, 0 to disable buffering, or any positive integer to indicate a buffer size). **options: keyword arguments for any additional information required by the filesystem (if any). Returns: io.IOBase: a *file-like* object. Raises: fs.errors.FileExpected: If the path is not a file. fs.errors.FileExists: If the file exists, and *exclusive mode* is specified (``x`` in the mode). fs.errors.ResourceNotFound: If the path does not exist. """ _mode = Mode(mode) _mode.validate_bin() _path = self.validatepath(path) dir_path, file_name = split(_path) if not file_name: raise errors.FileExpected(path) with self._lock: _dir_res = self._getresource(dir_path) if not _dir_res or not _dir_res.isdir(): raise errors.ResourceNotFound(path) if _mode.create: if file_name in _dir_res.listdir(): if _mode.exclusive: raise errors.FileExists(path) _res = self._getresource(path) if not _res or not _res.isfile(): raise errors.FileExpected(path) return self._btopen(_res, mode) return self._btopen(self._prep_path(_path), mode) if file_name not in _dir_res.listdir(): raise errors.ResourceNotFound(path) _res = self._getresource(path) if not _res or not _res.isfile(): raise errors.FileExpected(path) return self._btopen(_res, mode)
def pathsplit(self, context, v): return split(normpath(text_type(v)))
def check_path(path): dirname, filename = split(path) return filename not in [".svn", ".hg"]
def makedir(self, path: str, permissions: Permissions = None, recreate: bool = False): """Create directory on filesystem. :param path: Path of new directory on filesystem :param permissions: Currently not implemented :param recreate: Ignore if directory already exists """ path = normpath(path) base = split(path)[0] dirname = split(path)[1] # Plausability checks try: self.opendir(base) except DirectoryExpected: raise ResourceNotFound(path) base = self._get_dir_entry(base) try: self._get_dir_entry(path) except ResourceNotFound: pass else: if not recreate: raise DirectoryExists(path) else: # TODO: Update mtime return SubFS(self, path) parent_is_root = base == self.fs.root_dir # Determine 8DOT3 file name + LFN short_name = EightDotThree() n = short_name.make_8dot3_name(dirname, base) short_name.set_str_name(n) dt = DosDateTime.now(tz=self.tz) newdir = FATDirectoryEntry(DIR_Name=short_name, DIR_Attr=FATDirectoryEntry.ATTR_DIRECTORY, DIR_NTRes=0, DIR_CrtTimeTenth=0, DIR_CrtTime=dt.serialize_time(), DIR_CrtDate=dt.serialize_date(), DIR_LstAccessDate=dt.serialize_date(), DIR_FstClusHI=0x00, DIR_WrtTime=dt.serialize_time(), DIR_WrtDate=dt.serialize_date(), DIR_FstClusLO=0x00, DIR_FileSize=0, encoding=self.fs.encoding) # Create LFN entry if required _sfn = short_name.get_unpadded_filename() if _sfn != dirname.upper() or (_sfn != dirname and self.preserve_case): lfn_entry = make_lfn_entry(dirname, short_name) newdir.set_lfn_entry(lfn_entry) # Create . and .. directory entries first_cluster = self.fs.allocate_bytes( FATDirectoryEntry.FAT_DIRECTORY_HEADER_SIZE * 2, erase=True)[0] newdir.set_cluster(first_cluster) dot_sn = EightDotThree() dot_sn.set_byte_name(b". ") dot = FATDirectoryEntry(DIR_Name=dot_sn, DIR_Attr=FATDirectoryEntry.ATTR_DIRECTORY, DIR_NTRes=newdir.ntres, DIR_CrtTimeTenth=newdir.crttimetenth, DIR_CrtTime=newdir.crttime, DIR_CrtDate=newdir.crtdate, DIR_LstAccessDate=newdir.lstaccessdate, DIR_FstClusHI=newdir.fstclushi, DIR_WrtTime=newdir.wrttime, DIR_WrtDate=newdir.wrtdate, DIR_FstClusLO=newdir.fstcluslo, DIR_FileSize=newdir.filesize, encoding=self.fs.encoding) dotdot_sn = EightDotThree() dotdot_sn.set_byte_name(b".. ") base_fstclushi = base.fstclushi if not parent_is_root else 0x0 base_fstcluslo = base.fstcluslo if not parent_is_root else 0x0 dotdot = FATDirectoryEntry(DIR_Name=dotdot_sn, DIR_Attr=FATDirectoryEntry.ATTR_DIRECTORY, DIR_NTRes=base.ntres, DIR_CrtTimeTenth=base.crttimetenth, DIR_CrtTime=base.crttime, DIR_CrtDate=base.crtdate, DIR_LstAccessDate=base.lstaccessdate, DIR_FstClusHI=base_fstclushi, DIR_WrtTime=base.wrttime, DIR_WrtDate=base.wrtdate, DIR_FstClusLO=base_fstcluslo, DIR_FileSize=base.filesize, encoding=self.fs.encoding) newdir.add_subdirectory(dot) newdir.add_subdirectory(dotdot) # Write new directory contents self.fs.update_directory_entry(newdir) # Write parent directory base.add_subdirectory(newdir) self.fs.update_directory_entry(base) # Flush FAT(s) to disk self.fs.flush_fat() return SubFS(self, path)