summaryrefslogtreecommitdiff
path: root/fs/commands
diff options
context:
space:
mode:
authorwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2010-12-16 20:27:04 +0000
committerwillmcgugan <willmcgugan@67cdc799-7952-0410-af00-57a81ceafa0f>2010-12-16 20:27:04 +0000
commitb3a9c67cad59b3a90b6ddf91b7aaccba52328745 (patch)
treecbd76cfe81f15e8436b427b9488199b734fd42cd /fs/commands
parent46340fbf6a98d6ccbabcebf1d184d1bb0e5c08d1 (diff)
downloadpyfilesystem-b3a9c67cad59b3a90b6ddf91b7aaccba52328745.tar.gz
Command improvements
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@554 67cdc799-7952-0410-af00-57a81ceafa0f
Diffstat (limited to 'fs/commands')
-rw-r--r--fs/commands/fscp.py2
-rw-r--r--fs/commands/fsls.py41
-rw-r--r--fs/commands/fsmkdir.py2
-rw-r--r--fs/commands/fsmount.py2
-rw-r--r--fs/commands/fsserve.py2
-rw-r--r--fs/commands/fstree.py25
-rw-r--r--fs/commands/runner.py75
7 files changed, 95 insertions, 54 deletions
diff --git a/fs/commands/fscp.py b/fs/commands/fscp.py
index abae921..48978e9 100644
--- a/fs/commands/fscp.py
+++ b/fs/commands/fscp.py
@@ -74,7 +74,7 @@ Copy SOURCE to DESTINATION"""
srcs = args[:-1]
dst = args[-1]
- dst_fs, dst_path = self.open_fs(dst, writeable=True, create=True)
+ dst_fs, dst_path = self.open_fs(dst, writeable=True, create_dir=True)
if dst_path is not None and dst_fs.isfile(dst_path):
self.error('Destination must be a directory\n')
diff --git a/fs/commands/fsls.py b/fs/commands/fsls.py
index 611d700..2cfb244 100644
--- a/fs/commands/fsls.py
+++ b/fs/commands/fsls.py
@@ -17,7 +17,9 @@ List contents of [PATH]"""
optparse.add_option('-u', '--full', dest='fullpath', action="store_true", default=False,
help="output full path", metavar="FULL")
optparse.add_option('-s', '--syspath', dest='syspath', action="store_true", default=False,
- help="output system path", metavar="SYSPATH")
+ help="output system path (if one exists)", metavar="SYSPATH")
+ optparse.add_option('-r', '--url', dest='url', action="store_true", default=False,
+ help="output URL in place of path (if one exists)", metavar="URL")
optparse.add_option('-d', '--dirsonly', dest='dirsonly', action="store_true", default=False,
help="list directories only", metavar="DIRSONLY")
optparse.add_option('-f', '--filesonly', dest='filesonly', action="store_true", default=False,
@@ -52,30 +54,36 @@ List contents of [PATH]"""
if not options.dirsonly:
file_paths.append(path)
else:
- if not options.filesonly:
+ if not options.filesonly:
dir_paths += fs.listdir(path,
wildcard=wildcard,
- full=options.fullpath,
+ full=options.fullpath or options.url,
dirs_only=True)
if not options.dirsonly:
file_paths += fs.listdir(path,
wildcard=wildcard,
- full=options.fullpath,
+ full=options.fullpath or options.url,
files_only=True)
- try:
- for fs in fs_used:
+ for fs in fs_used:
+ try:
fs.close()
- except FSError:
- pass
-
+ except FSError:
+ pass
+
if options.syspath:
- dir_paths = [fs.getsyspath(path, allow_none=True) or path for path in dir_paths]
- file_paths = [fs.getsyspath(path, allow_none=True) or path for path in file_paths]
+ # Path without a syspath, just won't be displayed
+ dir_paths = filter(None, [fs.getsyspath(path, allow_none=True) for path in dir_paths])
+ file_paths = filter(None, [fs.getsyspath(path, allow_none=True) for path in file_paths])
+
+ if options.url:
+ # Path without a syspath, just won't be displayed
+ dir_paths = filter(None, [fs.getpathurl(path, allow_none=True) for path in dir_paths])
+ file_paths = filter(None, [fs.getpathurl(path, allow_none=True) for path in file_paths])
- dirs = frozenset(dir_paths)
- paths = sorted(dir_paths + file_paths, key=lambda p:p.lower())
+ dirs = frozenset(dir_paths)
+ paths = sorted(dir_paths + file_paths, key=lambda p:p.lower())
if not options.all:
paths = [path for path in paths if not isdotfile(path)]
@@ -129,9 +137,9 @@ List contents of [PATH]"""
if options.long:
for path in paths:
if path in dirs:
- output(self.wrap_dirname(path) + '\n')
+ output((self.wrap_dirname(path), '\n'))
else:
- output(self.wrap_filename(path) + '\n')
+ output((self.wrap_filename(path), '\n'))
else:
terminal_width = self.terminal_width
@@ -158,8 +166,7 @@ List contents of [PATH]"""
num_cols -= 1
num_cols = max(1, num_cols)
columns = columnize(paths, num_cols)
- output(condense_columns(columns))
- output('\n')
+ output((condense_columns(columns), '\n'))
def run():
return FSls().run()
diff --git a/fs/commands/fsmkdir.py b/fs/commands/fsmkdir.py
index bafb42c..bb64e2c 100644
--- a/fs/commands/fsmkdir.py
+++ b/fs/commands/fsmkdir.py
@@ -14,7 +14,7 @@ Make a directory"""
def do_run(self, options, args):
for fs_url in args:
- fs, path = self.open_fs(fs_url, create=True)
+ fs, path = self.open_fs(fs_url, create_dir=True)
def run():
return FSMkdir().run()
diff --git a/fs/commands/fsmount.py b/fs/commands/fsmount.py
index b0c4f98..3305f7f 100644
--- a/fs/commands/fsmount.py
+++ b/fs/commands/fsmount.py
@@ -54,7 +54,7 @@ Mounts a file system on a system path"""
if platform.system() == 'Windows':
pass
else:
- fs, path = self.open_fs(fs_url, create=True)
+ fs, path = self.open_fs(fs_url, create_dir=True)
if path:
if not fs.isdir(path):
self.error('%s is not a directory on %s' % (fs_url. fs))
diff --git a/fs/commands/fsserve.py b/fs/commands/fsserve.py
index c1a0c2d..cfe42a9 100644
--- a/fs/commands/fsserve.py
+++ b/fs/commands/fsserve.py
@@ -8,7 +8,7 @@ from fs.utils import print_fs
class FSServe(Command):
- """fsserve [OPTION]... [PATH]
+ usage = """fsserve [OPTION]... [PATH]
Serves the contents of PATH with one of a number of methods"""
def get_optparse(self):
diff --git a/fs/commands/fstree.py b/fs/commands/fstree.py
index 166612c..7f8fe4b 100644
--- a/fs/commands/fstree.py
+++ b/fs/commands/fstree.py
@@ -15,6 +15,8 @@ Recursively display the contents of PATH in an ascii tree"""
optparse = super(FSTree, self).get_optparse()
optparse.add_option('-l', '--level', dest='depth', type="int", default=5,
help="Descend only LEVEL directories deep", metavar="LEVEL")
+ optparse.add_option('-g', '--gui', dest='gui', action='store_true', default=False,
+ help="browse the tree with a gui")
optparse.add_option('-a', '--all', dest='all', action='store_true', default=False,
help="do not hide dot files")
optparse.add_option('-d', '--dirsfirst', dest='dirsfirst', action='store_true', default=False,
@@ -26,18 +28,23 @@ Recursively display the contents of PATH in an ascii tree"""
if not args:
args = ['.']
- for fs, path, is_dir in self.get_resources(args, single=True):
- if path is not None:
- fs.opendir(path)
+ for fs, path, is_dir in self.get_resources(args, single=True):
if not is_dir:
self.error(u"'%s' is not a dir\n" % path)
return 1
- print_fs(fs, path or '',
- file_out=self.output_file,
- max_levels=options.depth,
- terminal_colors=self.is_terminal(),
- hide_dotfiles=not options.all,
- dirs_first=options.dirsfirst)
+ fs.cache_hint(True)
+ if options.gui:
+ from fs.browsewin import browse
+ if path:
+ fs = fs.opendir(path)
+ browse(fs, hide_dotfiles=not options.all)
+ else:
+ print_fs(fs, path or '',
+ file_out=self.output_file,
+ max_levels=options.depth,
+ terminal_colors=self.is_terminal(),
+ hide_dotfiles=not options.all,
+ dirs_first=options.dirsfirst)
def run():
return FSTree().run()
diff --git a/fs/commands/runner.py b/fs/commands/runner.py
index 6647aa8..bc63ca1 100644
--- a/fs/commands/runner.py
+++ b/fs/commands/runner.py
@@ -5,7 +5,7 @@ from fs.errors import FSError
from fs.path import splitext, pathsplit, isdotfile, iswildcard
import platform
from collections import defaultdict
-
+import re
if platform.system() == 'Linux' :
def getTerminalSize():
@@ -51,8 +51,11 @@ class Command(object):
self.encoding = getattr(self.output_file, 'encoding', 'utf-8') or 'utf-8'
self.verbosity_level = 0
self.terminal_colors = not sys.platform.startswith('win') and self.is_terminal()
- w, h = getTerminalSize()
- self.terminal_width = w
+ if self.is_terminal():
+ w, h = getTerminalSize()
+ self.terminal_width = w
+ else:
+ self.terminal_width = 80
self.name = self.__class__.__name__.lower()
def is_terminal(self):
@@ -74,7 +77,9 @@ class Command(object):
def wrap_filename(self, fname):
fname = _unicode(fname)
if not self.terminal_colors:
- return fname
+ return fname
+ if '://' in fname:
+ return fname
if '.' in fname:
name, ext = splitext(fname)
fname = u'%s\x1b[36m%s\x1b[0m' % (name, ext)
@@ -88,16 +93,35 @@ class Command(object):
return text
return u'\x1b[2m%s\x1b[0m' % text
+ def wrap_link(self, text):
+ if not self.terminal_colors:
+ return text
+ return u'\x1b[1;33m%s\x1b[0m' % text
+
+ def wrap_strong(self, text):
+ if not self.terminal_colors:
+ return text
+ return u'\x1b[1m%s\x1b[0m' % text
+
def wrap_table_header(self, name):
if not self.terminal_colors:
return name
return '\x1b[1;32m%s\x1b[0m' % name
- def open_fs(self, fs_url, writeable=False, create=False):
+ def highlight_fsurls(self, text):
+ if not self.terminal_colors:
+ return text
+ re_fs = r'(\S*?://\S*)'
+ def repl(matchobj):
+ fs_url = matchobj.group(0)
+ return self.wrap_link(fs_url)
+ return re.sub(re_fs, repl, text)
+
+ def open_fs(self, fs_url, writeable=False, create_dir=False):
try:
- fs, path = opener.parse(fs_url, writeable=writeable, create_dir=create)
+ fs, path = opener.parse(fs_url, writeable=writeable, create_dir=create_dir)
except OpenerError, e:
- self.error(str(e)+'\n')
+ self.error(str(e), '\n')
sys.exit(1)
fs.cache_hint(True)
return fs, path
@@ -168,12 +192,15 @@ class Command(object):
return text
- def output(self, msg, verbose=False):
- if verbose and not self.verbose:
- return
- self.output_file.write(self.text_encode(msg))
-
+ def output(self, msgs, verbose=False):
+ if verbose and not self.verbose:
+ return
+ if isinstance(msgs, basestring):
+ msgs = (msgs,)
+ for msg in msgs:
+ self.output_file.write(self.text_encode(msg))
+
def output_table(self, table, col_process=None, verbose=False):
if verbose and not self.verbose:
@@ -199,8 +226,9 @@ class Command(object):
lines.append(self.text_encode('%s\n' % ' '.join(out_col).rstrip()))
self.output(''.join(lines))
- def error(self, msg):
- self.error_file.write('%s: %s' % (self.name, self.text_encode(msg)))
+ def error(self, *msgs):
+ for msg in msgs:
+ self.error_file.write('%s: %s' % (self.name, self.text_encode(msg)))
def get_optparse(self):
optparse = OptionParser(usage=self.usage, version=self.version)
@@ -229,23 +257,23 @@ class Command(object):
for line in lines:
words = []
line_len = 0
- for word in line.split():
+ for word in line.split():
+ if word == '*':
+ word = ' *'
if line_len + len(word) > self.terminal_width:
- self.output(' '.join(words))
- self.output('\n')
+ self.output((self.highlight_fsurls(' '.join(words)), '\n'))
del words[:]
line_len = 0
words.append(word)
line_len += len(word) + 1
if words:
- self.output(' '.join(words))
+ self.output(self.highlight_fsurls(' '.join(words)))
self.output('\n')
- for names, desc in opener_table:
- self.output('\n')
+ for names, desc in opener_table:
+ self.output(('-' * self.terminal_width, '\n'))
proto = ', '.join([n+'://' for n in names])
- self.output(self.wrap_dirname('[%s]' % proto))
- self.output('\n')
+ self.output((self.wrap_dirname('[%s]' % proto), '\n\n'))
if not desc.strip():
desc = "No information available"
wrap_line(desc)
@@ -280,8 +308,7 @@ class Command(object):
if options.debug:
raise
return 1
-
-
+
if __name__ == "__main__":
command = Command()