#!/home/<user>/bin/python/bin/python
#
# File name: tg_fastcgi.fcgi
#
# This module provides the glue for running TurboGears applications behind 
# FastCGI-enabled web servers. The code in this module depends on the fastcgi
# module downloadable from here:
#
# http://www.saddi.com/software/py-lib/py-lib/fcgi.py
#
# NOTE: The fcgi.py file needs to be placed in a location that is on the
# system path, such as the same the directory as the tg_fastcgi.py file
# or in the base directory of the TG app code.
#
# To configure this module, please edit the three variables in the "USER EDIT
# SECTION" before starting the TG application.  Also remember to edit the
# top of this file with the correct Python installation information.

import cherrypy
import sys
import os
from os.path import *
import pkg_resources
import turbogears

pkg_resources.require("TurboGears")

# -- START USER EDIT SECTION
# -- Users must edit this section -- 
code_dir = ''                               # (Required) The base directory of the TG app code.
root_class_name = ''                        # (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 = ''                                # (Optional) The log directory. Default = code_dir.
# -- END USER EDIT SECTION

class VirtualPathFilter(object):
    def on_start_resource(self):
        if not cherrypy.config.get('virtual_path_filter.on', False):
	    return
	prefix = cherrypy.config.get('virtual_path_filter.prefix', '')
	if not prefix:
	    return

	path = cherrypy.request.object_path
	if path == prefix:
	    path = '/'
	elif path.startswith(prefix):
	    path = path[len(prefix):]
	else:
	    raise cherrypy.NotFound(path)
	cherrypy.request.object_path = path


def tg_init():
    """ Checks for the required data and initializes the application. """

    global code_dir
    global root_class_name
    global log_dir
    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).""")    

    sys.path.append(code_dir)

    # Change the directory so the TG log file will not be written to the
    # web app root.
    if log_dir and isdir(log_dir):
        os.chdir(log_dir)
    else:
        os.chdir(code_dir)
        log_dir = code_dir

    sys.stdout = open(join(log_dir, 'stdout.log'),'a')
    sys.stderr = open(join(log_dir, 'stderr.log'),'a')        

    if exists(join(code_dir, "setup.py")):
        turbogears.update_config(configfile=join(code_dir, "devcfg.py"),modulename=project_module_name)
    else:
        turbogears.update_config(configfile=join(code_dir, "prodcfg.py"),modulename=project_module_name)

    # Set environment to production to disable auto-reload and
    # add virutal path information.
    cherrypy.config.update({
        'global': {'server.environment': 'production'},
	'/' : { 'virtual_path_filter.on' : True,
	        'virtual_path_filter.prefix' : '/tg_fastcgi.fcgi' }
		})

    # 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:]
    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.
tg_init()

from fcgi import WSGIServer
cherrypy.server.start(initOnly=True, serverClass=None)

from cherrypy._cpwsgi import wsgiApp
WSGIServer(application=wsgiApp).run()

