Newer
Older
twander / twander.py
#!/usr/local/bin/python
# twander - Wander around the file system
# Copyright (c) 2002 TundraWare Inc.  All Rights Reserved.


PROGNAME = "twander"
RCSID = "$Id: twander.py,v 1.22 2002/10/30 00:00:23 tundra Exp $"
VERSION = RCSID.split()[2]


#----------------------------------------------------------#
#          Variables User Might Change                     #
#----------------------------------------------------------#



#------------------- Nothing Below Here Should Need Changing ------------------#


#----------------------------------------------------------#
#                     Imports                              #
#----------------------------------------------------------#

import anygui as gui
import getopt
import os
import sys


#----------------------------------------------------------#
#               Aliases & Redefinitions                    #
#----------------------------------------------------------#



#----------------------------------------------------------#
#              Constants & Literals                        #
#----------------------------------------------------------#



#####
# Constants
#####

FALSE      = 0 == 1           # Booleans
TRUE       = not FALSE


#####
# General Literals
#####

DIR_LDELIM = '['              # Directory left dsply. delimiter
DIR_RDELIM = ']'              # Directory left dsply. delimiter
PSEP       = os.sep           # Character separating path components


#####
# Configuration File Related Literals
#####

CONFFILE   = os.path.join(os.getenv("HOME"), # Name of default config file
                          "." +
                          PROGNAME +
                          "rc")

CMDKEY     = r'&'             # Command key delimiter
COMMENT    = r"#"             # Comment character
NAME       = r'[NAME]'        # Substitution field in config files
ENVIRO     = r'$'             # Introduces environment variables


#----------------------------------------------------------#
#            Prompts, & Application Strings                #
#----------------------------------------------------------#


#####
# Error & Warning  Messages
#####

eBADROOT = " %s Is Not A Directory"
eDUPKEY  = "Duplicate Key In Configuration File Found In Entry: \'%s\'"
eERROR   = "ERROR"
eNOCONF  = "Cannot Find Configuration File: %s"
eOPEN    = "Cannot Open File: %s"
eTOOMANY = "You Can Only Specify One Starting Directory."

wCMDKEY  = "Configuration File Entry For: \'%s\' Has No Command Key Defined."
wWARN    = "WARNING"


#####
# Informational Messages
#####



#####
# Usage Prompts
#####

uTable = [PROGNAME + " " + VERSION + " - Copyright 2002, TundraWare Inc., All Rights Reserved\n",
          "usage:  " + PROGNAME + " [-d dir] [-hv] [starting directory] where,\n",
          "          startdir name of directory in which to begin (default: current dir)",
          "          -c file  name of configuration file (default: " + CONFFILE + ")",
          "          -h       print this help information",
          "          -v       print detailed version information",
          ]



#####
# Prompts
#####



#----------------------------------------------------------#
#        Global Variables & Data Structures                #
#----------------------------------------------------------#


#####
# GUI Related Setup
#####

MainApp   = gui.Application()
MainWin   = gui.Window(height=300,
                       width=500
                       )
DirList   = gui.ListBox()
MainWin.add(DirList,
            hstretch=1,
            vstretch=1,
            top=1,
            bottom=1,
            left= 1,
            right=1
            )



MainApp.add(MainWin)



#---------------------------Code Begins Here----------------------------------#


#----------------------------------------------------------#
#           Object Base Class Definitions                  #
#----------------------------------------------------------#

    

#----------------------------------------------------------#
#           Supporting Function Definitions                #
#----------------------------------------------------------#

#####
# Return Ordered List Of Directories & Files For Current Root
#####

def BuildDirList(rootdir):

    dList, fList = [], []

    dList.append("..")
    for file in os.listdir(rootdir):
        if os.path.isdir(os.path.join(rootdir,file)):
            dList.append(DIR_LDELIM + file + DIR_RDELIM)
        else:
            fList.append(file)

    dList.sort()
    fList.sort()
    return dList + fList

# End 'BuildDirList()'


#####
# Print An Error Message
#####

def ErrMsg(emsg):
    print PROGNAME + " " + VERSION + " " + eERROR + ": " + emsg

# End of 'ErrMsg()'


#####
# Parse & Process The Configuraton File
#####

def ParseRC():

    try:
        cf = open(conf)
    except:
        ErrMsg(eOPEN % conf)
        sys.exit(1)

    # Process and massage the configuration file
    for line in cf.read().splitlines():

        # Lex for comment token and discard until EOL
        # A line beginning with the comment token is thus
        # turned into a blank line, which is discarded.

        idx = line.find(COMMENT)
        if idx > -1:             # found a comment character
            line = line[:idx]

        # Anything which gets through the next conditional
        # must be a non-blank line - i.e., Configuration information
        # we care about, so process it and save for future use.

        if line != "":
            fields = line.split()
            for x in range(1,len(fields)):

                # Process environment variables
                if fields[x][0] == ENVIRO:
                    fields[x] = os.getenv(fields[x][1:])

            # Get command key value and store in dictionary

            keypos = fields[0].find(CMDKEY) # Look for key delimiter

            # No delimiter or delimiter at end of string
            if (keypos < 0) or (CMDKEY == fields[0][-1]):
                WrnMsg(wCMDKEY % fields[0])
                key = fields[0]             # Use whole word as index

            # Found legit delimiter
            else:
                key = fields[0][keypos+1]   # Use selected key as index

            if key in rcfile:
                ErrMsg(eDUPKEY % fields[0]) # Duplicate key found
                cf.close()
                sys.exit(1)
                
            # Save command name and command using key as index
            rcfile[key] = ["".join(fields[0].split(CMDKEY)),
                           " ".join(fields[1:])
                          ]

    cf.close()

# End of 'ParseRC()'


#####
# Print Usage Information
#####

def Usage():
    for x in uTable:
        print x
        
# End of 'Usage()'


#####
# Print A Warning Message
#####

def WrnMsg(wmsg):
    print PROGNAME + " " + VERSION + " " + wWARN + ": " + wmsg

# End of 'WrnMsg()'



#----------------------------------------------------------#
#                  Program Entry Point                     #
#----------------------------------------------------------#

# Newline to make sure cursor of invoking window is
# at LHS in case we get errors or warnings.

print ""

# Command line processing

try:
    opts, args = getopt.getopt(sys.argv[1:], '-c:hv')
except getopt.GetoptError:
    Usage()
    sys.exit(1)

conf    = CONFFILE
rootdir = "." + PSEP
for opt, val in opts:
    if opt == "-c":
        conf = val
    if opt == "-h":
        Usage()
        sys.exit(0)
    if opt == "-v":
        print RCSID
        sys.exit(0)

# Can only have 0 or 1 arguments
# Make sure any starting directory argument is legit

if len(args) > 1:
    ErrMsg(eTOOMANY)
    sys.exit(1)

if len(args) == 1:
    rootdir = args[0]
    if not os.path.isdir(rootdir):
        ErrMsg(eBADROOT % rootdir)
        sys.exit(1)


# This program requires a config file

if not os.path.exists(conf):
    ErrMsg(eNOCONF % conf)
    sys.exit(1)

rcfile = {}
ParseRC()

# Fill the control with directory contents
DirList.items = BuildDirList(rootdir)

MainWin.set(title= PROGNAME + " " + VERSION + "    -     Examining:    " + rootdir)
MainApp.run()