コード例 #1
0
                else:
                    print_dir(fs, pathjoin(path, item),
                              levels[:] + [is_last_item])
            else:
                write('%s %s' %
                      (wrap_prefix(prefix + char_line), wrap_filename(item)))

        return len(dir_listing)

    print_dir(fs, path)
    return dircount[0], filecount[0]


if __name__ == "__main__":
    from fs.tempfs import TempFS
    from six import b
    t1 = TempFS()
    t1.setcontents("foo", b("test"))
    t1.makedir("bar")
    t1.setcontents("bar/baz", b("another test"))

    t1.tree()

    t2 = TempFS()
    print t2.listdir()
    movedir(t1, t2)

    print t2.listdir()
    t1.tree()
    t2.tree()
コード例 #2
0
ファイル: utils.py プロジェクト: ctismer/pyfilesystem
                    #write(wrap_prefix(prefix[:-1] + '       ') + wrap_error('max recursion levels reached'))
                else:
                    print_dir(fs, pathjoin(path, item), levels[:] + [is_last_item])
            else:
                write('%s %s' % (wrap_prefix(prefix + char_line), wrap_filename(item)))

        return len(dir_listing)

    print_dir(fs, path)
    return dircount[0], filecount[0]


if __name__ == "__main__":
    from fs.tempfs import TempFS
    from six import b
    t1 = TempFS()
    t1.setcontents("foo", b("test"))
    t1.makedir("bar")
    t1.setcontents("bar/baz", b("another test"))

    t1.tree()

    t2 = TempFS()
    print t2.listdir()
    movedir(t1, t2)

    print t2.listdir()
    t1.tree()
    t2.tree()

コード例 #3
0
class COWFS(FS):
    def __init__(
        self,
        base_fs: FS,
        additions_fs: Optional[FS] = None,
        deletions_fs: Optional[FS] = None,
    ) -> None:
        FS.__init__(self)
        if additions_fs:
            self.additions_fs = additions_fs
        else:
            self.additions_fs = TempFS()

        if deletions_fs:
            _deletions_invariant(deletions_fs)
            self.deletions_fs = deletions_fs
        else:
            self.deletions_fs = TempFS()

        self.original_base_fs = base_fs
        self.base_fs = fs.wrap.read_only(base_fs)

        self.invariant()

    @staticmethod
    def create_cowfs(base_fs: FS,
                     read_write_layer: FS,
                     recreate: bool = False) -> "COWFS":
        additions_fs = read_write_layer.makedir("/additions",
                                                recreate=recreate)
        deletions_fs = read_write_layer.makedir("/deletions",
                                                recreate=recreate)

        return COWFS(base_fs, additions_fs, deletions_fs)

    def __str__(self) -> str:
        return (f"COWFS({self.original_base_fs}, "
                f"{self.additions_fs}, "
                f"{self.deletions_fs})")

    def __repr__(self) -> str:
        return (f"COWFS({self.original_base_fs!r}, "
                f"{self.additions_fs!r}, "
                f"{self.deletions_fs!r})")

    ############################################################

    def invariant(self) -> bool:
        if not self.additions_fs:
            raise ValueError(f"Invalid additions_fs: {self.additions_fs}.")
        if not self.deletions_fs:
            raise ValueError(f"Invalid deletions_fs: {self.additions_fs}.")
        if not self.base_fs:
            raise ValueError(f"Invalid base_fs: {self.base_fs}.")

        _deletions_invariant(self.deletions_fs)

        additions_paths = set(paths(self.additions_fs))
        deletions_paths = {
            fs.path.dirname(file)
            for file in self.deletions_fs.walk.files()
        }
        if additions_paths > deletions_paths:
            raise ValueError(f"Additions_paths {additions_paths} " +
                             "is not a subset of deletions_path " +
                             f"{deletions_paths}. Extras are " +
                             f"{additions_paths - deletions_paths}.")

        return True

    def is_deletion(self, path: str) -> bool:
        """
        Is the path marked in the deletions_fs"
        """
        return self.deletions_fs.exists(del_path(path))

    def mark_deletion(self, path: str) -> None:
        """
        Mark the path in the deletions_fs.
        """
        self.deletions_fs.makedirs(path, None, True)
        self.deletions_fs.touch(del_path(path))

    def makedirs_mark_deletion(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> None:
        for p in fs.path.recursepath(path)[:-1]:
            self.additions_fs.makedirs(p,
                                       permissions=permissions,
                                       recreate=True)
            self.mark_deletion(p)
        self.additions_fs.makedir(path,
                                  permissions=permissions,
                                  recreate=recreate)
        self.mark_deletion(path)

    def layer(self, path: str) -> int:
        """
        Get the layer on which the file lives, or ROOT_LAYER if it's the
        root path.
        """

        if path == "/":
            return ROOT_LAYER
        if self.additions_fs.exists(path):
            return ADD_LAYER
        elif self.is_deletion(path):
            return NO_LAYER
        elif self.base_fs.exists(path):
            return BASE_LAYER
        else:
            return NO_LAYER

    def copy_up(self, path: str) -> None:
        """
        Copy the file from the base_fs to additions_fs.
        """
        self.makedirs_mark_deletion(fs.path.dirname(path))
        self.mark_deletion(path)
        fs.copy.copy_file(self.base_fs, path, self.additions_fs, path)

    def triple_tree(self) -> None:
        print("base_fs ------------------------------")
        self.base_fs.tree()
        print("additions_fs ------------------------------")
        self.additions_fs.tree()
        print("deletions_fs ------------------------------")
        self.deletions_fs.tree()

    ############################################################
    def getmeta(self, namespace: str = "standard") -> Mapping[str, object]:
        return self.base_fs.getmeta(namespace)

    def getinfo(self,
                path: str,
                namespaces: Optional[Collection[str]] = None) -> Info:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            return self.base_fs.getinfo(path, namespaces)
        elif layer == ADD_LAYER:
            return self.additions_fs.getinfo(path, namespaces)
        elif layer == ROOT_LAYER:
            # TODO implement this
            raw_info = {}
            if namespaces is None or "basic" in namespaces:
                raw_info["basic"] = {"name": "", "is_dir": True}
            return Info(raw_info)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def getsyspath(self, path: str) -> str:
        self.check()
        # self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.NoSysPath(path=path)
        elif layer == BASE_LAYER:
            return self.base_fs.getsyspath(path)
        elif layer == ADD_LAYER:
            return self.additions_fs.getsyspath(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.NoSysPath(path=path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def listdir(self, path: str) -> List[str]:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            return [
                name for name in self.base_fs.listdir(path)
                if self.layer(fs.path.join(path, name)) != NO_LAYER
            ]
        elif layer == ADD_LAYER:
            # Get the listing on the additions layer
            names = set(self.additions_fs.listdir(path))
            # Add in the listing on the base layer (if it exists)
            if self.base_fs.isdir(path):
                names |= set(self.base_fs.listdir(path))
            # Return the entries that actually exist
            return [
                name for name in list(names)
                if self.layer(fs.path.join(path, name)) != NO_LAYER
            ]
        elif layer == ROOT_LAYER:
            # Get the listing of the root on the additions layer and
            # the base layer.
            names = set(self.additions_fs.listdir("/"))
            names |= set(self.base_fs.listdir("/"))
            # Return the entries that actually exist.
            return [
                name for name in list(names) if self.layer(name) != NO_LAYER
            ]
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def makedir(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> SubFS["COWFS"]:
        self.check()
        self.validatepath(path)

        # Check if it *can* be created.

        # get a normalized parent_dir path.
        parent_dir = fs.path.dirname(fs.path.forcedir(path)[:-1])
        if not parent_dir:
            parent_dir = "/"

        if not self.isdir(parent_dir):
            raise fs.errors.ResourceNotFound(path)

        layer = self.layer(path)
        if layer == NO_LAYER:
            self.makedirs_mark_deletion(path,
                                        permissions=permissions,
                                        recreate=recreate)
            return SubFS(self, path)
        elif layer in [BASE_LAYER, ADD_LAYER, ROOT_LAYER]:
            if recreate:
                return SubFS(self, path)
            else:
                # I think this is wrong.  What if it's a file?
                raise fs.errors.DirectoryExists(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def openbin(self,
                path: str,
                mode: str = "r",
                buffering: int = -1,
                **options: Any) -> BinaryIO:
        self.check()
        self.validatepath(path)

        parent_dir = fs.path.dirname(fs.path.forcedir(path)[:-1])
        if not parent_dir:
            parent_dir = "/"

        if not self.isdir(parent_dir):
            raise fs.errors.ResourceNotFound(path)

        mode_obj = Mode(mode)
        layer = self.layer(path)
        if layer == NO_LAYER:
            if mode_obj.create:
                for p in fs.path.recursepath(path)[:-1]:
                    self.additions_fs.makedirs(p, recreate=True)
                    self.mark_deletion(p)
                self.mark_deletion(path)
                return self.additions_fs.openbin(path, mode, buffering,
                                                 **options)
            else:
                raise fs.errors.ResourceNotFound(path)
        elif layer == ADD_LAYER:
            self.mark_deletion(path)
            return self.additions_fs.openbin(path, mode, buffering, **options)
        elif layer == BASE_LAYER:
            if mode_obj.writing:
                self.copy_up(path)
                return self.additions_fs.openbin(path, mode, buffering,
                                                 **options)
            else:
                return self.base_fs.openbin(path, mode, buffering, **options)
        elif layer == ROOT_LAYER:
            raise fs.errors.FileExpected(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def remove(self, path: str) -> None:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            if self.base_fs.isfile(path):
                self.mark_deletion(path)
            else:
                raise fs.errors.FileExpected(path)
        elif layer == ADD_LAYER:
            self.additions_fs.remove(path)
            self.mark_deletion(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.FileExpected(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def removedir(self, path: str) -> None:
        self.check()
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            if self.base_fs.isdir(path):
                self.mark_deletion(path)
            else:
                raise fs.errors.FileExpected(path)
        elif layer == ADD_LAYER:
            if self.additions_fs.isdir(path):
                self.additions_fs.removedir(path)
                self.mark_deletion(path)
            else:
                raise fs.errors.DirectoryExpected(path)
        elif layer == ROOT_LAYER:
            raise fs.errors.RemoveRootError(path)
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    def setinfo(self, path: str, info: _INFO_DICT) -> None:
        self.check()
        self.validatepath(path)
        layer = self.layer(path)
        if layer == NO_LAYER:
            raise fs.errors.ResourceNotFound(path)
        elif layer == BASE_LAYER:
            self.copy_up(path)
            self.additions_fs.setinfo(path, info)
        elif layer == ADD_LAYER:
            self.additions_fs.setinfo(path, info)
        elif layer == ROOT_LAYER:
            pass
        else:
            raise RuntimeError(f"Unknown layer {layer}.")

    ############################################################

    def makedirs(
        self,
        path: str,
        permissions: Optional[Permissions] = None,
        recreate: bool = False,
    ) -> SubFS[FS]:
        return FS.makedirs(self,
                           path,
                           permissions=permissions,
                           recreate=recreate)