#!/usr/bin/python
# Rotating zoom timelapse
# 2009-05-05 by Nick Fankhauser

import sys,os,time,Image,ImageFont,ImageDraw,string,math

movie_s=60 # length of movie in seconds
framerate=25
wg=0.02 # circular speed
ely=1.333 # elyptic factor
rad=90 # circle radius
dvdx=320 # movie resolution X
dvdy=240 # movie resolution Y
day=10,15 # from 1000 to 1500

startDir=os.path.abspath(sys.argv[1]).rstrip('/')+'/'
tDir='/tmp/nh'
qt='>/dev/null 2>&1'
if os.path.isdir(tDir): 
 for f in os.listdir(tDir): os.unlink(tDir+'/'+f)
else: os.mkdir(tDir)

def scanDir(d):
 rl=[]
 for fn in os.listdir(d):
  if os.path.isdir(d+fn): rl+=scanDir(d+fn+'/')
  else: rl.append(d+fn)
 return rl

getTime=lambda x : int(filter(lambda y : y in string.digits,os.path.basename(x)))
fSize=lambda x : int(os.stat(x)[6])

def is_day((t,s,f)):
 h=int(time.strftime('%H',time.localtime(t)))
 if h>day[0] and h<day[1]: return True

photoList=scanDir(startDir)
photoList=filter(lambda x:x.find('jpg')==len(x)-3,photoList)
print 'Photos:%d' % len(photoList)
timeList=map(getTime,photoList)
t1,t2=min(timeList),max(timeList)
print 'Start date: %s' % time.strftime('%Y-%m-%d',time.localtime(t1))
print 'End date: %s' % time.strftime('%Y-%m-%d',time.localtime(t2))
duration=(t2-t1)/(60*60*24)
print 'Duration in days: %d' % duration
movie_frames=movie_s*framerate
sizeList=map(fSize,photoList)
bl=zip(timeList,sizeList,photoList)
bl=filter(is_day,bl)
print 'Photos %d - %dh: %d' % (day[0],day[1],len(bl))
bl.sort()
pack_len=len(bl)/duration+1
packs=[bl[x:x+pack_len] for x in range(0,len(bl),pack_len)]
packframes=movie_frames/len(packs)
print 'Number of packs: %d' % len(packs)
print 'Photos per pack: %d' % pack_len
print 'Used per pack: %d' % packframes
fnl=[]
for pack in packs:
 pack2=map(lambda (t,s,f) : (s,f),pack)
 fnl+=map(lambda (s,f) : f,sorted(pack2)[-packframes:])
cnt,wink=0,0.0
img=Image.open(fnl[0])
xc,yc=img.size[0]/4,img.size[1]/4 # center of circle
print 'Movie length in seconds: %d' % movie_s
print 'Movie resolution: %d x %d' % (dvdx,dvdy)
print 'Circle: r = %d, M = %d / %d, ely = %2.2f, v = %2.3f' % (rad,xc,yc,ely,wg)
print 'Length in frames: %d' % len(fnl)
for f in fnl:
 img=Image.open(f)
 xi=int(rad*math.sin(wink)*ely)+xc
 yi=int(rad*math.cos(wink))+yc
 wink-=wg
 img=img.crop((xi,yi,xi+dvdx,yi+dvdy))
 fontSize=img.size[1]/10
 arial=ImageFont.truetype('/usr/share/fonts/corefonts/arialbd.ttf',fontSize)
 draw = ImageDraw.Draw(img) # new draw instance 
 txs=time.strftime('%b%Y',time.gmtime(getTime(f)))
 draw.text((5,img.size[1]-(fontSize+5)),txs,fill='blue',font=arial)
 ofn='%s/img%06d.jpg' % (tDir,cnt)
 img.save(ofn)
 cnt+=1
qt='>/dev/null 2>&1'
ofn=startDir.split('/')[-2]+'.avi'
tp=tDir,ofn,qt
os.system('mencoder mf://%s/*.jpg -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=5000 -o %s -quiet %s' % tp )