-
-
Save otger/9765072 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Name: EXIFmover | |
# Forked from EXIFmover.py by Brian Klug (@nerdtalker / [email protected]) | |
# Purpose: | |
# Move Files into directory based on dates | |
# Designed to un-clusterfuck the Dropbox camera upload directory which is a mess as all files are | |
# uploaded to same folder. | |
# Moves files into /YEAR/MONTH eg /2014/03 | |
# Creates directory if it doesn't exist, moves into that directory if it exists | |
# Files without "YYYY-mm-dd" pattern on its name are scanned looking for exif data | |
# Files without EXIF are keep at root folder | |
# Only files with valid extensions are moved | |
# This is experimental and one-way in a destructive sense, I take no responsibility | |
# if this absolutely destroys your directory structure for some reason | |
# I STRONGLY recommend making a copy of Camera Uploads, then running this on the copy, first | |
# Requires EXIF-PY to be installed and importable in order to check exif. If all your files are named using | |
# the "YYYY-mm-dd" pattern, there is no need to have EXIF-PY installed | |
# EXIF-PY can be obtained from https://github.com/ianare/exif-py or using pip: "sudo pip install ExifRead" | |
# Run simply inside "Camera Upload" folder or whatever you have the media you want to organize | |
# (eg from ipython "run exifmover.py" inside "Camera Upload") | |
# or "python exifmover.py" | |
# Tested on Ubuntu | |
# Extremely fast: Sorted more than 1400 pictures ranging 4 years in less than a second | |
try: | |
import exifread | |
except: | |
exifread = None | |
print "exifread was not found, exif data won't be used" | |
import os | |
import time | |
import re | |
start_time = time.time() | |
current_path = os.path.abspath(os.getcwd()) | |
# current_path = "/home/otger/Dropbox/Camera Uploads" | |
file_names = os.listdir(current_path) | |
print "Found {0} items on folder {1}".format(len(file_names), current_path) | |
valid_extensions = ["png", "jpg", "jpeg", "mp4"] | |
## expression matches: YYYY-mm-dd | |
re_date = re.compile(r"(\d{4})[:\-\.]?(\d{2})[:\-\.]?\d{2}") | |
for fname in file_names: | |
file_path = os.path.join(current_path, fname) | |
if os.path.isfile(file_path): | |
if fname.split('.')[-1] in valid_extensions: | |
year = month = None | |
fname_date = re_date.search(fname) | |
if fname_date: | |
(year, month) = fname_date.groups() | |
elif exifread: | |
f = open(file_path) | |
try: | |
tags = exifread.process_file(f) | |
except Exception, ex: | |
print "Couldn't read tags on " + fname | |
print ex.message | |
continue | |
finally: | |
f.close() | |
exif_date = re_date.search(str(tags.get("Image DateTime", "NA"))) | |
if not exif_date: | |
exif_date = re_date.search(str(tags.get("EXIF DateTimeOriginal", "NA"))) | |
if not exif_date: | |
print "Couldn't find date on exif for " + fname | |
continue | |
(year, month) = exif_date.groups() | |
print file_path + "date extracted by exif: {0}-{1}".format(year,month) | |
else: | |
print "exifread not found, skipping " + file_path | |
dst_path = os.path.join(current_path, year, month) | |
dst_file_path = os.path.join(dst_path, fname) | |
# print "{0} would be moved to {1}".format(fname, dst_path) | |
if not os.path.exists(dst_path): | |
print "Creating folder: " + dst_path | |
try: | |
os.makedirs(dst_path) | |
except Exception, ex: | |
print "Failed to create folder " + dst_path | |
print ex.message | |
try: | |
print "Moving from {0} to {1}".format(file_path, dst_file_path) | |
os.rename(file_path, dst_file_path) | |
except Exception, ex: | |
print "Oh noes. That didn't work for some reason:" | |
print ex.message | |
else: | |
print "Skipping " + file_path | |
else: | |
print "Not a file: " + file_path | |
print 'Done. Execution took {:0.3f} seconds'.format((time.time() - start_time)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment