#!/usr/bin/env python __requires__ = 'BazBase' import os, sys from os.path import * # -- START USER EDIT SECTION # -- Users must edit this section -- code_dir = dirname(abspath(__file__)) # (Required) The base directory of the TG app code. PROJECTNAME = 'xibalba' root_class_name = PROJECTNAME+'.controllers.Root' # (Required) The fully qualified Root class name. project_module_name = PROJECTNAME+'.config' # (Required) The config module name. Replace # PROJECTNAME with your project's name (e.g. wiki20). log_dir = join(code_dir,'log') __import__(PROJECTNAME) # Make sure its requirements get satisfied # -- END USER EDIT SECTION # We do this here, not before the user stuff, in case importing PROJECTNAME # is important import pkg_resources pkg_resources.require("flup") try: sys.stdout = open(join(log_dir, 'flup-stdout.log'),'a') sys.stderr = open(join(log_dir, 'flup-stderr.log'),'a') import time starttime = time.time() from flup.server.fcgi import WSGIServer class RestartingServer(WSGIServer): """A variant on WSGIServer that exits if we've been modified, to allow Apache to restart us.""" def _mainloopPeriodic(self): WSGIServer._mainloopPeriodic(self) mod = getmtime(__file__) if mod > starttime: self._keepGoing = False from logging import FileHandler import logging.handlers import commands class UnbufferedFileHandler(FileHandler): def emit(self, *args, **kw): FileHandler.emit(self, *args, **kw) self.flush() commands.getoutput('fs flush '+self.baseFilename) logging.handlers.UnbufferedFileHandler = UnbufferedFileHandler import turbogears import cherrypy print >> sys.stdout, "starting with basename %s" % basename(__file__) class VirtualPathFilter(object): def on_start_resource(self): infix = '/'+basename(__file__) path = cherrypy.request.path cherrypy.request.path = path.replace(infix,'',1) path = cherrypy.request.object_path cherrypy.request.object_path = path.replace(infix,'',1) path = cherrypy.request.wsgi_environ['SCRIPT_NAME'] cherrypy.request.wsgi_environ['SCRIPT_NAME'] = path.replace( turbogears.config.get('server.webpath')+infix,'',1) def tg_init(): """ Checks for the required data and initializes the application. """ global code_dir global root_class_name global project_module_name last_mark = 0 # Input checks if not code_dir or not isdir(code_dir): raise ValueError("""The code directory setting is missing. The fastcgi code will be unable to find the TG code without this setting.""") if not root_class_name: raise ValueError("""The fully qualified root class name must be provided.""") last_mark = root_class_name.rfind('.') if (last_mark < 1) or (last_mark + 1) == len(root_class_name): raise ValueError("""The user-defined class name is invalid. Please make sure to include a fully qualified class name for the root_class value (e.g. wiki20.controllers.Root).""") print >> sys.stdout, "code dir: %s, log_dir: %s" % (code_dir, log_dir) sys.path.append(code_dir) if exists(join(code_dir, "setup.py")): print >> sys.stdout, "About to update config from %s" % join(code_dir, "dev.cfg") turbogears.update_config(configfile=join(code_dir, "dev.cfg"),modulename=project_module_name) else: print >> sys.stdout, "About to update config from %s" % join(code_dir, "prod.cfg") turbogears.update_config(configfile=join(code_dir, "prod.cfg"),modulename=project_module_name) # This is my convention, totally separate from the # TurboGears/Cherrypy autoreload functionality turbogears.config.update({'restart.file':abspath(__file__)}) # Parse out the root class information for Cherrypy Root class. package_name = root_class_name[:last_mark] class_name = root_class_name[last_mark+1:] print >> sys.stdout, "from %s import %s as Root" % (package_name, class_name) exec('from %s import %s as Root' % (package_name, class_name)) Root._cp_filters = [VirtualPathFilter()] cherrypy.root = Root() # Main section - # Initialize the application, then start the server. print >> sys.stdout, "Before tg_init()" tg_init() print >> sys.stdout, "Before cherrypy.server.start()" sys.stdout.flush() cherrypy.server.start(initOnly=True, serverClass=None) print >> sys.stdout, "After cherrypy.server.start()" sys.stdout.flush() print >> sys.stdout, "before import cherrypy/wsgiapp" from cherrypy._cpwsgi import wsgiApp print >> sys.stdout, "Before wsgiserver(application=wsgiapp).run()" sys.stdout.flush() server = RestartingServer(wsgiApp) except Exception,e: from traceback import format_exception import pwd,socket tup = sys.exc_info() def errApp(environ, start_response): start_response('500 Flup Error', [('Content-Type', 'text/plain')], sys.exc_info()) for l in format_exception(*tup): yield l whoami = pwd.getpwuid(os.getuid())[0] hostname = socket.gethostname() yield "To restart: touch %s\n" % (abspath(__file__)) errserver = RestartingServer(errApp) errserver.run() print >> sys.stdout, "Error server exiting, probably due to modification." sys.stdout.flush() else: server.run() print >> sys.stdout, "WSGIServer exiting, probably due to modification." sys.stdout.flush()