Began restructuring Rename() and added a new supporting RenameIt() method.
1 parent 95a694b commit 9510a5b85fc519df04f34e10233be392f7d1bcf1
@tundra tundra authored on 17 Feb 2010
Showing 1 changed file
View
341
tren.py
 
PROGNAME = "tren.py"
BASENAME = PROGNAME.split(".py")[0]
PROGENV = BASENAME.upper()
RCSID = "$Id: tren.py,v 1.152 2010/02/17 16:31:35 tundra Exp $"
RCSID = "$Id: tren.py,v 1.153 2010/02/17 20:07:53 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
ESCAPE = "ESCAPE"
ERRORCONTINUE = "ERRORCONTINUE"
EXISTSUFFIX = "EXISTSUFFIX"
EXTDELIM = "EXTDELIM"
FORCERENAM = "FORCERENAM"
FORCERENAME = "FORCERENAME"
GLOBAL = "GLOBAL"
MAXLINELEN = "MAXLINELEN"
QUIET = "QUIET"
REGEX = "REGEX"
eFILEOPEN = "Cannot open file '%s': %s!"
eLINELEN = "Specified line length too short! Must be at least %s" % MINLEN
eNAMELONG = "Renaming '%s' to new name '%s' too long! (Maximum length is %s.)"
eNAMESHORT = "Renaming '%s' to new name '%s' too short! (Minimum length is %s.)"
eNOTHINGTODO = "Nothing to do!"
eNULLARG = "%s cannot be empty!"
eTOOMANYINC = "Too many includes! (Max is %d) Possible circular reference?" % MAXINCLUDES
 
 
#####
# Informational Messages
#####
 
iFORCEDREN = "Forced Rename:"
iRENAME = "Rename:"
iSKIPPING = "Target Exists, Rename Skipped:"
iNEWOLDSAME = "New Name '%s' Same As The Old Name. %s"
iNOTHINGTODO = "Nothing to do."
iRENFORCED = "Target '%s' Exists. Creating Backup."
iRENSKIPPED = "Target '%s' Exists. Renaming Of '%s' Skipped."
 
 
#####
# Usage Prompts
"usage: " + PROGNAME + " [-abCcdEefGghqtvwXx] [-I file] [-L string] [-r old=new]... [-S suffix] file|dir file|dir ...",
" where,",
" -a Rename within the entire file or directory name (Default)",
" -C Do case-sensitive renaming (Default)",
" -c Collapse case when doing string substitution",
" -d Dump debugging information",
" -e Only perform renaming within extension portion of or directory name",
" -E Continue renaming even after an error is encountered",
" -f Force renaming even if target file or directory name already exists",
" -c Collapse case when doing string substitution (Default: False)",
" -d Dump debugging information (Default: False)",
" -e Only perform renaming within extension portion of or directory name (Default: False)",
" -E Continue after an error is encountered (Default: False)",
" -f Force renaming even if target file or directory name already exists (Default: False)",
" -G Rename only the first instance of the specified string (Default)",
" -g Replace all instances (global rename) of the old string with the new",
" -h Print help information",
" -g Replace all instances (global rename) of the old string with the new (Default: False)",
" -h Print help information (Default: False)",
" -I file Include command line arguments from file",
" -L string File extension delimiter string (Default: %s)" % DEFEXT,
" -P char Use 'char' as the escape sequence (Default: %s)" % DEFESC,
" -q Quiet mode, do not show progress",
" -q Quiet mode, do not show progress (Default: False)",
" -R char Separator character for -r rename arguments (Default: %s)" % DEFSEP,
" -r old=new Replace old with new in file or directory names",
" -S suffix Suffix to use when renaming existing filenames (Default: %s)" % DEFSUFFIX,
" -t Test mode, don't rename, just show what the program *would* do",
" -v Print detailed program version information and continue",
" -t Test mode, don't rename, just show what the program *would* do (Default: False)",
" -v Print detailed program version information and continue (Default: False)",
" -w Line length of diagnostic and error output (Default: %s)" % DEFLEN,
" -X Treat the renaming strings literally (Default)",
" -x Treat the old replacement string as a Python regular expression",
" -x Treat the old replacement string as a Python regular expression (Default: False)",
]
 
#----------------------------------------------------------#
# Global Variables & Data Structures #
ESCAPE : DEFESC, # Escape string
ERRORCONTINUE : False, # Do not continue after error
EXISTSUFFIX : DEFSUFFIX, # What to tack on when renaming existing targets
EXTDELIM : DEFEXT, # Name/Extension delimiter
FORCERENAM : False, # Do not rename if target already exists
FORCERENAME : False, # Do not rename if target already exists
GLOBAL : False, # Only rename first instance of old string
MAXLINELEN : DEFLEN, # Width of output messages
QUIET : False, # Display progress
REGEX : False, # Do not treat old string as a regex
DEBUG : debug flag,
CASESENSITIVE : case sensitivity flag,
ERRORCONTINUE : error continuation flag,
EXTDELIM : name/Extension delimiter string,
FORCERENAM : force renaming flag,
FORCERENAME : force renaming flag,
GLOBAL : global replace flag,
MAXLINELEN : max output line length,
QUIET : quiet output flag,
REGEX : regular expression enable flag,
#####
 
def Rename(self):
 
 
# Make sure we actually have work to do
 
if not self.SortViews[ORDERBYCMDLINE] or not self.RenRequests:
 
ErrorMsg(eNOTHINGTODO)
return
 
# Create a list of all renaming to be done.
# This includes the renaming of any existing targets.
 
 
renamelist = []
for target in self.SortViews[ORDERBYCMDLINE]:
 
basename, pathname = self.RenNames[target][BASE], self.RenNames[target][PATHNAME]
oldname, pathname = self.RenNames[target][BASE], self.RenNames[target][PATHNAME]
newname = oldname
 
for renrequest in self.RenRequests:
 
old, new = self.ResolveRenameStrings(renrequest[OLD], renrequest[NEW])
oldstrings = []
# Handle the case when old = "".
# This means to *replace the entire* old name with new.
if not old:
old = basename
old = oldname
 
# Collapse case if requested
 
name = basename
name = oldname
if not renrequest[CASESENSITIVE]:
 
name = name.lower()
old = old.lower()
# so as not to mess up the replacement indicies.
 
oldstrings.reverse()
for i in oldstrings:
basename = basename[:i] + new + basename[i + len(old):]
 
# Now that we have a new name, attempt the actual renaming
# operation
 
# First make sure the new name meets length constraints
 
RenamingError = False
newname = newname[:i] + new + newname[i + len(old):]
 
# If the new name is different from the old one, add
# result to renaming table in the format:
#
# (path, old name, new name)
 
 
if newname != oldname:
renamelist.append((pathname, oldname, newname))
 
else:
InfoMsg(iNEWOLDSAME % newname)
 
# Make sure we actually have something to do
 
if not renamelist:
 
InfoMsg(iNOTHINGTODO)
return
 
# Iterate over the list of renamings
 
newnames = []
for pathname, oldname, newname in renamelist:
 
# Get names into absolute path form
oldname = pathname + oldname
newname = pathname + newname
 
# See if our proposed renaming is about to stomp on an
# existing file, and create a backup if forced renaming
# requested.
 
# NOTE: We have to keep track of every new name produced.
# When running in test mode, this is the only way to know
# what *would* end up on the disk (in case a previous
# renaming operation creates a filename that is now in
# conflict with a subseqent renaming target.
if (newname in newnames) or os.path.exists(newname):
 
if ProgramOptions[FORCERENAME]:
 
# Create the backup
bkuname = newname + ProgramOptions[EXISTSUFFIX]
newnames.append(bkuname)
InfoMsg(iRENFORCED % newname)
self.RenameIt(newname, bkuname)
 
# Rename the original
 
newnames.append(newname)
self.RenameIt(oldname, newname)
 
else:
InfoMsg(iRENSKIPPED % (newname, oldname))
 
# No target conflict, just do the requested renaming
 
else:
 
newnames.append(newname)
self.RenameIt(oldname, newname)
 
# End of 'Rename()'
 
 
#####
# Actually Rename A File (Or Show What Would Happen)
#####
 
def RenameIt(self, oldname, newname):
return
 
# End of 'RenameIt()'
 
"""
# First make sure the new name meets length constraints
 
RenamingError = False
if len(basename) < MINNAMELEN:
ErrorMsg(eNAMESHORT% (target, basename, MINNAMELEN), EXIT=not ProgramOptions[ERRORCONTINUE])
RenamingError = True
 
if len(basename) > MAXNAMELEN:
ErrorMsg(eNAMELONG % (target, basename, MAXNAMELEN), EXIT=not ProgramOptions[ERRORCONTINUE])
RenamingError = True
 
newname = pathname + basename
if (target != newname) and not RenamingError:
 
renamejobs = [(target, newname)]
renaming = " %s %s %s %s" % (iRENAME, renamejobs[0][0], ARROW, renamejobs[0][1])
# Figure out if the newname already exists
 
newexists = False
if os.path.exists(newname):
newexists = True
renameexisting = newname + ProgramOptions[EXISTSUFFIX]
renamejobs.append((newname, renameexisting))
forcedren = " %s %s %s %s" % (iFORCEDREN, renamejobs[1][0], ARROW, renamejobs[1][1])
skipping = " %s %s %s %s" % (iSKIPPING, renamejobs[0][0], ARROW, renamejobs[0][1])
 
# In test mode, just show what we would do
 
if ProgramOptions[TESTMODE]:
 
if newexists:
 
# Forced renaming of existing targets
 
if ProgramOptions[FORCERENAM]:
InfoMsg(forcedren, TESTMODE)
 
# Skip renaming if target already exists
 
else:
InfoMsg(skipping, TESTMODE)
 
# Target does not exist or forced renaming is in effect, do the rename
 
if not newexists or ProgramOptions[FORCERENAM]:
InfoMsg(renaming, TESTMODE)
 
# Actually do the renaming
else:
print target + "---->"+ newname
 
# End of 'Rename()'
 
"""
 
 
#####
# Resolve Rename Strings
 
 
return [old, new]
 
# End of 'ReolveRenameStrings()'
# End of 'ResolveRenameStrings()'
 
 
# End of class 'RenameTargets'
# End of 'DumpState()'
 
 
#####
# Print An Error Message
# Print An Error Message, Exiting Program As Required
#####
 
def ErrorMsg(emsg, EXIT=False):
 
 
for emsg in l:
PrintStderr(PROGNAME + " " + eERROR + ": " + emsg)
 
if EXIT:
if EXIT or not ProgramOptions[ERRORCONTINUE]:
sys.exit(1)
 
# End of 'ErrorMsg()'
 
#####
# Print An Informational Message
#####
 
def InfoMsg(dmsg, msgtype):
 
l = ConditionLine(dmsg)
 
for dmsg in l:
PrintStdout(PROGNAME + " " + msgtype + ": " + dmsg)
def InfoMsg(imsg):
 
l = ConditionLine(imsg)
 
msgtype = ""
if ProgramOptions[TESTMODE]:
msgtype = TESTMODE
 
if not ProgramOptions[QUIET]:
for dmsg in l:
PrintStdout(PROGNAME + " " + msgtype + ": " + imsg)
 
# End of 'InfoMsg()'
 
 
if opt == "-e":
ProgramOptions[TARGET] = EXT
 
if opt == "-f":
ProgramOptions[FORCERENAM] = True
ProgramOptions[FORCERENAME] = True
 
if opt == "-G":
ProgramOptions[GLOBAL] = False