Welcome, guest | Sign In | My Account | Store | Cart
import os
import sys

# NOTE
# ====
# Renaming should happen in groups based on extention.
# All files should first be renamed with a unique ID.

################################################################################

ERR = False
ALL = ''.join(map(chr, xrange(256)))
NUM = '0123456789'
LET = ALL.translate(ALL, NUM)
EXT = 'avi', 'bmp', 'gif', 'jpg', 'wmv'

################################################################################

class Filename:

    def __init__(self, filename):
        self.filename = filename.lower()
        split = self.filename.rsplit('.', 1)
        self.name = split[0]
        self.ext = split[1] if len(split) == 2 else ''
        self.let = self.name.translate(ALL, NUM)
        self.num = self.name.translate(ALL, LET)

    def __eq__(self, other):
        return bool(self.num) and other == int(self.num)

################################################################################

def main():
    try:
        arguments = sys.argv[1:]
        assert arguments
        for path in arguments:
            assert os.path.isdir(path)
        for path in arguments:
            engine(path)
    except:
        sys.stdout.write('Usage: %s <directory>' % os.path.basename(sys.argv[0]))

def engine(path):
    global ERR
    for root, dirs, files in os.walk(path):
        # gather all relevant names
        files = filter(lambda name: name.num and name.ext in EXT, map(Filename, files))
        # find all taken number names
        taken = []
        for name in files[:]:
            if name.name == name.num:
                files.remove(name)
                taken.append(name)
        # put all names in order
        files.sort(compare)
        taken.sort(compare)
        # rename all non-number names
        count = 0
        for name in files:
            while count in taken:
                taken.remove(count)
                count += 1
            name.new = str(count)
            count += 1
        # condense all numerical names
        for name in taken:
            if name.num != str(count):
                name.new = str(count)
                files.append(name)
            count += 1
        # rename files needing new names
        for name in files:
            old = os.path.join(root, name.filename)
            try:
                os.rename(old, os.path.join(root, name.new + '.' + name.ext))
            except:
                sys.stderr.write('%sError: %s' % (ERR and '\n' or '', old))
                ERR = True

def compare(x, y):
    integer = cmp(x.let, y.let)
    return integer if integer else cmp(int(x.num), int(y.num))

################################################################################
    
if __name__ == '__main__':
    main()

Diff to Previous Revision

--- revision 1 2007-03-20 18:22:34
+++ revision 2 2012-07-04 01:23:12
@@ -1,11 +1,20 @@
 import os
 import sys
 
+# NOTE
+# ====
+# Renaming should happen in groups based on extention.
+# All files should first be renamed with a unique ID.
+
+################################################################################
+
 ERR = False
+ALL = ''.join(map(chr, xrange(256)))
 NUM = '0123456789'
-ALL = ''.join(map(chr, xrange(256)))
 LET = ALL.translate(ALL, NUM)
-EXT = 'avi', 'gif', 'jpg', 'wmv'
+EXT = 'avi', 'bmp', 'gif', 'jpg', 'wmv'
+
+################################################################################
 
 class Filename:
 
@@ -20,6 +29,8 @@
     def __eq__(self, other):
         return bool(self.num) and other == int(self.num)
 
+################################################################################
+
 def main():
     try:
         arguments = sys.argv[1:]
@@ -29,19 +40,23 @@
         for path in arguments:
             engine(path)
     except:
-        sys.stdout.write(os.path.basename(sys.argv[0]) + ' <directory>')
+        sys.stdout.write('Usage: %s <directory>' % os.path.basename(sys.argv[0]))
 
 def engine(path):
     global ERR
     for root, dirs, files in os.walk(path):
+        # gather all relevant names
         files = filter(lambda name: name.num and name.ext in EXT, map(Filename, files))
+        # find all taken number names
         taken = []
         for name in files[:]:
             if name.name == name.num:
                 files.remove(name)
                 taken.append(name)
+        # put all names in order
         files.sort(compare)
         taken.sort(compare)
+        # rename all non-number names
         count = 0
         for name in files:
             while count in taken:
@@ -49,11 +64,13 @@
                 count += 1
             name.new = str(count)
             count += 1
+        # condense all numerical names
         for name in taken:
             if name.num != str(count):
                 name.new = str(count)
                 files.append(name)
             count += 1
+        # rename files needing new names
         for name in files:
             old = os.path.join(root, name.filename)
             try:
@@ -65,6 +82,8 @@
 def compare(x, y):
     integer = cmp(x.let, y.let)
     return integer if integer else cmp(int(x.num), int(y.num))
+
+################################################################################
     
 if __name__ == '__main__':
     main()

History