Monday, July 29, 2013

Tip: Python rename Images by creation date

Hi,
This is a short tool I wrote that renames images files in a directory by creation date. There may be some bugs but hope you find it helpful.
cheers,
-Nate

#!/usr/bin/python

#Inspired by Greg Hewgil's online tutorial on sorting files by creation time


import getopt,sys

#for file stuff
import os
import fnmatch

#for sorting files by creation date
import time

#for printing stuff
from pprint import pprint





##rename all files like name_### by creation time
#@note skips if any files by formatted name exist in directory
#@note by default looks in current directory
#@note if call it twice over the creation times will be affected hence will loose the ordering
##
def renameFileInDirectory(d = '.', ext = '*.png', name = 'out'):    

    newNamePrefix = name
    
    #hold all the file names
    result = []
    
    if os.path.isdir(d):
        print 'Great Found Directory >> %s\n' %d
        
        files = os.listdir(d) #only file names not full path need glob for full path
        goodFiles = fnmatch.filter( files, ext )
        
        #renaming happens here
        newName = [ newNamePrefix+'_'+str(x+1)+'.'+ext[2:] for x in range(0,len(goodFiles)) ]
        pathWithNewName = [ os.path.join(d,f) for f in newName]
        
        #make sure dont rename if any new names are taken already
        isAnyNewFileInDir = False
        isAnyNewFileInDir = any( x for x in pathWithNewName if os.path.isfile(x) )
        
        if isAnyNewFileInDir: 
            print 'Error! Cannot Rename Because A file By New Name Exists'
            sys.exit()
        
        
        pprint( newName )
        

        
        
        #sorts files by creation time
        #first it makes a list of all file names and a stat thingie
        #
        #then it sorts them by the second thingies key st_ctime 
        #
        #that is what this does
        #sorted([(fn, os.stat(fn)) for fn in goodFiles], key = lambda x: x[1].st_ctime)
        #
        #finally we organize what to print 
        #z[1].st_ctime  is like os.stat(path).st_ctime it gives secs back
        # 
        #the time.ctime(z[1].st_ctime) makes a string like "Sun Jul 28 18:17:13 2013" from seconds
        arg = [(z[0], time.ctime(z[1].st_ctime)) for z in sorted([(fn, os.stat(fn)) for fn in goodFiles], key = lambda x: x[1].st_ctime)]

        pprint(arg)
        
        result = [ arg[x][0] for x in range(0,len(arg)) ]
        

        for f,name in zip(result,newName):
            os.rename(f,name)
  
    else:
        print 'Requires Directory >> %s' %d   
    
    return result


def usage():
    print "usage: rename [-d|--directory]"
    print "-d,--directory  find files in "
    print "-e,--extension  find files with wild card  ex: <*.png>"
    print "-n,--name  new name "
def main():


    
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hden:", ["help","directory=","extension=","name="])
    except getopt.GetoptError, err:
        #print help info and exit
        print str(err)
        usage()
        sys.exit(2)
    
    dir = '.'   
    ext = '*.png'
    name = 'out'
    
    for o, a in opts:
        if o in ("-h","--help"):
            usage()
            sys.exit()
        elif o in ("-d","--directory"):
            dir = a
        elif o in ("-e","--extension"):
            ext = a
        elif o in ("-n","--name"):
            name = a
            
    allFile = renameFileInDirectory(dir,ext,name)
    print allFile
    
if __name__ == '__main__':
    print 'current _name is: '+__name__
    main()