def test_error(self): output_file = io.StringIO() filterdir = self.fs.filterdir def broken_filterdir(path, **kwargs): if path.startswith("/deep/deep1/"): # Because error messages differ accross Python versions raise Exception("integer division or modulo by zero") return filterdir(path, **kwargs) self.fs.filterdir = broken_filterdir tree.render(self.fs, file=output_file, with_color=True) expected = "\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mbar\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mbaz\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mdeep\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep1\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep2\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[31merror (integer division or modulo by zero)\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mfoo\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[1;34megg1\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[1;34megg2\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[33m.hidden\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m test.txt\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m test2.txt\n\x1b[32m\u251c\u2500\u2500\x1b[0m root1\n\x1b[32m\u2514\u2500\u2500\x1b[0m root2\n" tree_output = output_file.getvalue() print(repr(tree_output)) self.assertEqual(expected, tree_output) output_file = io.StringIO() tree.render(self.fs, file=output_file, with_color=False) expected = "|-- bar\n|-- baz\n|-- deep\n| `-- deep1\n| `-- deep2\n| `-- error (integer division or modulo by zero)\n|-- foo\n| |-- egg1\n| |-- egg2\n| |-- .hidden\n| |-- test.txt\n| `-- test2.txt\n|-- root1\n`-- root2\n" self.assertEqual(expected, output_file.getvalue())
def test_tree_bytes_no_dirs_first(self): output_file = io.StringIO() tree.render(self.fs, file=output_file, dirs_first=False) expected = "|-- bar\n|-- baz\n|-- deep\n| `-- deep1\n| `-- deep2\n| `-- deep3\n| `-- deep4\n| `-- deep5\n|-- foo\n| |-- .hidden\n| |-- egg1\n| |-- egg2\n| |-- test.txt\n| `-- test2.txt\n|-- root1\n`-- root2\n" self.assertEqual(output_file.getvalue(), expected)
def test_tree_encoding(self): output_file = io.StringIO() tree.render(self.fs, file=output_file, with_color=True) print(repr(output_file.getvalue())) expected = "\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mbar\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mbaz\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mdeep\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep1\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep2\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep3\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep4\x1b[0m\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m \x1b[1;34mdeep5\x1b[0m\n\x1b[32m\u251c\u2500\u2500\x1b[0m \x1b[1;34mfoo\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[1;34megg1\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[1;34megg2\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m \x1b[33m.hidden\x1b[0m\n\x1b[32m\u2502 \u251c\u2500\u2500\x1b[0m test.txt\n\x1b[32m\u2502 \u2514\u2500\u2500\x1b[0m test2.txt\n\x1b[32m\u251c\u2500\u2500\x1b[0m root1\n\x1b[32m\u2514\u2500\u2500\x1b[0m root2\n" self.assertEqual(output_file.getvalue(), expected)
def isclosed(self): # type: () -> bool return self._tar.closed # type: ignore def geturl(self, path, purpose="download"): # type: (Text, Text) -> Text if purpose == "fs" and isinstance(self._file, six.string_types): quoted_file = url_quote(self._file) quoted_path = url_quote(path) return "tar://{}!/{}".format(quoted_file, quoted_path) else: raise NoURL(path, purpose) if __name__ == "__main__": # pragma: no cover from fs.tree import render with TarFS("tests.tar") as tar_fs: print(tar_fs.listdir("/")) print(tar_fs.listdir("/tests/")) print(tar_fs.readtext("tests/ttt/settings.ini")) render(tar_fs) print(tar_fs) print(repr(tar_fs)) with TarFS("TarFS.tar", write=True) as tar_fs: tar_fs.makedirs("foo/bar") tar_fs.writetext("foo/bar/baz.txt", "Hello, World") print(tar_fs) print(repr(tar_fs))
def tree(self): (dirs, files) = render(self.fs, with_color=True, file=None) return f'Found {dirs} directories and {files} files.'
def close(self): super(ReadZipFS, self).close() self._zip.close() def getbytes(self, path): self.check() if not self._directory.isfile(path): raise errors.ResourceNotFound(path) zip_name = self._path_to_zip_name(path) zip_bytes = self._zip.read(zip_name) return zip_bytes if __name__ == "__main__": # pragma: nocover from fs.tree import render from fs.opener import open_fs with ZipFS('tests.zip') as zip_fs: print(zip_fs.listdir('/')) print(zip_fs.listdir('/tests/')) print(zip_fs.gettext('tests/ttt/settings.ini')) render(zip_fs) print(zip_fs) print(repr(zip_fs)) with ZipFS("zipfs.zip", write=True) as zip_fs: zip_fs.makedirs('foo/bar') zip_fs.settext('foo/bar/baz.txt', 'Hello, World') print(zip_fs) print(repr(zip_fs))
def run(self): args = self.args application = WSGIApplication( self.location, self.get_settings(), args.server, disable_autoreload=True, master_settings=self.master_settings, ) archive = application.archive filesystems = archive.filesystems fs = None if args.fs: try: fs = filesystems[args.fs] except KeyError: self.console.error("No filesystem called '%s'" % args.fs) return -1 if args.tree is not None: if fs is None: self.console.error("Filesystem required") return -1 with fs.opendir(args.tree or "/") as tree_fs: tree.render(tree_fs, max_levels=None) return if args.listdir: if fs is None: self.console.error("Filesystem required") return -1 dir_fs = fs.opendir(args.listdir) file_paths = [] dir_paths = [] for info in dir_fs.scandir("/"): if info.is_dir: dir_paths.append(info.name) else: file_paths.append(info.name) _ls(self.console, file_paths, dir_paths) elif args.cat: if fs is None: self.console.error("Filesystem required") return -1 contents = fs.gettext(args.cat) self.console.cat(contents, args.cat) elif args.open: if fs is None: self.console.error("Filesystem required") return -1 try: filepath = fs.getsyspath(args.open) except NoSysPath: self.console.error( "No system path for '%s' in filesystem '%s'" % (args.open, args.fs) ) return -1 import subprocess system = sys.platform if system == "darwin": subprocess.call(("open", filepath)) elif system == "win32": subprocess.call(("start", filepath), shell=True) elif system == "linux2": subprocess.call(("xdg-open", filepath)) else: self.console.error( "Moya doesn't know how to open files on this platform (%s)" % os.name ) elif args.syspath: if fs is None: self.console.error("Filesystem required") return -1 if not fs.exists(args.syspath): self.console.error( "No file called '%s' found in filesystem '%s'" % (args.syspath, args.fs) ) return -1 try: syspath = fs.getsyspath(args.syspath) except NoSysPath: self.console.error( "No system path for '%s' in filesystem '%s'" % (args.syspath, args.fs) ) else: self.console(syspath).nl() elif args.copy: if fs is None: self.console.error("Filesystem required") return -1 if len(args.copy) == 1: src = "/" dst = args.copy[0] elif len(args.copy) == 2: src, dst = args.copy else: self.console.error("--copy requires 1 or 2 arguments") return -1 if fs.isdir(src): src_fs = fs.opendir(src) from fs.copy import copy_dir with open_fs(dst, create=True) as dst_fs: if not args.force and not dst_fs.isempty("/"): response = raw_input( "'%s' is not empty. Copying may overwrite directory contents. Continue? " % dst ) if response.lower() not in ("y", "yes"): return 0 copy_dir(src_fs, "/", dst_fs, "/") else: with fs.open(src, "rb") as read_f: if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) try: os.makedirs(dst) with open(dst, "wb") as write_f: while 1: chunk = read_f.read(16384) if not chunk: break write_f.write(chunk) except IOError as e: self.error("unable to write to {}".format(dst)) elif args.extract: if fs is None: self.console.error("Filesystem required") return -1 src_path, dst_dir_path = args.extract src_fs = fs dst_fs = open_fs(dst_dir_path, create=True) if not args.force and dst_fs.exists(src_path): response = raw_input( "'%s' exists. Do you want to overwrite? " % src_path ) if response.lower() not in ("y", "yes"): return 0 dst_fs.makedirs(dirname(src_path), recreate=True) with src_fs.open(src_path, "rb") as read_file: dst_fs.setfile(src_path, read_file) elif args.serve: from .serve import Serve Serve.run_server( args.host, args.port, fs, show_access=True, develop=False, debug=True ) else: table = [ [ Cell("Name", bold=True), Cell("Type", bold=True), Cell("Location", bold=True), ] ] if fs is None: list_filesystems = filesystems.items() else: list_filesystems = [(args.fs, fs)] def get_type_name(name): name = type(fs).__name__ return name[:-2].lower() if name.endswith("FS") else name.lower() for name, fs in sorted(list_filesystems): if isinstance(fs, MultiFS): location = "\n".join( mount_fs.desc("/") for name, mount_fs in fs.iterate_fs() ) fg = "yellow" elif isinstance(fs, MountFS): mount_desc = [] for path, dirmount in fs.mount_tree.items(): mount_desc.append("%s->%s" % (path, dirmount.fs.desc("/"))) location = "\n".join(mount_desc) fg = "magenta" else: try: syspath = fs.getsyspath("/") except NoSysPath: location = syspath fg = "green" else: try: location = fs.desc("/") except FSError as e: location = text_type(e) fg = "red" else: fg = "blue" table.append( [ Cell(name), Cell(get_type_name(fs)), Cell(location, bold=True, fg=fg), ] ) self.console.table(table, header=True)