Newer
Older
tdir / tdir
#!/usr/local/bin/python
"""
tdir - Display Formatted Directory Listings
Copyright (c) 2001, TundraWare Inc., All Rights Reserved.
"""

# python Library Imports

import getopt
import os
import string
import sys

# Version info

VERSION = "$Id: tdir,v 1.54 2001/06/24 01:35:50 tundra Exp $"


# Booleans

FALSE = 0
TRUE = not FALSE

# Output formatting constants.

OWIDTH = 80                 # Output width
COLWIDTH = 19               # Width of each column
TWIDTH = COLWIDTH - 1       # Text width
MAXCOL, INDENT = divmod(OWIDTH, COLWIDTH) # No of output cols & indent
PAD = " "                   # Padding character
SEP = "."                   # Filename "extension" separator
TRUNC = "^"                 # Character indicating name truncation

# Defaults

RECURSE = FALSE             # No recursion
SHOWDIR = TRUE              # Show directories in listing
SHOWFILE = TRUE             # Show files in listing


def OrderByExtension(list):
    ExtList = {}
    ExtList[""] = []             # List of files with no extension
    for x in list:
        y = string.rfind(x, SEP)
        if y != -1:                    # File has extension
            ext = x[y+1:]
            name =  x[:y]
            if not ExtList.has_key(ext):
                ExtList[ext]= []
            ExtList[ext].append(name)
        else:                    # File has no extension
            ExtList[""].append(x)
    return ExtList


def OutputColumns(list, ISDIRLIST):
    col = 0
    if ISDIRLIST:     # If listing directory, printed length
        BIAS = 2      # is longer by BIAS chars than actual name
    else:
        BIAS = 0
    for x in list:
        if col == MAXCOL:
            sys.stdout.write("\n")
            col = 0
        if len(x) > TWIDTH - BIAS:
            x = x[:TWIDTH - BIAS - 1 ] + TRUNC
        if ISDIRLIST:
            x = "[" + x + "]"
        if col == 0:
                sys.stdout.write(INDENT * PAD)
        sys.stdout.write(x + (COLWIDTH - len(x)) * PAD)
        col += 1
    sys.stdout.write("\n\n")
    

def DisplayOutput(dir, DirList, FileList):
    sys.stdout.write(dir.replace("\\", "/") + ":" + "\n")
    if SHOWDIR or SHOWFILE :
	sys.stdout.write("\n")
    if len(DirList) > 0:
        DirList.sort()
        OutputColumns(DirList, TRUE)
    if len(FileList) > 0:
        ExtList = OrderByExtension(FileList)
        Ext = ExtList.keys()
        Ext.sort()
        for x in Ext:
            FileList = ExtList[x]
            if len(FileList) > 0:
                FileList.sort()
                if x == "":
                    sep = x
                else:
                    sep = SEP
                sys.stdout.write("{" + sep + x + "}\n")
                OutputColumns(FileList, FALSE)

                                 
def BuildFileList (args, dir, files):
    DirList = []
    FileList = []
    for x in files:
        if os.path.isdir(dir + "/" + x) and SHOWDIR:
            DirList.append(x)
        elif SHOWFILE:
            FileList.append(x)
    DisplayOutput(dir, DirList, FileList)


def Usage():
     sys.stdout.write("tdir - Copyright (c) 2001, TundraWare Inc., All Rights Reserved. \n\n")
     sys.stdout.write("  usage: tdir [-Rdfhtv] [-c #] [-s c] [-w #] [dir...]  where,\n\n")
     sys.stdout.write("            -R    Recur down each named directory tree\n")
     sys.stdout.write("            -c #  Column width\n")
     sys.stdout.write("            -d    Do not display directories in output\n")
     sys.stdout.write("            -f    Do not display files in output\n")
     sys.stdout.write("            -h    Display this help information\n")
     sys.stdout.write("            -s c  Separator character\n")
     sys.stdout.write("            -t    Display only the directory tree - same as -Rdf\n")
     sys.stdout.write("            -v    Display tdir version information\n")
     sys.stdout.write("            -w #  Width of output\n")
     sys.stdout.write("        dir... List of directories to display.  Defaults to ./\n")


# Program entry and command line processing

try:
    opts, args = getopt.getopt(sys.argv[1:], '-Rc:dfhs:tvw:')
except getopt.GetoptError:
    Usage()
    sys.exit(2)
    
for opt, val in opts:
    if opt == "-R":
        RECURSE = TRUE
    if opt == "-c":
        COLWIDTH = int(val)
    if opt == "-d":
        SHOWDIR = FALSE
    if opt == "-f":
        SHOWFILE = FALSE
    if opt == "-h":
        Usage()
        sys.exit(0)
    if opt == "-s":
         SEP = val[0]
    if opt == "-t":
         RECURSE = TRUE
         SHOWDIR = FALSE
         SHOWFILE = FALSE
    if opt == "-v":
        sys.stdout.write(VERSION + "\n")
        sys.exit(0)
    if opt == "-w":
        OWIDTH = int(val)

if OWIDTH < COLWIDTH:
     sys.stdout.write("Huh? Column width exceeds output width!\n")
     sys.exit(2)
    
TWIDTH = COLWIDTH - 1       # Text width
MAXCOL, INDENT = divmod(OWIDTH, COLWIDTH) # No of output cols & indent

if len(args) == 0:          # Default to local directory if none given
    args = ["./"]

for root in args:
     if not os.path.isdir(root):
          sys.stdout.write(root + " is not a directory!\n")
          sys.exit(2)                           
     if RECURSE:
          os.path.walk(root, BuildFileList, None)
     else:
          BuildFileList(None, root, os.listdir(root))