Picture Sorting with EXIF

From wiki.network-crawler.de
Jump to: navigation, search
#!/usr/bin/env python

# call with ./exif_sort <from> <to>
# e.g.: ./exif_sort.py /home/pbeyer/Pictures/ /usr/photo/

import sys
import subprocess
import os
import stat
import dircache
from datetime import date, timedelta, datetime
from time import localtime

gmonthly = 1 #if this is set to 1 files are sorted per month
			 #if not they are sorted daily

def walktree (top = "", depthfirst = True):
    names = os.listdir(top)
    if not depthfirst:
        yield top, names
    for name in names:
        try:
            st = os.lstat(os.path.join(top, name))
        except os.error:
            continue
        if stat.S_ISDIR(st.st_mode):
       	    for (newtop, children) in walktree (os.path.join(top, name), depthfirst):
               	yield newtop, children
    if depthfirst:
        yield top, names


def exifcopytopath (picture = "", path = "/usr/photos/"):
	global gmonthly
	#cmd = "exif -t 0x0132 \"" + picture + "\" | awk '/Value/ {split($2,dat,\":\"); printf \"%s%c%s%c%s\",dat[1],\"_\",dat[2],\"_\",dat[3]}'"
	cmd = "exif -t 0x9003 \"" + picture + "\" | awk '/Value/ {split($2,dat,\":\"); printf \"%s%c%s%c%s\",dat[1],\"_\",dat[2],\"_\",dat[3]}'"

	proc = subprocess.check_output(cmd, shell=True);

	#Add exif tags: exiftool -sep ", " -keywords="1980, Summer, holiday" <folder|file>
	#after this you should delete the backups like: find ./ -name *_original -print0 | xargs -0 rm
	foldername = proc
	if foldername:
		if gmonthly:
			tmp = foldername.split('_')
			foldername = tmp[0] + "_" + tmp[1]
		cmd = ""
		head, tail = os.path.split(picture)

		if os.path.exists(path + "/" + foldername + "/" + tail):
			source_creation_date = proc
			dest = "exif -t 0x9003 \"" + path + "/" + foldername + "/" + tail + "\" | awk '/Value/ {split($2,dat,\":\"); printf \"%s%c%s%c%s\",dat[1],\"_\",dat[2],\"_\",dat[3]}'"
			proc = subprocess.check_output(dest, shell=True);
			dest_creation_date = proc
			#print "Source: " + source_creation_date + "Dest: " + dest_creation_date + "\n"
			#source_size = os.stat(picture).st_size
			#dest_size = os.stat(path + "/" + foldername + "/" + tail).st_size
			
			#if source_size <> dest_size:
			#	print "\n**** DUP: source: " + source_size.__str__() + " destination: " + dest_size.__str__() + " ****\n"
			if source_creation_date != dest_creation_date:
				print "\n**** DUP: source: " + source_creation_date + " destination: " + dest_creation_date + " ****\n"
				cmd += "cp -n \"" + picture + "\" \"" + path + "/" + foldername + "/" + tail + ".dup" + "\""
		else:
			cmd = "mkdir -p " + "\"" + path + "/" + foldername + "\"; "
			cmd += "cp -n \"" + picture + "\" \"" + path + "/" + foldername + "\""
	else:
		cmd = "mkdir -p " + "\"" + path + "/" + "not sorted\"; "
		cmd += "cp -n \"" + picture + "\" \"" + path + "/not sorted\""
		
	if cmd != "":
		print cmd
		subprocess.call(cmd, shell=True);

def moviecopypath (movie = "", path = "/usr/photos/"):
	cmd = "mkdir -p " + "\"" + path + "/" + "movies\"; "
	cmd += "cp -n \"" + movie + "\" \"" + path + "/movies\""
	print cmd
	subprocess.call(cmd, shell=True);


directory = sys.argv[1]
path = sys.argv[2]

print "walking " + directory + " ...\n"

for (basepath, children) in walktree(directory, False):
	for child in children:
		str = os.path.join(basepath, child)
#		only use JPG, jpg and jpeg


		if str.find("JPG") <> -1:
			exifcopytopath(str, path)
		if str.find("JPEG") <> -1:
			exifcopytopath(str, path)
		if str.find("jpg") <> -1:
			exifcopytopath(str, path)
		if str.find("jpeg") <> -1:
			exifcopytopath(str, path)

		if str.find("MOV") <> -1:
			moviecopypath(str, path)
		if str.find("AVI") <> -1:
			moviecopypath(str, path)
		if str.find("avi") <> -1:
			moviecopypath(str, path)
		if str.find("mp4") <> -1:
			moviecopypath(str, path)

print "...done"