summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwillmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f>2014-02-27 15:38:30 +0000
committerwillmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f>2014-02-27 15:38:30 +0000
commit5142e4da3e4a838b256c5c582a25ad0fdbb9bf49 (patch)
tree35f90f42713775c74d0083ad8d4cb49a8564e591
parent5c3387371f9cbbbdb081931dce4f7b6498ae30cd (diff)
downloadpyfilesystem-5142e4da3e4a838b256c5c582a25ad0fdbb9bf49.tar.gz
Fixes for fs commands in PY3
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@886 67cdc799-7952-0410-af00-57a81ceafa0f
-rw-r--r--fs/commands/fsls.py137
-rw-r--r--fs/commands/runner.py26
-rw-r--r--fs/utils.py9
-rw-r--r--tox.ini19
4 files changed, 104 insertions, 87 deletions
diff --git a/fs/commands/fsls.py b/fs/commands/fsls.py
index d1ee324..b98da79 100644
--- a/fs/commands/fsls.py
+++ b/fs/commands/fsls.py
@@ -8,17 +8,17 @@ from collections import defaultdict
import sys
class FSls(Command):
-
+
usage = """fsls [OPTIONS]... [PATH]
List contents of [PATH]"""
-
-
+
+
def get_optparse(self):
- optparse = super(FSls, self).get_optparse()
+ optparse = super(FSls, self).get_optparse()
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 (if one exists)", 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,
@@ -29,73 +29,73 @@ List contents of [PATH]"""
help="use a long listing format", metavar="LONG")
optparse.add_option('-a', '--all', dest='all', action='store_true', default=False,
help="do not hide dot files")
-
+
return optparse
-
-
- def do_run(self, options, args):
+
+
+ def do_run(self, options, args):
output = self.output
-
+
if not args:
args = [u'.']
-
- dir_paths = []
+
+ dir_paths = []
file_paths = []
- fs_used = set()
+ fs_used = set()
for fs_url in args:
- fs, path = self.open_fs(fs_url)
- fs_used.add(fs)
+ fs, path = self.open_fs(fs_url)
+ fs_used.add(fs)
path = path or '.'
wildcard = None
-
+
if iswildcard(path):
path, wildcard = pathsplit(path)
-
- if path != '.' and fs.isfile(path):
- if not options.dirsonly:
+
+ if path != '.' and fs.isfile(path):
+ if not options.dirsonly:
file_paths.append(path)
- else:
+ else:
if not options.filesonly:
dir_paths += fs.listdir(path,
wildcard=wildcard,
full=options.fullpath or options.url,
dirs_only=True)
-
- if not options.dirsonly:
+
+ if not options.dirsonly:
file_paths += fs.listdir(path,
wildcard=wildcard,
- full=options.fullpath or options.url,
+ full=options.fullpath or options.url,
files_only=True)
-
+
for fs in fs_used:
try:
fs.close()
except FSError:
pass
-
+
if options.syspath:
# 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())
-
- if not options.all:
+ 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)]
-
+
if not paths:
- return
-
+ return
+
def columnize(paths, num_columns):
-
- col_height = (len(paths) + num_columns - 1) / num_columns
- columns = [[] for _ in xrange(num_columns)]
+
+ col_height = (len(paths) + num_columns - 1) / num_columns
+ columns = [[] for _ in xrange(num_columns)]
col_no = 0
col_pos = 0
for path in paths:
@@ -104,73 +104,72 @@ List contents of [PATH]"""
if col_pos >= col_height:
col_no += 1
col_pos = 0
-
+
padded_columns = []
-
+
wrap_filename = self.wrap_filename
wrap_dirname = self.wrap_dirname
- def wrap(path):
+
+ def wrap(path):
if path in dirs:
return wrap_dirname(path.ljust(max_width))
else:
return wrap_filename(path.ljust(max_width))
-
+
for column in columns:
if column:
max_width = max([len(path) for path in column])
else:
max_width = 1
- max_width = min(max_width, terminal_width)
+ max_width = min(max_width, terminal_width)
padded_columns.append([wrap(path) for path in column])
-
+
return padded_columns
-
def condense_columns(columns):
max_column_height = max([len(col) for col in columns])
lines = [[] for _ in xrange(max_column_height)]
for column in columns:
for line, path in zip(lines, column):
- line.append(path)
+ line.append(path)
return '\n'.join(u' '.join(line) for line in lines)
-
- if options.long:
+
+ if options.long:
for path in paths:
if path in dirs:
output((self.wrap_dirname(path), '\n'))
else:
- output((self.wrap_filename(path), '\n'))
-
- else:
+ output((self.wrap_filename(path), '\n'))
+
+ else:
terminal_width = self.terminal_width
path_widths = [len(path) for path in paths]
- smallest_paths = min(path_widths)
- num_paths = len(paths)
-
- num_cols = min(terminal_width / (smallest_paths + 2), num_paths)
- while num_cols:
- col_height = (num_paths + num_cols - 1) / num_cols
- line_width = 0
- for col_no in xrange(num_cols):
- try:
- col_width = max(path_widths[col_no*col_height:(col_no + 1) * col_height])
+ smallest_paths = min(path_widths)
+ num_paths = len(paths)
+
+ num_cols = min(terminal_width // (smallest_paths + 2), num_paths)
+ while num_cols:
+ col_height = (num_paths + num_cols - 1) // num_cols
+ line_width = 0
+ for col_no in xrange(num_cols):
+ try:
+ col_width = max(path_widths[col_no * col_height: (col_no + 1) * col_height])
except ValueError:
continue
- line_width += col_width
- if line_width > terminal_width:
- break;
+ line_width += col_width
+ if line_width > terminal_width:
+ break
line_width += 2
else:
if line_width - 1 <= terminal_width:
break
- num_cols -= 1
- num_cols = max(1, num_cols)
- columns = columnize(paths, num_cols)
- output((condense_columns(columns), '\n'))
+ num_cols -= 1
+ num_cols = max(1, num_cols)
+ columns = columnize(paths, num_cols)
+ output((condense_columns(columns), '\n'))
def run():
- return FSls().run()
-
+ return FSls().run()
+
if __name__ == "__main__":
sys.exit(run())
- \ No newline at end of file
diff --git a/fs/commands/runner.py b/fs/commands/runner.py
index e32d036..c5c7e6f 100644
--- a/fs/commands/runner.py
+++ b/fs/commands/runner.py
@@ -8,7 +8,7 @@ from fs.errors import FSError
from fs.path import splitext, pathsplit, isdotfile, iswildcard
import platform
from collections import defaultdict
-import re
+import six
if platform.system() == 'Windows':
@@ -76,8 +76,12 @@ class Command(object):
version = ''
def __init__(self, usage='', version=''):
- self.output_file = sys.stdout
- self.error_file = sys.stderr
+ if six.PY3:
+ self.output_file = sys.stdout.buffer
+ self.error_file = sys.stderr.buffer
+ else:
+ self.output_file = sys.stdout
+ self.error_file = sys.stderr
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()
@@ -210,11 +214,9 @@ class Command(object):
return raw_input('%s: %s ' % (self.name, msg))
def text_encode(self, text):
-
if not isinstance(text, unicode):
text = text.decode('ascii', 'replace')
text = text.encode(self.encoding, 'replace')
-
return text
def output(self, msgs, verbose=False):
@@ -226,10 +228,8 @@ class Command(object):
self.output_file.write(self.text_encode(msg))
def output_table(self, table, col_process=None, verbose=False):
-
if verbose and not self.verbose:
return
-
if col_process is None:
col_process = {}
@@ -248,7 +248,9 @@ class Command(object):
td = col_process[col_no](td)
out_col.append(td)
lines.append(self.text_encode('%s\n' % ' '.join(out_col).rstrip()))
- self.output(''.join(lines))
+ for l in lines:
+ self.output_file.write(l)
+ #self.output(''.join(lines))
def error(self, *msgs):
for msg in msgs:
@@ -275,7 +277,7 @@ class Command(object):
desc = getattr(fs_opener, 'desc', '')
opener_table.append((names, desc))
- opener_table.sort(key = lambda r:r[0])
+ opener_table.sort(key=lambda r: r[0])
def wrap_line(text):
@@ -298,14 +300,13 @@ class Command(object):
for names, desc in opener_table:
self.output(('-' * self.terminal_width, '\n'))
- proto = ', '.join([n+'://' for n in names])
+ proto = ', '.join([n + '://' for n in names])
self.output((self.wrap_dirname('[%s]' % proto), '\n\n'))
if not desc.strip():
desc = "No information available"
wrap_line(desc)
self.output('\n')
-
def run(self):
parser = self.get_optparse()
options, args = parser.parse_args()
@@ -340,7 +341,8 @@ class Command(object):
opener.add(new_opener)
- args = [unicode(arg, sys.getfilesystemencoding()) for arg in args]
+ if not six.PY3:
+ args = [unicode(arg, sys.getfilesystemencoding()) for arg in args]
self.verbose = options.verbose
try:
return self.do_run(options, args) or 0
diff --git a/fs/utils.py b/fs/utils.py
index 28e6538..e0ab693 100644
--- a/fs/utils.py
+++ b/fs/utils.py
@@ -18,15 +18,16 @@ __all__ = ['copyfile',
'find_duplicates',
'print_fs']
-import os
import sys
import stat
+import six
from fs.mountfs import MountFS
from fs.path import pathjoin
from fs.errors import DestinationExistsError, RemoveRootError
from fs.base import FS
+
def copyfile(src_fs, src_path, dst_fs, dst_path, overwrite=True, chunk_size=64*1024):
"""Copy a file from one filesystem to another. Will use system copyfile, if both files have a syspath.
Otherwise file will be copied a chunk at a time.
@@ -491,7 +492,7 @@ def print_fs(fs,
terminal_colors = hasattr(file_out, 'isatty') and file_out.isatty()
def write(line):
- file_out.write(line.encode(file_encoding, 'replace')+'\n')
+ file_out.write(line.encode(file_encoding, 'replace') + b'\n')
def wrap_prefix(prefix):
if not terminal_colors:
@@ -511,11 +512,7 @@ def print_fs(fs,
def wrap_filename(fname):
if not terminal_colors:
return fname
-# if '.' in fname:
-# name, ext = os.path.splitext(fname)
-# fname = '%s\x1b[36m%s\x1b[0m' % (name, ext)
if fname.startswith('.'):
- #fname = '\x1b[2m%s\x1b[0m' % fname
fname = '\x1b[33m%s\x1b[0m' % fname
return fname
dircount = [0]
diff --git a/tox.ini b/tox.ini
index 06f76eb..849eea8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -15,6 +15,16 @@ changedir=.tox
commands = nosetests fs.tests -v \
[]
+
+[testenv:py31]
+commands = nosetests fs.tests -v \
+ []
+deps = distribute
+ six
+ dexml
+ nose
+ winpdb
+
[testenv:py32]
commands = nosetests fs.tests -v \
[]
@@ -24,3 +34,12 @@ deps = distribute
nose
winpdb
+[testenv:py33]
+commands = nosetests fs.tests -v \
+ []
+deps = distribute
+ six
+ dexml
+ nose
+ winpdb
+