Quick and dirty image sorting script


Recently my wife and I decided to try and wrangle our images into some sort of logical order for easy accessibility. After some thought we decided on a simple system of image-directory/year/month for our images and since our old images were spread out across several folders in no particular order I decided to write a script to copy everything into the right folders.

Here is the Python script I wrote to sort all of our images by creation date into properly ordered folders.1

Usage:

./picturesorter.py /images/source /images/dest
#!/usr/bin/python

import sys, shutil, os, time, tempfile
from os.path import join, getsize
from stat import *

if len(sys.argv) != 3:
	print "Usage: "+sys.argv[0]+" [source] [target]"
	sys.exit(-1)

if not os.path.isdir(sys.argv[1]):
	print "'"+sys.argv[1] +"' is not a valid source directory"
	sys.exit(-1)

if not os.path.isdir(sys.argv[2]):
	print "'"+sys.argv[2] + "' is not a valid destination directory"
	sys.exit(-1)

#Define your system's copy command here
copyCmd = "cp -f"

def walk( root, recurse=0, pattern='*', return_folders=0 ):
	import fnmatch, os, string
	
	result = []

	try:
		names = os.listdir(root)
	except os.error:
		return result

	pattern = pattern or '*'
	pat_list = string.splitfields( pattern , ';' )
	
	for name in names:
		fullname = os.path.normpath(os.path.join(root, name))

		for pat in pat_list:
			if fnmatch.fnmatch(name, pat.upper()) or fnmatch.fnmatch(name, pat.lower()):
				if os.path.isfile(fullname) or (return_folders and os.path.isdir(fullname)):
					result.append(fullname)
				continue
		
		if recurse:
			if os.path.isdir(fullname) and not os.path.islink(fullname):
				result = result + walk( fullname, recurse, pattern, return_folders )
			
	return result

def getTime(file):
	result = []
	try:
		st = os.stat(file)
	except IOError:
		print "failed to get information about", file
	else:
		result = time.localtime(st[ST_MTIME])
	return result

if __name__ == '__main__':
	log_fd, logfilename = tempfile.mkstemp (".log","psort_")
	logfile = os.fdopen(log_fd, 'w+')
	print "Scanning '%s' for images..." % sys.argv[1]
	files = walk(sys.argv[1], 1, '*.jpg;*.gif;*.png;*.psd;*.tif', 0)
	
	logfile.write("Found %d images in '%s'...\n" % (len(files), sys.argv[1]))
	print "Copying %d images to '%s'" % (len(files),sys.argv[2])
	for file in files:
		fileTime = getTime(file)
		
		destination = os.path.join(sys.argv[2], "%s" % fileTime.tm_year)
		
		if not os.path.isdir(destination):
			os.mkdir(destination)
			logfile.write("Created directory '%s''n" % destination)
		
		destination = os.path.join(destination, time.strftime("%m", fileTime))
		
		if not os.path.isdir(destination):
			os.mkdir(destination)
			logfile.write("Created directory '%s''\n" % destination)
		
			
		os.system("%s \"%s\" \"%s\"" % (copyCmd, file, destination))
		if os.path.isfile(os.path.join(destination,os.path.basename(file))):
			print ".",
			logfile.write("'%s' => '%s''\n" % (file,destination))
		else:
			logfile.write("[FAIL] '%s' => '%s''\n" % (file,destination))
	
	print "Finished copying files, log file avaliable at %s" % logfilename
	logfile.close()

No related content found.

  1. Directory walking code taken from here with slight modification to make patterns truly case insensitive. []

Leave a comment