#!/www/python/bin/python
'''$URL: svn+ssh://svn/repos/trunk/dulcinea/bin/start-scgi.py $
$Id: start-scgi.py 25002 2004-08-27 20:00:37Z nascheme $

Script invoked by site command to start scgi.
'''

import os, sys
import pwd
import socket
from scgi.quixote_handler import QuixoteHandler, scgi_server, debug
from durus.logger import logger
from dulcinea import local
from dulcinea.site_util import get_config_value, get_pid_file_name, is_local, \
     get_administrator_address, is_live, is_staging, log_to, \
     ensure_uid_gid_not_root, parse_address, is_devel, enable_email
from dulcinea.ui.publisher import DulcineaPublisher

site = os.environ['SITE'] = sys.argv[1]
ensure_uid_gid_not_root()
pid_file_name = get_pid_file_name('scgi', site)
ip, port = parse_address(
    get_config_value('scgi_address', site=site))
site_log_dir = os.path.join(get_config_value('log_directory', site=site), site)
error_log = os.path.join(site_log_dir, 'error.log')
assert is_local(get_config_value('scgi_address', site=site))
logger.setLevel(int(get_config_value('logginglevel', fallback=20, site=site)))

def create_site_publisher(site):
    local.open_database()
    publisher = DulcineaPublisher()
    # set config options
    publisher.config.form_tokens = 1
    publisher.config.display_exceptions = 0
    publisher.config.secure_errors = 1
    publisher.config.session_cookie_path = '/'
    site_log_dir = os.path.join(get_config_value('log_directory', site=site),
                                site)
    publisher.config.access_log = os.path.join(site_log_dir, 'access.log')
    publisher.config.error_log = error_log
    publisher.config.compress_pages = 1
    administrator = get_administrator_address()
    if is_live(site):
        publisher.config.error_email = administrator[0]
        publisher.config.mail_from = administrator
    elif is_staging(site):
        publisher.config.error_email = administrator[0]
        publisher.config.mail_from = administrator
        publisher.config.mail_debug_addr = administrator[0]
    else: # devel
        publisher.config.display_exceptions = 1
        publisher.config.secure_errors = 0
        publisher.config.fix_trailing_slash = 0
        user = pwd.getpwuid(os.geteuid())[0] # Owner of the SCGI process
        user_email = user + '@' + socket.getfqdn()
        publisher.config.mail_debug_addr = get_config_value(
            'mail_debug_addr',
            fallback=user_email,
            site=site)
        publisher.config.mail_from = user_email
        if os.path.exists("/usr/bin/tidy"):
            publisher.TIDY_CHECK = True
    # Adjust any values that are set in the site configuration.
    for config_var in publisher.config.config_vars:
        if get_config_value(config_var, site=site):
            setattr(publisher.config, config_var,
                    get_config_value(config_var, site=site))
    if get_config_value('email_enabled', site=site):
        enable_email()
    publisher.setup_logs()


    # We have to commit the current transaction here, just in case there wasn't
    # an existing session manager object in the DB.  In the case,
    # get_session_manager() created a new session manager and added it to the
    # DB root, but then start_request() will call abort(), losing the
    # modification to the DB root.  The net result is that, without the
    # following commit, the session manager is never written to disk and
    # sessions are always immediately thrown away.
    local.get_connection().commit()

    return publisher


class Handler (QuixoteHandler):
    prefix = ""

    def __init__(self, *args, **kwargs):
        scgi_server.SCGIHandler.__init__(self, *args, **kwargs)
        self.publisher = create_site_publisher(site)
        debug("SCGI server for %s starting up (pid %d)" % (site, os.getpid()))


log_to(error_log)

if is_devel(site):
    max_children = 1 # faster for development
else:
    max_children = 5

pid = os.fork()
if pid == 0:
    pid = os.getpid()
    pidfile = open(pid_file_name, 'w')
    pidfile.write(str(pid))
    pidfile.close()
    try:
        scgi_server.SCGIServer(Handler, port=port,
                               max_children=max_children).serve()
    finally:
        # grandchildren get here too, don't let them unlink the pid
        if pid == os.getpid():
            try:
                os.unlink(pid_file_name)
            except OSError:
                pass

