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