subdirs.py
'''\
List sub-directories.
commands:
sizes - List directory sizes
recent - Scan for recently modified files
list - Generate a text listing
xml - Generate an XML listing
main - Main function (normal use)
demo - Demo function (show off and test app)
test - Test function (development)
usage:
module.dispatch({command}, args={arguments}) -- calling module from code
$PYTHON module_name {command} {arguments} -- executing module externally
Developer@Sonnack.com
April 2016
'''
from __future__ import print_function
from sys import argv, exc_info
from traceback import extract_tb
from os import path, listdir
from datetime import datetime, timedelta
from time import localtime
from logger import logger, info, debug, trace
from filelist import fileobj, ListFiles, ListFolder, ListFolders
from zoo import add_commas
Log = logger('subdirs')
BasePath = r'C:\CJS\prj\Python\app'
DemoFilepath = r'C:\cjs\www\root\pub'
def create_xml_listing (*args):
'''\
List files in XML format.
arguments:
base-path
output-file
'''
basepath = str(args[0]) if 0 < len(args) else DemoFilepath
listname = str(args[1]) if 1 < len(args) else 'filelist.xml'
Log.debug('xml-listing/parameters: %d' % len(args))
Log.info('xml-listing/basepath: %s' % basepath)
Log.info('xml-listing/listname: %s' % listname)
fn = path.join(basepath, listname)
fp = open(fn, 'w')
try:
print('<?xml version="1.0" encoding="UTF-8"?>', file=fp)
print('<filelist basepath="%s">' % basepath, file=fp)
_create_xml_listing(basepath, fp)
print('</filelist>', file=fp)
Log.info('wrote: %s' % fn)
except:
raise
finally:
fp.close()
return [basepath, fn]
def _create_xml_listing (pathname, fp):
Log.trace('xml-listing: %s' % pathname)
fs = []
ds = []
ns = listdir(pathname)
for n in ns:
fn = path.join(pathname, n)
if path.isfile(fn):
fs.append(fn)
continue
if path.isdir(fn):
ds.append(fn)
continue
print('<directory name="%s">' % pathname, file=fp)
for dn in sorted(ds):
_create_xml_listing(dn, fp)
for fn in sorted(fs):
tm = localtime(path.getctime(fn))
tc = datetime(tm[0],tm[1],tm[2],tm[3],tm[4],tm[5])
tm = localtime(path.getmtime(fn))
tu = datetime(tm[0],tm[1],tm[2],tm[3],tm[4],tm[5])
t = (fn, path.getsize(fn), tc, tu)
s = '<file name="%s" size="%d" cdate="%s" mdate="%s" />'
print(s % t, file=fp)
print('</directory>', file=fp)
def list_directory_sizes (*args):
'''\
List Directory Sizes.
arguments:
base-path
output-file
'''
basepath = args[0] if 0 < len(args) else DemoFilepath
listname = args[1] if 1 < len(args) else 'dir-sizes.list'
Log.debug('list-directory-sizes/parameters: %d' % len(args))
Log.info('list-directory-sizes/basepath: %s' % basepath)
Log.info('list-directory-sizes/listname: %s' % listname)
result = []
t_bytes = _list_directory_sizes(basepath, result)
fn = path.join(basepath, listname)
fp = open(fn, 'w')
try:
print(' Total Bytes Files Dir Bytes Files Directory Name', file=fp)
print('============== ====== ============ ===== =========================================', file=fp)
for d in result:
s1 = add_commas(d[1]) if d[1] != d[3] else '-'
s2 = add_commas(d[2]) if d[2] != d[4] else '-'
s3 = add_commas(d[3])
s4 = add_commas(d[4])
print('%14s %7s %13s %6s %s' % (s1, s2, s3, s4, d[0]), file=fp)
Log.info('wrote: %s' % fn)
except:
raise
finally:
fp.close()
return result
def _list_directory_sizes (pathname, result):
Log.trace('list-directory-size: %s' % pathname)
ds = []
dt = [pathname, 0L, 0L, 0L, 0L]
result.append(dt)
ns = listdir(pathname)
for n in ns:
fn = path.join(pathname, n)
if path.isfile(fn):
dt[3] += path.getsize(fn)
dt[4] += 1
continue
if path.isdir(fn):
ds.append(fn)
continue
dt[1] += dt[3]
dt[2] += dt[4]
for dn in sorted(ds):
t = _list_directory_sizes(dn, result)
dt[1] += t[1]
dt[2] += t[2]
return dt
def create_text_listing (*args):
'''\
List files in a nice text format.
arguments:
base-path
output-file
'''
basepath = str(args[0]) if 0 < len(args) else DemoFilepath
listname = str(args[1]) if 1 < len(args) else 'files.list'
Log.debug('text-listing/parameters: %d' % len(args))
Log.info('text-listing/basepath: %s' % basepath)
Log.info('text-listing/listname: %s' % listname)
ts = ListFolder(basepath)
Log.debug('text-listing/found: %d' % len(ts))
fn = path.join(basepath, listname)
fp = open(fn, 'w')
try:
for t in ts:
Log.trace('Dir: %s' % t[0])
print(t[0], file=fp)
for f in t[1]:
fname = path.join(t[0], f)
fo = fileobj(fname)
Log.trace('File: %s' % f)
print('%-40s %9d %s %s' % (f, fo.fsize, fo.created, fo.updated), file=fp)
print(file=fp)
Log.trace()
Log.info('wrote: %s' % fn)
except:
raise
finally:
fp.close()
return ts
def find_recent_files (*args):
'''\
Find Recent Files.
arguments:
nbr-days-back
base-path
output-file
'''
datespan = int(args[0]) if 0 < len(args) else 3
basepath = str(args[1]) if 1 < len(args) else DemoFilepath
listname = str(args[2]) if 2 < len(args) else 'recent-files.list'
Log.debug('find-recent-files/parameters: %d' % len(args))
Log.info('find-recent-files/datespan: %d' % datespan)
Log.info('find-recent-files/basepath: %s' % basepath)
Log.info('find-recent-files/listname: %s' % listname)
dt = datetime.now() - timedelta(datespan)
ts = ListFolder(basepath)
fs = []
for t in ts:
Log.trace('Dir: %s' % t[0])
for f in t[1]:
fn = path.join(t[0], f)
fo = fileobj(fn)
if fo.updated < dt:
continue
Log.trace('File: %s [%s, %d]' % (f, fo.updated, fo.fsize))
fs.append(fn)
Log.trace()
fn = path.join(basepath, listname)
fp = open(fn, 'w')
try:
for f in fs:
print(f, file=fp)
Log.info('wrote: %s' % fn)
except:
raise
finally:
fp.close()
return fs
def dump_filelist (flist):
Log.trace()
Log.trace('Total Dirs: %d' % len(flist))
Log.trace('Total Files: %d' % sum(map(lambda t: len(t[1]), flist)))
Log.trace()
for t in flist:
Log.trace('Dir: %s (%d files)' % (t[0], len(t[1])))
for f in t[1]:
Log.trace('. File: %s' % path.join(t[0], f))
Log.trace()
def do_test (*args):
Log.trace('test/parameters: %s' % str(args))
basepath = args[0] if 0 < len(args) else DemoFilepath
ts = ListFolder(basepath)
dump_filelist(ts)
return 'Done!'
def do_demo (*args):
Log.trace('demo/parameters: %s' % str(args))
ts = ListFolders(args)
dump_filelist(ts)
return 'Done!'
def do_main (*args):
Log.trace('main/parameters: %s' % str(args))
ts = ListFolders(args)
dump_filelist(ts)
return 'Done!'
def dispatch (cmd, *args):
Log.trace('command: %s' % cmd)
Log.trace('arguments: %d' % len(args))
if cmd == 'sizes': return list_directory_sizes(*args)
if cmd == 'recent': return find_recent_files(*args)
if cmd == 'list': return create_text_listing(*args)
if cmd == 'xml': return create_xml_listing(*args)
if cmd == 'test': return do_test(*args)
if cmd == 'demo': return do_demo(*args)
if cmd == 'main': return do_main(*args)
return 'Nothing to do!'
if __name__ == '__main__':
print('autorun: %s' % argv[0])
Log.start(path.join(BasePath,'subdirs.log'))
Log.level(info())
cmd = argv[1] if 1 < len(argv) else ''
etc = argv[2:] if 2 < len(argv) else []
try:
obj = dispatch(cmd, *etc)
print(obj)
Log.info(obj)
except:
etype, evalue, tb = exc_info()
ts = extract_tb(tb)
Log.error('%s: %s' % (etype.__name__,str(evalue)))
for t in ts[-3:]:
Log.error('[%d] %s (%s)' % (t[1], t[2], t[0]))
Log.error(' %s' % t[3])
raise
finally:
Log.end()
'''eof'''