###
# Copyright (c) 2006-2007, Jared Kuolt
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice, 
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright 
#       notice, this list of conditions and the following disclaimer in the 
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of the SuperJared.com nor the names of its 
#       contributors may be used to endorse or promote products derived from 
#       this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.
###

###
# The TextDrive Django Installer
###

import os, sys, pwd
from os.path import expanduser

export_lines = """export PATH=$PATH:$HOME/local/django_src/django/bin
export PYTHONPATH=$PYTHONPATH:$HOME/local:$HOME/local/django_src:$HOME/django_projects"""

def create_directories(dirs):
    for dirname in dirs:
        try:
            print "Creating `%s`" % dirname
            os.mkdir(expanduser(dirname))
        except OSError:
            print "`%s` exists. Skipping." % dirname
            pass

def install_django_project():
    print "What is your Django project name? (Characters and underscores only!)"
    project_name = raw_input()
    
    print "What is the domain for the project? (NO WWW!)"
    domain_name = raw_input()
    
    project_dir = '~/django_projects/%s' % project_name
    project_init = '%s/init.sh' % project_dir
    
    required_dirs = (project_dir,)
    create_directories(required_dirs)
    
    lighttpd_vhost_conf = \
"""$HTTP["host"] =~ "(www\.)?%(domain_name)s" {
    server.document-root = base + "/web/public/"
    fastcgi.server = (
        "/%(project_name)s.fcgi" => (
            "main" => (
                "socket" => base + "/django_projects/%(project_name)s/%(project_name)s.socket",
                "check-local" => "disable",
            )
        ),
    )
    alias.url = (
        "/media/" => base + "/local/django_src/django/contrib/admin/media/",
    )

    url.rewrite-once = (
        "^(/static.*)$" => "$1",
        "^(/media.*)$" => "$1",
        "^favicon.ico$" => "$1",
        "^(/.*)$" => "/%(project_name)s.fcgi$1",
    )
}
""" % {'project_name':project_name, 'domain_name':domain_name}

    print "Writing Virtual Host for project."
    f = open(expanduser('~/etc/lighttpd/vhosts.d/%s.conf' % project_name), 'w')
    f.write(lighttpd_vhost_conf)
    f.close()
    
    print "Writing Virtual Host include in main Lighttpd configuration file."
    f = open(expanduser('~/etc/lighttpd/lighttpd.conf'), 'a+')
    f.write('include "vhosts.d/%s.conf"\n' % project_name)
    
    project_init_script = \
"""#!/usr/local/bin/bash
%(export_lines)s

PROJECT_NAME="%(project_name)s"
PROJECT_DIR="$HOME/django_projects/$PROJECT_NAME"
PID_FILE="$PROJECT_DIR/$PROJECT_NAME.pid"
SOCKET_FILE="$PROJECT_DIR/$PROJECT_NAME.socket"
MANAGE_FILE="$PROJECT_DIR/manage.py"
METHOD="prefork"

case "$1" in
    start)
      # Starts the Django process
      echo "Starting Django project"
      /usr/local/bin/python $MANAGE_FILE runfcgi maxchildren=2 maxspare=2 minspare=1 method=$METHOD socket=$SOCKET_FILE pidfile=$PID_FILE
  ;;
    stop)
      # stops the daemon by cat'ing the pidfile
      echo "Stopping Django project"
      kill `/bin/cat $PID_FILE`
  ;;
    restart)
      ## Stop the service regardless of whether it was
      ## running or not, start it again.
      echo "Restarting process"
      $0 stop
      $0 start
  ;;
    *)
      echo "Usage: init.sh (start|stop|restart)"
      exit 1
  ;;
esac""" % {'export_lines':export_lines, 'project_name':project_name}

    print "Writing init script for project."
    f = open(expanduser(project_init), 'w')
    f.write(project_init_script)
    f.close()
    os.system('chmod 755 %s' % project_init)
    print ""
    print "Django project ready to be uploaded into the %s directory. Make sure you don't overwrite the init.sh file!" % project_dir
    print "Now, create a cron job to start your init.sh file on server boot."

def install_django():
    # Download and place django and flup in ~/local directory
    required_directories = ('~/local', '~/django_projects')
    create_directories(required_directories)
    os.chdir(expanduser('~/local'))
    print "Downloading Django"
    os.system('wget http://www.djangoproject.com/download/0.96/tarball/')
    print "Extracting Django"
    os.system('tar zxvf Django-0.96.tar.gz')
    os.system('mv Django-0.96 django_src')
    
    print "Downloading Flup"
    os.system('wget http://www.saddi.com/software/flup/dist/flup-r2311.tar.gz')
    print "Extracting Flup"
    os.system('tar -zxvf flup-r2311.tar.gz')
    os.system('mv flup-r2311/flup/ ./')
    os.system('rm -rf flup-r2311*')
    
    print "Django and Flup have been placed in their proper directories."
    
    for f in (expanduser('~/.shrc'), expanduser('~/.profile')):
        a = open(f, 'a+')
        a.write(export_lines)
    
    print ""
    print "~* Django Installation Complete *~"
    print "You may now upload your Django project into the `django_projects` directory."

def install_lighttpd():
    print "Installing Lighttpd"
    
    required_directories = ('~/var', 
                            '~/var/log', 
                            '~/var/run', 
                            '~/etc/rc.d', 
                            '~/etc/lighttpd', 
                            '~/etc/lighttpd/vhosts.d',)
                            
    create_directories(required_directories)
    
    print "What is your Port number?"
    port_number = raw_input()
    username = pwd.getpwuid(os.getuid())[0]
    
    lighttpd_conf = """
### Lighttpd Configuration File

#-- Lighttpd modules
server.modules              = ( "mod_rewrite",
                                "mod_redirect",
                                "mod_access",
                                "mod_cgi",
                                "mod_fastcgi",
                                "mod_compress",
                                "mod_accesslog",
                                "mod_alias" )

#-- CGI configuration
cgi.assign = ( ".pl"  => "/usr/local/bin/perl",
               ".cgi" => "/usr/local/bin/perl" )

#-- Mimetypes
include_shell "cat /usr/local/etc/lighttpd_mimetypes.conf"

#-- Default domain
#
# Replace USERNAME with your TextDrive user name, PORTNUMBER with 
# your assigned port number (you'll need only one).

server.username             = "%(username)s"
server.port                 = %(port_number)s
server.groupname            = server.username
var.base                    = "/users/home/" + server.username
server.document-root        = base + "/web/public/"
server.pid-file             = base + "/var/run/lighttpd.pid"
server.tag                  = "Lighttpd | TextDriven"
server.indexfiles           = ( "index.php", "index.html",
                                "index.htm", "default.htm" )
url.access-deny             = ( "~", ".inc", ".ht" )

#-- Logging
accesslog.filename          = base + "/var/log/lighttpd.access.log"
server.errorlog             = base + "/var/log/lighttpd.error.log"

#-- VHOSTS
#
# Uncomment the line bellow (remove the #) and replace APPNAME with 
# the name of your Rails or Django Application.
# If you have more than one Rails or Django application, you'll need to add 
# another include "vhosts.d/APPNAME.conf" and replace APPNAME with 
# for each of your applications.

# include "vhosts.d/APPNAME.conf"
""" % {'username':username, 'port_number':port_number}
    print "Writing lighttpd.conf"
    f = open(expanduser('~/etc/lighttpd/lighttpd.conf'), 'w')
    f.write(lighttpd_conf)
    f.close()
    
    lighttpd_init = \
"""#!/bin/sh
# This is for Starting/Stopping/Restarting Lighttpd. You won't need
# to edit anything.

 HOME=/users/home/`whoami`
 LIGHTTPD_CONF=$HOME/etc/lighttpd/lighttpd.conf
 PIDFILE=$HOME/var/run/lighttpd.pid
 export SHELL=/bin/sh

case "$1" in
    start)
      # Starts the lighttpd deamon
      echo "Starting Lighttpd"
      PATH=$PATH:/usr/local/bin /usr/local/sbin/lighttpd -f $LIGHTTPD_CONF
  ;;
    stop)
      # stops the daemon bt cat'ing the pidfile
      echo "Stopping Lighttpd"
      kill `/bin/cat $PIDFILE`
  ;;
    restart)
      ## Stop the service regardless of whether it was
      ## running or not, start it again.
      echo "Restarting Lighttpd"
      $0 stop
      $0 start
  ;;
    reload)
      # reloads the config file by sending HUP
      echo "Reloading config"
      kill -HUP `/bin/cat $PIDFILE`
  ;;
    *)
      echo "Usage: lighttpdctrl (start|stop|restart|reload)"
      exit 1
  ;;
esac"""
    print "Writing Lighttpd init script"
    lighttpd_init_file = '~/etc/rc.d/lighttpd.sh'
    f = open(expanduser(lighttpd_init_file), 'w')
    f.write(lighttpd_init)
    f.close()
    os.system('chmod 755 %s' % lighttpd_init_file)
    print "~* Lighttpd Installation Complete *~"
    print "You may now start Lighttpd with the command `~/etc/rc.d/lighttpd.sh start`. Have your server start Lighttpd automatically by following the directions here: http://help.textdrive.com/index.php?pg=kb.page&id=254"
    
def main():
    print \
"""To install Django, press 1.
To install Lighttpd, press 2.
To install a new Django project, press 3."""
    choice = raw_input()
    if choice == '1':
        install_django()
    elif choice == '2':
        install_lighttpd()
    elif choice == '3':
        install_django_project()
    else:
        print "Your input was incorrect. Please try again."
        main()

if __name__ == "__main__":
    main()