#!/usr/bin/python
#
# Download.py
# Tabulator XPI snapshot source
#
# Joe Presbrey <presbrey@mit.edu>
# 2010-09-16
#

from flup.server.fcgi import WSGIServer
from tempfile import mkdtemp
from os import chdir, getcwd, path
from subprocess import Popen, PIPE, call

from urllib import urlopen
from re import compile
link = compile('(https?://[^<]+)')

def lastRevision():
    for line in urlopen('http://dig.csail.mit.edu/hg/tabulator/rss-log').readlines():
        if 'guid' in line:
            m = link.findall(line)
            if m:
                return m[0].split('/')[-1]

def latestPackage():
    dout = mkdtemp()
    dold = getcwd()
    # get latest tabulator
    chdir(dout)
    hg_clone = Popen(['hg', 'clone', 'http://dig.csail.mit.edu/hg/tabulator'], stdin=None, stdout=PIPE)
    hg_clone.stdout.read()
    del hg_clone
    # lookup revision
    chdir(dout+'/tabulator')
    hg_log = Popen(['hg', 'log', '-l1'], stdin=None, stdout=PIPE)
    r = hg_log.stdout.read()
    r = r.split('\n')[0] # changeset:   1234:badf00d
    v = r.split(' ')[-1] # 1234:badf00d
    #v = v.split(':',1)[1]  # badf00d
    # rewrite install.rdf
    install_rdf = file('install.rdf.snapshot').read().replace('@@REV@@', v)
    file('install.rdf','w').write(install_rdf)
    # create package
    p_find = Popen(['find', '(', '-name', '.hg*', '-prune', ')', '-or', '-print'], close_fds=True, stdin=None, stdout=PIPE)
    p_zip = Popen(['zip', '-@', '-'], close_fds=True, stdin=p_find.stdout, stdout=PIPE)
    r = p_zip.stdout.read()
    chdir(dold)
    call(['rm', '-rf', dout])
    return r

def package(environ, start_response):
    last = lastRevision()
    arch = '/tmp/tabulator-'+last+'.xpi'

    # start HTTP response
    start_response('200 OK', [
        ('Content-Type', 'application/x-xpinstall'),
        ('Content-Disposition', 'filename='+path.basename(arch))
    ])

    # cache and send archive
    if (not path.exists(arch)):
        file(arch,'wb').write(latestPackage())
    return file(arch,'rb')

if __name__ == '__main__':
    WSGIServer(package).run()

