Skip to content

Instantly share code, notes, and snippets.

@ledzep2
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ledzep2/cf36238653b4a8dff074 to your computer and use it in GitHub Desktop.
Save ledzep2/cf36238653b4a8dff074 to your computer and use it in GitHub Desktop.
Move all photos/videos/audios to date directories and optionally rename to a date format. Use exiftool to extract REAL creation date.
import os, sys, datetime, shutil, subprocess as sp
class D(object):
def __init__(self, format = '%Y/%m', filename_format = None):
self.files = {}
self.format = format
self.filename_format = filename_format
with open('.args', 'w') as f:
pass
self.p = sp.Popen(['exiftool','-stay_open', '1','-@', '.args'], stdout=sp.PIPE)
print self.p
def extract(self, lines):
r = filter(lambda x:x.find('Date/Time Original') > -1, lines)
if not r:
r = filter(lambda x:x.find('Create Date') > -1, lines)
if not r:
r = filter(lambda x:x.find('Creation Date') > -1, lines)
if r:
r = r[0].split(':', 1)[1].replace(':', '').strip()
if r == '00000000 000000':
print 'bad timestamp'
return None
try:
r = datetime.datetime.strptime(r, '%Y%m%d %H%M%S')
except:
r = r.split('+')
if len(r) == 1:
r = r[0].split('-')
r = datetime.datetime.strptime(r[0], '%Y%m%d %H%M%S')
return r
def exif(self, path):
with open('.args', 'a') as f:
f.write('-fast2\n')
f.write(path + '\n')
f.write('-execute\n')
buf = ''
while True:
buf += self.p.stdout.read(1)
if buf.endswith('{ready}'):
return buf
def f(self, dir):
for i in os.listdir(dir):
name, ext = os.path.splitext(i)
if i.startswith('.') or ext.lower() in ('.ini', '.exe', '.lvix'):
continue
path = os.path.join(dir, i)
if os.path.isfile(path):
try:
#ret = subprocess.check_output(['exiftool', '-fast', path]).split('\r\n')
ret = self.exif(path).split('\r\n')
except Exception, e:
print e
print 'Error getting exif on file', path
continue
ret = self.extract(ret)
if not ret:
print 'Warning: no creation date found for file', path
else:
print i, ret
self.files[path] = ret
else:
self.f(path)
def make_path(self, dir, date):
if not date is None:
path = os.path.join(dir, date.strftime(self.format))
else:
path = os.path.join(dir, 'unknown')
if not os.path.isdir(path):
try:
os.makedirs(path)
except:
pass
return path
def move(self, dir):
names = set()
for k, v in self.files.iteritems():
dst = self.make_path(dir, v)
if self.filename_format and v:
tmp, ext = os.path.splitext(k)
fn = v.strftime(self.filename_format)
while fn in names:
fn = fn + '2'
names.add(fn)
dst = os.path.join(dst, fn + ext)
print 'moving %s to %s' % (k, dst)
shutil.move(k, dst)
d = D('%Y\\%m', '%Y%m%d-%H%M%S')
d.f(sys.argv[1])
print len(d.files), 'to move'
r = raw_input('Continue?')
if not r in ('y', 'yes'):
print 'Aborted'
sys.exit(0)
d.move(sys.argv[2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment