view pavement.py @ 4:cf673c093b61 default tip

paver runserver now shows errors if cajoling failed.
author Atul Varma <varmaa@toolness.com>
date Sun, 07 Jun 2009 20:44:44 -0700
parents 6737bc744b46
children
line wrap: on
line source

import md5
import os
import subprocess
import wsgiref
import wsgiref.simple_server
from paver.easy import *

DEFAULT_PORT = 8080
DEFAULT_HOST = '127.0.0.1'

class CajolerWebApp(object):
    def __init__(self, cajoler_path):
        self.cajoler_path = cajoler_path
        self.cache = {}

    def cajole(self, filename):
        contents = open(filename).read()
        hash = md5.md5(contents).hexdigest()
        if hash not in self.cache:
            # TODO: This isn't threadsafe.
            # TODO: There's no way to evict entries from the cache.
            cajoled_filename = "output.co.js"
            output_filename = "output.txt"
            popen = subprocess.Popen([self.cajoler_path,
                                      "-i", filename,
                                      "-o", cajoled_filename],
                                     stdout=open(output_filename, 'w'),
                                     stderr=subprocess.STDOUT)
            popen.wait()
            if popen.returncode == 0:
                content = open(cajoled_filename).read()
                self.cache[hash] = Bunch(success = True,
                                         content = content)
                os.remove(cajoled_filename)
            else:
                output = open(output_filename).read()
                self.cache[hash] = Bunch(success = False,
                                         content = output)
            os.remove(output_filename)
        return self.cache[hash]

    def app(self, env, start_response):
        path = env['PATH_INFO']
        parts = path.split('/')[1:]
        if len(parts) == 1:
            filename = os.path.join('caja-js', parts[0])
            if os.path.exists(filename) and not os.path.isdir(filename):
                result = self.cajole(filename)
                if not result.success:
                    start_response('500 Internal Server Error',
                                   [('Content-type', 'text/plain')])
                    return ["Cajoling failed:\n\n%s" % result.content]
                start_response('200 OK',
                               [('Content-type', 'text/javascript')])
                return [result.content]
        start_response('404 Not Found',
                       [('Content-type', 'text/plain')])
        return ['Not found: %s' % path]

@task
@cmdopts((['port=', 'p', 'port to bind to'],
          ['host=', 'o', 'host to bind to'],
          ['cajoler-path=', 'c', 'path to cajole_html']))
def runserver(options):
    port = int(options.get('port', DEFAULT_PORT))
    host = options.get('host', DEFAULT_HOST)
    if not options.get('cajoler_path'):
        raise Exception('Required option: --cajoler-path.')
    print "Running server at %s port %d, press Ctrl-C to stop." % (host,
                                                                   port)
    app = CajolerWebApp(options.cajoler_path)
    server = wsgiref.simple_server.make_server(host, port, app.app)
    server.serve_forever()