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])