Moved checks for existing targets from Rename() to RenameIt().
Made check for existing target recursive so existing backups would get backed up.
Implemented min/max new filename length enforcement.
Restructured Rename() so it didn't have to iterate twice over the work queue.
1 parent 9510a5b commit bad774134cfa09a82116321c58d214a8b1aad4ff
@tundra tundra authored on 17 Feb 2010
Showing 1 changed file
View
231
tren.py
 
PROGNAME = "tren.py"
BASENAME = PROGNAME.split(".py")[0]
PROGENV = BASENAME.upper()
RCSID = "$Id: tren.py,v 1.153 2010/02/17 20:07:53 tundra Exp $"
RCSID = "$Id: tren.py,v 1.154 2010/02/17 22:07:53 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
DEFSUFFIX = ".backup" # String used to rename existing targets
DEFESC = "\\" # Escape character
EXT = "Ext" # Rename target is extension
INCL = "I" # Include file command line option
INDENT = " " # Indent string for nested messages
NAM = "Nam" # Rename target is name
NULLESC = "Escape string" # Cannot be null
NULLEXT = "Extension delimiter string" # Cannot be null
NULLRENSEP = "Old/New separator string" # Cannot be null
#####
# Informational Messages
#####
 
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."
 
iRENAMING = "Renaming '%s' To '%s'."
 
#####
# Usage Prompts
#####
#####
 
def Rename(self):
 
self.newnames = []
self.indentlevel = -1
 
# Create a list of all renaming to be done.
# This includes the renaming of any existing targets.
 
renamelist = []
for target in self.SortViews[ORDERBYCMDLINE]:
 
oldname, pathname = self.RenNames[target][BASE], self.RenNames[target][PATHNAME]
newname = oldname
oldstrings.reverse()
for i in oldstrings:
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 the new name is different from the old one, rename it.
 
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
self.__RenameIt(pathname, oldname, newname)
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()'
 
"""
def __RenameIt(self, pathname, oldname, newname):
 
self.indentlevel += 1
indent = self.indentlevel * INDENT
newlen = len(newname)
# 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
 
 
"""
 
 
if newlen < MINNAMELEN:
ErrorMsg(indent + eNAMESHORT% (oldname, newname, MINNAMELEN))
return
 
if newlen > MAXNAMELEN:
ErrorMsg(indent + eNAMELONG % (oldname, newname, MAXNAMELEN))
return
 
# Get names into absolute path form
 
fullold = pathname + oldname
fullnew = pathname + newname
 
# Let the user know what we're trying to do
 
InfoMsg(indent + iRENAMING % (fullold, fullnew))
 
# See if our proposed renaming is about to stomp on an
# existing file, and create a backup if forced renaming
# requested. We such backups with a recursive call to
# ourselves so that length and backups of backups are
# enforced.
 
# 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 (fullnew in self.newnames) or os.path.exists(fullnew):
 
if ProgramOptions[FORCERENAME]:
 
# Create the backup
 
bkuname = newname + ProgramOptions[EXISTSUFFIX]
InfoMsg(indent + iRENFORCED % fullnew)
self.__RenameIt(pathname, newname, bkuname)
self.newnames.remove(fullnew)
# Rename the original
 
self.__RenameIt(pathname, oldname, newname)
 
 
else:
InfoMsg(indent + iRENSKIPPED % (fullnew, fullold))
 
# No target conflict, just do the requested renaming
 
else:
 
self.newnames.append(fullnew)
 
self.indentlevel -= 1
 
# End of '__RenameIt()'
 
#####
# Resolve Rename Strings
#####
 
if opt == "-P":
if len(val) == 1:
ProgramOptions[ESCAPE] = val
else:
ErrorMsg(eARGLENGTH % (NULLESC, "1"), EXIT=True)
ErrorMsg(eARGLENGTH % (NULLESC, 1), EXIT=True)
 
if opt == "-q":
ProgramOptions[QUIET] = True
 
if opt == '-R':
if len(val) == 1:
ProgramOptions[RENSEP] = val
else:
ErrorMsg(eARGLENGTH % (NULLRENSEP, "1"), EXIT=True)
ErrorMsg(eARGLENGTH % (NULLRENSEP, 1), EXIT=True)
 
if opt == "-r":
req = {}
req[OLD], req[NEW] = GetOldNew(val)