El programa a continuación es un ejemplo de las cosas que se pueden hacer con Python 3. Para mí fue una excusa para aprender lo siguiente:
- Uso de ‘.format’ para mostrar contenido con formato (mucho mejor que interpolación de cadena de caracteres con ‘%’)
- La librería ‘OptionParser’ (Mejor que Getoptions)
- Trucos con ‘list comprehensions’ , ordenaciones
- Referencias a funciones
(Les debo el manejo de recursividad, me dio algo de flojera escribirlo :-))
#!/usr/bin/env python3
from optparse import OptionParser, OptionValueError
from collections import namedtuple
import locale, os, time
from _locale import LC_ALL
locale.setlocale(LC_ALL, "en_US.UTF-8") # locale -a
usage = '''
%prog [options] [path1 [path2] [... pathN]]]
The paths are optional; if not given '.' is used
@author: Jose Vicente Nunez (josevnz@kodegeek.com)
'''
Entry = namedtuple('Entry', 'name size modified')
def orderCheck(option, opt_str, value, parser):
if value in ['n', 'name']:
parser.values.order = "name"
elif value in ['m', 'modified']:
parser.values.order = "modified"
elif value in ['s', 'size']:
parser.values.order = "size"
else:
raise OptionValueError("Invalid value for --order received: {0}".format(value))
def getKeyByName(entry):
return entry.name
def getKeyBySize(entry):
return int(entry.size)
def getKeyByModif(entry):
return int(entry.modified())
def createTuple(path):
bits = os.stat(path)
return Entry(path, bits.st_size, bits.st_mtime)
def doLs(path, hidden, getKey):
if (not os.path.isdir(path)):
return path
if hidden: # On Unix, hidden files start with '.'
return sorted([ createTuple(os.path.join(path, entry)) for entry in os.listdir(path) ], key=getKey, reverse=False)
return sorted([ createTuple(os.path.join(path, entry)) for entry in os.listdir(path) if entry[0] != "." ], key=getKey, reverse=False)
def doLsR(path, hidden, getKey):
# TODO
pass
def formatEntries(entries, modified, sizes):
if entries == None:
return
dirs = 1
files = 0
for entry in entries:
mod = time.ctime(entry.modified) if modified else ""
size = entry.size if sizes else ""
if os.path.isfile(entry.name):
files += 1
else:
dirs += 1
print("{modif}{theSize:>10,} bytes{name:>35}".format(modif=mod, theSize=size, name=entry.name))
print("files={0}, directories={1}".format(files, dirs))
parser = OptionParser(usage=usage)
parser.add_option("-H", "--hidden", action="store_true", dest="hidden", default=False, help='Show hidden files [default: off]')
parser.add_option("-m", "--modified", action="store_true", dest="modified", default=False, help='Show last modified date/time [default: off]')
parser.add_option("-r", "--recursive", action="store_true", dest="recursive", default=False, help='Recurse into sub-directories [default: off]')
parser.add_option("-s", "--sizes", action="store_true", dest="sizes", default=False, help='Show sizes [default: off]')
parser.add_option("-o", "--order", action="callback", type="string", callback=orderCheck, default="name", help='''Order by ('name', 'n', 'modified', 'm', 'size', 's') [default: name]''')
(options, args) = parser.parse_args()
hidden = options.hidden
modified = options.modified
recursive = options.recursive
sizes = options.sizes
order = options.order
getKey = getKeyByName
if order == 'size':
getKey = getKeyBySize
elif order == 'modified':
getKey = getKeyByModif
paths = args if len(args) > 0 else ["."]
lsCallback = doLs if not recursive else doLsR
for path in paths:
formatEntries(lsCallback(path, hidden, getKey), modified, sizes)