Skip to content

Instantly share code, notes, and snippets.

@marlonmarcello
Forked from cliss/organize-photos.py
Created March 31, 2014 06:34
Show Gist options
  • Save marlonmarcello/9886491 to your computer and use it in GitHub Desktop.
Save marlonmarcello/9886491 to your computer and use it in GitHub Desktop.
Photo management script. This script will copy photos from "sourceDir" into a tree the script creates, with folders representing month and years, and photo names timestamped. Completely based on the work of the amazing Dr. Drang; see here: http://www.leancrew.com/all-this/2013/10/photo-management-via-the-finder/. Casey Liss did more edits as you…
#!/usr/bin/python
import sys
import os, shutil
import subprocess
import os.path
import json
from datetime import datetime
######################## Functions #########################
def photoDate(f):
"Return the date/time on which the given photo was taken."
cDate = subprocess.check_output(['sips', '-g', 'creation', f])
cDate = cDate.split('\n')[1].lstrip().split(': ')[1]
return datetime.strptime(cDate, "%Y:%m:%d %H:%M:%S")
###################### Main program ########################
# Where the photos are and where they're going.
sourceDir = os.environ['HOME'] + '/Pictures/Fotos'
destDir = os.environ['HOME'] + '/Pictures/Pessoais'
errorDir = destDir + '/Unsorted'
# The format for the new file names.
fmt = "%Y-%m-%d %H-%M-%S"
# The problem files.
problems = []
# Get all the JPEGs in the source folder.
photos = []
for root, subdirs, files in os.walk(sourceDir):
for file in files:
if os.path.splitext(file)[1].lower() in ('.jpg', '.jpeg'):
t = root.replace(sourceDir, '')
sub = t.replace(file, '')
photos.append({"dir": sub, "name": file})
# Prepare to output as processing occurs
lastMonth = 0
lastYear = 0
# Create the destination folder if necessary
if not os.path.exists(destDir):
os.makedirs(destDir)
if not os.path.exists(errorDir):
os.makedirs(errorDir)
# Copy photos into year and month subfolders. Name the copies according to
# their timestamps. If more than one photo has the same timestamp, add
# suffixes 'a', 'b', etc. to the names.
for photo in photos:
# print "Processing %s..." % photo
#original = sourceDir + '/' + photo
original = sourceDir + photo["dir"] + "/" + photo["name"]
suffix = 'a'
try:
pDate = photoDate(original)
yr = pDate.year
mo = pDate.month
if not lastYear == yr or not lastMonth == mo:
sys.stdout.write('\nProcessing %04d-%02d...' % (yr, mo))
lastMonth = mo
lastYear = yr
else:
sys.stdout.write('.')
newname = pDate.strftime(fmt)
thisDestDir = destDir + '/%04d/%02d' % (yr, mo)
if not os.path.exists(thisDestDir):
os.makedirs(thisDestDir)
duplicate = thisDestDir + '/%s.jpg' % (newname)
while os.path.exists(duplicate):
newname = pDate.strftime(fmt) + suffix
duplicate = destDir + '/%04d/%02d/%s.jpg' % (yr, mo, newname)
suffix = chr(ord(suffix) + 1)
shutil.copy2(original, duplicate)
except Exception:
shutil.copy2(original, errorDir + "/" + photo["name"])
problems.append(photo["name"])
except:
sys.exit("Execution stopped.")
# Report the problem files, if any.
if len(problems) > 0:
print "\nProblem files:"
print "\n".join(problems)
print "These can be found in: %s" % errorDir
@marlonmarcello
Copy link
Author

I just improved the script making it run through subfolders. The credits goes to Dr. Drang and Casey Liss for the hard work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment