Commits

Anonymous committed 3030fa8

Changed django-caktus script and added basic and features with extra packages in both

Comments (0)

Files changed (44)

bin/django-caktus.py

 import os
 import sys
 import subprocess
+
+import caktus_django_template as template
+
 from optparse import OptionParser
 
-from caktus_django_template import template
 
-
-usage = """usage: %prog <project-name>"""
+usage = """usage: %prog <project-name> <extra-template1> <extra-template2>"""
 parser = OptionParser(usage=usage)
 
 
 def main():
     (options, pos_args) = parser.parse_args()
-    if len(pos_args) < 1:
+    length = len(pos_args)
+    additional = ['base']
+    if length < 1:
         parser.print_help()
         sys.exit(-1)
+    elif length > 1:
+        additional.extend(pos_args[1:])
     cwd = os.getcwd()
     project_name = pos_args[0]
     project_dir = os.path.join(cwd, project_name)
     # add trailing slash to copy contents of template directory
-    template_dir = os.path.abspath(os.path.dirname(template.__file__)) + '/'
-    subprocess.check_call(['rsync', '-avq', template_dir, project_dir])
+    template_dir = os.path.abspath(os.path.dirname(template.__file__))
+    for add in additional:
+        rsync(template_dir, add, project_dir)
     update_template(project_dir, project_name)
 
 
+def rsync(template_dir, addition, project_dir):
+    temp = os.path.join(template_dir, addition) + '/'
+    print temp
+    return subprocess.check_call(['rsync', '-avq', temp, project_dir])
+
+
 def update_template(project_dir, project_name):
     for path, dirs, files in os.walk(project_dir):
         for file_name in files:

caktus_django_template/base/__init__.py

Empty file added.

caktus_django_template/base/apache/production.conf

+<VirtualHost *>
+    ServerName www.caktusgroup.com
+    ServerAlias caktusgroup.com
+
+    WSGIScriptReloading On
+    WSGIReloadMechanism Process
+    WSGIDaemonProcess PROJECT_NAME-prod
+    WSGIProcessGroup PROJECT_NAME-prod
+    WSGIApplicationGroup PROJECT_NAME-prod
+    WSGIPassAuthorization On
+    
+    WSGIScriptAlias / /var/www/PROJECT_NAME/production/PROJECT_NAME/apache/production.wsgi/
+    
+    <Location "/">
+        Order Allow,Deny
+        Allow from all
+    </Location>
+    
+    <Location "/media">
+        SetHandler None
+    </Location>
+
+    Alias /media /var/www/PROJECT_NAME/production/PROJECT_NAME/media
+    
+    <Location "/admin-media">
+        SetHandler None
+    </Location>
+    
+    Alias /admin-media /var/www/PROJECT_NAME/production/PROJECT_NAME/media/admin
+    
+    Alias /blog /var/www/PROJECT_NAME/wordpress
+    <Directory /var/www/PROJECT_NAME/wordpress>
+        Options FollowSymLinks
+        AllowOverride Limit Options FileInfo
+        DirectoryIndex index.php
+    </Directory>
+    
+    ErrorLog /var/www/PROJECT_NAME/log/error.log
+    LogLevel warn
+    CustomLog /var/www/PROJECT_NAME/log/access.log combined
+</VirtualHost>

caktus_django_template/base/apache/production.wsgi

+import os
+import sys
+import site
+
+sp = '/var/www/PROJECT_NAME/production/env/lib/python2.5/site-packages'
+site.addsitedir(sp)
+
+#Calculate the project path based on the location of the WSGI script.
+PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
+sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
+
+SHOW_UPGRADE_MESSAGE = False
+ADMIN_IPS = ('127.0.0.1', )
+UPGRADE_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'upgrade.html')
+ERROR_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'server_error.html')
+
+os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT_NAME.settings_production'
+
+
+try:
+    import django.core.handlers.wsgi
+    django_app = django.core.handlers.wsgi.WSGIHandler()
+except:
+    import traceback
+    traceback.print_exc(file=sys.stderr)
+    django_app = None
+
+
+def static_response(environ, start_response, status, file, default_message=''):
+    response_headers = [('Retry-After', '120')] # Retry-After: <seconds>
+    if os.path.exists(file):
+        response_headers.append(('Content-type', 'text/html'))
+        response = open(file).read()
+    else:
+        response_headers.append(('Content-type', 'text/plain'))
+        response = default_message
+    start_response(status, response_headers)
+    return [response]
+
+
+def server_error(environ, start_response):
+    status = '500 Internal Server Error'
+    msg = 'Internal Server Error...please retry in a few minutes.'
+    return static_response(environ, start_response, status, ERROR_FILE, msg)
+
+
+def upgrade_in_progress(environ, start_response):
+    if environ['REMOTE_ADDR'] in ADMIN_IPS and django_app:
+        return django_app(environ, start_response)
+
+    if environ['REQUEST_METHOD'] == 'GET':
+        status = '503 Service Unavailable'
+    else:
+        status = '405 Method Not Allowed'
+
+    msg = 'Upgrade in progress...please retry in a few minutes.'
+    return static_response(environ, start_response, status, UPGRADE_FILE, msg)
+
+
+class LoggingMiddleware(object):
+
+    def __init__(self, application):
+        self.__application = application
+
+    def __call__(self, environ, start_response):
+        try:
+            return self.__application(environ, start_response)
+        except:
+            import traceback
+            traceback.print_exc(file=sys.stderr)
+            return server_error(environ, start_response)
+
+
+if SHOW_UPGRADE_MESSAGE:
+    application = upgrade_in_progress
+elif not django_app:
+    application = server_error
+else:
+    application = LoggingMiddleware(django_app)

caktus_django_template/base/apache/staging.conf

+<VirtualHost *:80>
+    ServerName dev.caktusgroup.com
+    
+    WSGIScriptReloading On
+    WSGIReloadMechanism Process
+    WSGIDaemonProcess PROJECT_NAME-staging
+    WSGIProcessGroup PROJECT_NAME-staging
+    WSGIApplicationGroup PROJECT_NAME-staging
+    WSGIPassAuthorization On
+    
+    WSGIScriptAlias / /home/PROJECT_NAME/www/staging/PROJECT_NAME/apache/staging.wsgi/
+    
+    <Location "/">
+        #Order Allow,Deny
+        #Allow from all
+        Order deny,allow
+        Allow from none 
+        AuthType basic
+        AuthName "Caktus Staging Authentication"
+        AuthUserFile "/home/passwords"
+        Require valid-user
+    </Location>
+    
+    <Location "/PROJECT_NAME/media">
+        SetHandler None
+    </Location>
+
+    Alias /media /home/PROJECT_NAME/www/staging/PROJECT_NAME/media
+    
+    <Location "/admin-media">
+        SetHandler None
+    </Location>
+    
+    Alias /admin-media /home/PROJECT_NAME/www/staging/PROJECT_NAME/media/admin
+    
+    ErrorLog /home/PROJECT_NAME/www/log/error.log
+    LogLevel info
+    CustomLog /home/PROJECT_NAME/www/log/access.log combined
+</VirtualHost>

caktus_django_template/base/apache/staging.wsgi

+import os
+import sys
+import site
+
+sp = '/home/PROJECT_NAME/www/staging/env/lib/python2.6/site-packages'
+site.addsitedir(sp)
+
+#Calculate the project path based on the location of the WSGI script.
+PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
+sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
+
+SHOW_UPGRADE_MESSAGE = False
+ADMIN_IPS = ('127.0.0.1', )
+UPGRADE_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'upgrade.html')
+ERROR_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'server_error.html')
+
+os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT_NAME.settings_staging'
+
+
+try:
+    import django.core.handlers.wsgi
+    django_app = django.core.handlers.wsgi.WSGIHandler()
+except:
+    import traceback
+    traceback.print_exc(file=sys.stderr)
+    django_app = None
+
+
+def static_response(environ, start_response, status, file, default_message=''):
+    response_headers = [('Retry-After', '120')] # Retry-After: <seconds>
+    if os.path.exists(file):
+        response_headers.append(('Content-type', 'text/html'))
+        response = open(file).read()
+    else:
+        response_headers.append(('Content-type', 'text/plain'))
+        response = default_message
+    start_response(status, response_headers)
+    return [response]
+
+
+def server_error(environ, start_response):
+    status = '500 Internal Server Error'
+    msg = 'Internal Server Error...please retry in a few minutes.'
+    return static_response(environ, start_response, status, ERROR_FILE, msg)
+
+
+def upgrade_in_progress(environ, start_response):
+    if environ['REMOTE_ADDR'] in ADMIN_IPS and django_app:
+        return django_app(environ, start_response)
+
+    if environ['REQUEST_METHOD'] == 'GET':
+        status = '503 Service Unavailable'
+    else:
+        status = '405 Method Not Allowed'
+
+    msg = 'Upgrade in progress...please retry in a few minutes.'
+    return static_response(environ, start_response, status, UPGRADE_FILE, msg)
+
+
+class LoggingMiddleware(object):
+
+    def __init__(self, application):
+        self.__application = application
+
+    def __call__(self, environ, start_response):
+        try:
+            return self.__application(environ, start_response)
+        except:
+            import traceback
+            traceback.print_exc(file=sys.stderr)
+            return server_error(environ, start_response)
+
+
+if SHOW_UPGRADE_MESSAGE:
+    application = upgrade_in_progress
+elif not django_app:
+    application = server_error
+else:
+    application = LoggingMiddleware(django_app)

caktus_django_template/base/bootstrap.py

+#!/usr/bin/env python
+# bootstrap.py
+# Bootstrap and setup a virtualenv with the specified requirements.txt
+import os
+import sys
+import shutil
+import subprocess
+from optparse import OptionParser
+
+
+usage = """usage: %prog [options]"""
+parser = OptionParser(usage=usage)
+parser.add_option("-c", "--clear", dest="clear", action="store_true",
+                  help="clear out existing virtualenv")
+
+
+def main():
+    if "VIRTUAL_ENV" not in os.environ:
+        sys.stderr.write("$VIRTUAL_ENV not found.\n\n")
+        parser.print_usage()
+        sys.exit(-1)
+    (options, pos_args) = parser.parse_args()
+    virtualenv = os.environ["VIRTUAL_ENV"]
+    if options.clear:
+        subprocess.call(["virtualenv", "--clear", "--distribute",
+                        virtualenv])
+    file_path = os.path.dirname(__file__)
+    subprocess.call(["pip", "install", "-E", virtualenv, "--requirement",
+                     os.path.join(file_path, "requirements/apps.txt")])
+
+
+if __name__ == "__main__":
+    main()
+    sys.exit(0)

caktus_django_template/base/fabfile.py

+import os
+
+from fabric.api import *
+from fabric.contrib.project import rsync_project
+from fabric.contrib import files, console
+from fabric import utils
+from fabric.decorators import hosts
+
+
+RSYNC_EXCLUDE = (
+    '.DS_Store',
+    '.svn',
+    '*.pyc',
+    '*.example',
+    'media/admin',
+    'media/photologue',
+    'media/upload',
+    'media/team_photos',
+    'passwords.py',
+    'local_settings.py',
+    'fabfile.py',
+    'bootstrap.py',
+    'hudson_test_settings.py',
+)
+env.home = '/home/PROJECT_NAME/'
+env.project = 'PROJECT_NAME'
+# remove -l from env.shell, "mesg n" in ~/.profile was causing issues
+# see Why do I sometimes see ``err: stdin: is not a tty``?
+# http://github.com/bitprophet/fabric/blob/master/FAQ
+env.shell = '/bin/bash -c'
+
+
+def setup_path():
+    env.code_root = os.path.join(env.root, env.project)
+    env.virtualenv_root = os.path.join(env.root, 'env')
+    env.db = '%s_%s' % (env.project, env.environment)
+    env.settings = '%(project)s.settings_%(environment)s' % env
+
+
+def staging():
+    env.user = ''
+    env.environment = 'staging'
+    env.hosts = ['']
+    env.root = os.path.join(env.home, 'www', env.environment)
+    setup_path()
+
+
+def production():
+    env.home = ''
+    env.user = ''
+    env.environment = 'production'
+    env.hosts = ['']
+    env.root = os.path.join(env.home, env.environment)
+    setup_path()
+
+
+def create_virtualenv():
+    args = '--clear --distribute'
+    run('virtualenv %s %s' % (args, env.virtualenv_root))
+
+
+def update_requirements():
+    requirements = os.path.join(env.code_root, 'requirements')
+    with cd(requirements):
+        cmd = ['pip install']
+        cmd += ['-E %(virtualenv_root)s' % env]
+        cmd += ['--requirement %s' % os.path.join(requirements, 'apps.txt')]
+        run(' '.join(cmd))
+
+
+def deploy():
+    if env.environment == 'production':
+        if not console.confirm('Are you sure you want to deploy production?',
+                               default=False):
+            utils.abort('Production deployment aborted.')
+    # run_tests()
+    # defaults rsync options:
+    # -pthrvz
+    # -p preserve permissions
+    # -t preserve times
+    # -h output numbers in a human-readable format
+    # -r recurse into directories
+    # -v increase verbosity
+    # -z compress file data during the transfer
+    extra_opts = '--omit-dir-times'
+    rsync_project(
+        env.root,
+        exclude=RSYNC_EXCLUDE,
+        delete=True,
+        extra_opts=extra_opts,
+    )
+    touch()
+
+
+def run_tests():
+    local('./manage.py test', capture=False)
+
+
+def touch():
+    apache_dir = os.path.join(env.code_root, 'apache')
+    with cd(apache_dir):
+        run('touch %s.wsgi' % env.environment)
+
+
+def syncdb():
+    with cd(env.code_root):
+        activate = os.path.join(env.virtualenv_root, 'bin', 'activate')
+        activate = 'source %s' % activate
+        cmd = './manage.py syncdb --noinput --settings=%s' % env.settings
+        run('%s && %s' % (activate, cmd))
+
+
+def update_apache_conf():
+    source = os.path.join('apache', '%(environment)s.conf' % env)
+    dest = os.path.join(env.home, 'apache.conf.d')
+    put(source, dest, mode=0755)
+    apache_reload()
+
+
+def configtest():
+    run('apache2ctl configtest')
+
+
+def apache_reload():
+    run('sudo /etc/init.d/apache2 reload')
+
+
+def apache_restart():
+    run('sudo /etc/init.d/apache2 restart')
+
+
+def mkdirs():
+    run('mkdir -p %(root)s' % env)
+    
+    run('mkdir -p %s' % os.path.join(env.home, 'www', 'log'))
+
+
+def _get_pg_password():
+    password_file = os.path.join(env.home, '.pg_password')
+    with settings(warn_only=True):
+        if files.exists(password_file):
+            password = run('cat %s' % password_file)
+        else:
+            run('pwgen 20 1 > %s' % password_file)
+            password = run('cat %s' % password_file)
+            sql = "ALTER ROLE %s WITH PASSWORD \'%s\'" % (env.project,
+                                                          password)
+            run('psql -c "%s"' % sql)
+    return password
+
+
+def symlink_django():
+    admin_media = os.path.join(env.virtualenv_root,
+                               'src/django/django/contrib/admin/media/')
+    media = os.path.join(env.code_root, 'media/admin')
+    if not files.exists(media):
+        run('ln -s %s %s' % (admin_media, media))
+
+
+def createdb():
+    passwords_file = os.path.join(env.code_root, 'passwords.py')
+    if not files.exists(passwords_file):
+        data = {
+            'DATABASE_PASSWORD': _get_pg_password(),
+            'SECRET_KEY': run('pwgen 60 1'),
+        }
+        for key, val in data.iteritems():
+            line = '%s = "%s"' % (key, val)
+            files.append(line, passwords_file)
+    with settings(warn_only=True):
+        run('createdb %s' % env.db)
+
+
+def bootstrap():
+    mkdirs()
+    create_virtualenv()
+    deploy()
+    update_requirements()
+    if env.environment == 'staging':
+        createdb()
+        update_apache_conf()
+
+
+def reset_local_media():
+    """ Reset local media from remote host """
+    require('code_root', provided_by=('production', 'staging'))
+    media = os.path.join(env.code_root, 'media', 'photologue')
+    local('rsync -rvaz %s@%s:%s media/' % (env.user, env.hosts[0], media))
+    media = os.path.join(env.code_root, 'media', 'team_photos')
+    local('rsync -rvaz %s@%s:%s media/' % (env.user, env.hosts[0], media))
+
+
+def reset_local_db():
+    if not console.confirm('Are you sure you want to reset your local '
+                           'database with the production database?',
+                           default=False):
+        utils.abort('Local database reset aborted.')
+    database_server = 'calliope.caktusgroup.com'
+    production_db = 'PROJECT_NAME_prod'
+    settings = 'local_settings.py'
+    local_db = local('grep DATABASE_NAME "%s" | cut -d"\'" -f2' % settings)
+    local('dropdb %s' % local_db)
+    local('createdb %s' % local_db)
+    cmd = 'ssh -C %s pg_dump -Ox %s | psql %s' % (database_server,
+                                                  production_db,
+                                                  local_db)
+    local(cmd)

caktus_django_template/base/local_settings.py.example

+from PROJECT_NAME.settings import *
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': '',                      # Or path to database file if using sqlite3.
+        'USER': '',                      # Not used with sqlite3.
+        'PASSWORD': '',                  # Not used with sqlite3.
+        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+SERVE_STATIC_MEDIA = True

caktus_django_template/base/manage.py

+#!/usr/bin/env python
+
+import sys
+import os.path
+
+# remove '.' from the path
+sys.path.pop(0)
+# add project directory to path
+PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
+sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
+
+from django.core.management import execute_manager
+try:
+    import PROJECT_NAME.settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(PROJECT_NAME.settings)

caktus_django_template/base/requirements/apps.txt

+-e svn+http://code.djangoproject.com/svn/django/trunk/#egg=django

caktus_django_template/base/settings.py

+# Django settings for PROJECT_NAME project.
+
+from os import path
+
+PROJECT_PATH = path.abspath('%s' % path.dirname(__file__))
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale
+USE_L10N = True
+
+URL_PREFIX = ''
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = '%s/media/' % PROJECT_PATH
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = '/%smedia/' % URL_PREFIX
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/admin-media/'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+#     'django.template.loaders.eggs.Loader',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = [
+    'django.contrib.auth.context_processors.auth',
+    'django.core.context_processors.debug',
+    'django.core.context_processors.i18n',
+    'django.core.context_processors.media',
+    'django.core.context_processors.request',
+    'django.contrib.messages.context_processors.messages',
+]
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+ROOT_URLCONF = 'PROJECT_NAME.urls'
+
+TEMPLATE_DIRS = (
+    '%s/templates' % PROJECT_PATH,
+)
+
+INSTALLED_APPS = [
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.admin',
+]

caktus_django_template/base/settings_production.py

+from PROJECT_NAME.settings import *
+from PROJECT_NAME.passwords import *
+
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
+SERVE_STATIC_MEDIA = DEBUG
+
+URL_PREFIX = ''
+MEDIA_URL = '/%smedia/' % URL_PREFIX
+ADMIN_MEDIA_PREFIX = '/%sadmin-media/' % URL_PREFIX
+
+ADMINS = (
+    ('Caktus Team', 'team@caktusgroup.com'),
+)
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'postgresql_psycopg2'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = ''             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_HOST = ''
+
+"""
+CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
+CACHE_MIDDLEWARE_SECONDS = 120
+CACHE_MIDDLEWARE_KEY_PREFIX = ''
+CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
+SESSION_ENGINE = "django.contrib.sessions.backends.cache"
+"""

caktus_django_template/base/settings_staging.py

+from PROJECT_NAME.settings import *
+from PROJECT_NAME.passwords import *
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+SERVE_STATIC_MEDIA = False
+
+EMAIL_HOST = 'localhost'
+DEFAULT_FROM_EMAIL = 'no-reply@norton.caktusgroup.com'
+
+URL_PREFIX = ''
+MEDIA_URL = '/%smedia/' % URL_PREFIX
+ADMIN_MEDIA_PREFIX = '/%sadmin-media/' % URL_PREFIX
+
+ADMINS = (
+    ('Caktus Team', 'team@caktusgroup.com'),
+)
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'postgresql_psycopg2'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = ''             # Or path to database file if using sqlite3.
+DATABASE_USER = ''             # Not used with sqlite3.
+DATABASE_HOST = 'localhost'
+
+"""
+CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
+CACHE_MIDDLEWARE_SECONDS = 10
+CACHE_MIDDLEWARE_KEY_PREFIX = 'PROJECT_NAME_staging_'
+CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
+SESSION_ENGINE = "django.contrib.sessions.backends.cache"
+"""
+
+MIDDLEWARE_CLASSES.insert(0, 'debug_toolbar.middleware.DebugToolbarMiddleware')
+
+INSTALLED_APPS += [
+    'debug_toolbar',
+]
+
+INTERNAL_IPS = []
+
+DEBUG_TOOLBAR_CONFIG = {
+    'INTERCEPT_REDIRECTS': False,
+}

caktus_django_template/base/templates/404.html

+{% extends "base.html" %}
+
+{% block title %}404 Not Found{% endblock %}
+
+{% block center_column %}
+
+<h1>Not Found</h1>
+	
+<p>The requested URL {{ request.path }} was not found on this server.</p>
+
+{% endblock %}

caktus_django_template/base/templates/500.html

+{% extends "base.html" %}
+
+{% block title %}500 Internal Server Error{% endblock %}
+
+{% block center_column %}
+
+<h1>Internal Server Error</h1>
+
+<p>A server error prevented this page from being displayed.  The system administrator has been notified and will investigate the problem as soon as possible.</h3>
+
+{% endblock %}

caktus_django_template/base/templates/base.html

+{% load treenav_tags %}{% load analytics %}<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+	<meta name='verify-v1' content='lDuJSxFGjLeE9nsfGwVwVIJitVZxe6mOzMZ05j/mV4s=' />
+	<meta name="description" content="{% spaceless %}{% block description %}Caktus Consulting Group builds custom, Django-based web applications for clients in the Raleigh, Durham and Chapel Hill (Triangle) area and beyond.{% endblock %}{% endspaceless %}" />
+	<meta name="author" content='Caktus Consulting Group, LLC' />
+	<title>{% block title %}{% endblock %} | Django Web Development | Raleigh Durham Chapel Hill | Caktus Consulting Group</title>
+
+	<link rel='stylesheet' charset='UTF-8' type='text/css' media='screen' href='{{ MEDIA_URL }}style/main.css?1' />
+	
+    <link rel="stylesheet" charset='UTF-8' type='text/css' href="{{ MEDIA_URL }}css/pagelets.css" />
+    <script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.2.6.min.js"></script>
+    <script type="text/javascript" src="{{ MEDIA_URL }}wymeditor/jquery.wymeditor.min.js"></script>
+
+	<script type="text/javascript" src="{{ MEDIA_URL }}js/pagelets.js"></script>
+	{% block js %}{% endblock %}
+	{% block css %}{% endblock %}
+	
+	<link rel='icon' href='{{ MEDIA_URL }}images/favicon.png' />
+</head>
+<body class='caktus {% block body-class %}{% endblock %}'>
+<div id="page-wrapper">{# /everything/ but footer goes inside page-wrapper #}
+
+<div id="title">
+
+	<div id='logo'>
+		<a href='{% url home %}'><img src="{{ MEDIA_URL }}images/caktus-web-logo.png" alt="Caktus Logo" /></a>
+	</div>
+	
+	<div id="utils">
+		<!--form action="#" method="GET">
+			<input type="text" size="20" name="q" value="Search" /> <input type="submit" value="Search" /> <br/>
+		</form-->
+		<a href="{% url contact_form %}"><span id="contact">Contact Us</span></a>
+	</div>
+
+	<div id="navigation">
+		{% block navigation %}
+            {% single_level_menu 'primary-nav' 0 %}
+		{% endblock %}
+	</div>
+
+	<div id="sub-navigation">
+		{% block subnavigation %}
+		    {% single_level_menu 'primary-nav' 1 %}
+		{% endblock %}
+	</div>
+</div>
+
+<div id="content">
+	<div id="left-column"></div>
+	<div id="right-column"></div>
+	<div id="center-column">
+		{% block center_column %}{% endblock %}
+		{% block content %}{% endblock %}
+	</div>
+	<div id="cleaner" > </div>
+</div>
+</div>
+<div id="footer">
+	<div id='caktus-info'>
+		<ul >
+			<li id='who-we-are'>
+				<h2>Who We Are</h2>
+				<p><strong>Caktus Consulting Group</strong> is a team of highly talented and creative web designers and developers based in the Raleigh-Durham-Chapel Hill area of North Carolina.</p>
+				<p>&rarr; <a href="{% url view_page 'about' %}">About Us</a></p>
+			</li>
+			<li id='our-clients'>
+				<h2>Our Clients</h2>
+				<p>Caktus' clients range from individuals to non-profits and corporations in the broader Raleigh-Durham-Chapel Hill region and beyond.</p>
+				<p>&rarr; <a href="{% url portfolio %}">Our Portfolio</a></p>
+			</li>
+			<li id='what-we-do'>
+				<h2>What We Do</h2>
+				<p><strong>Caktus Consulting Group</strong> builds custom web applications with <a href="http://www.djangoproject.com/">Django</a>.  Our web apps feature <strong>elegant, dynamic user interfaces</strong> and a <strong>rock solid database backend</strong>.</p>
+				<p>&rarr; <a href="{% url view_page 'services' %}">Read More...</a></p>
+			</li>
+			<li id='how-to-reach-us'>
+				<h2>How to Reach Us</h2>
+				<p><strong>Mailing address:</strong><br/>
+				P.O. Box 1454<br/>
+				Carrboro, NC 27510</p>
+				<p><strong>Telephone:</strong><br/>
+				919/951-0052</p>
+				<p>&rarr; <a href="{% url contact_form %}">Contact Us</a></p>
+
+			</li>
+		</ul>
+	</div>
+	<div id="copyright">&copy; 2007-{{ now|date:"Y" }} <a href="http://www.caktusgroup.com/">Caktus Consulting Group, LLC</a>. All rights reserved.</div>
+	<div id='badges'>
+		{# <a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a> #}
+		{# <a href="http://jigsaw.w3.org/css-validator/"><img style="border:0;width:88px;height:31px" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" /></a> #}
+		<a href="http://www.djangoproject.com/"><img src="http://media.djangoproject.com/img/badges/djangomade124x25.gif" alt="Made with Django." title="Made with Django." /></a>
+	</div>
+</div>
+{% analytics %}
+</body>
+</html>

caktus_django_template/base/urls.py

+from django.conf.urls.defaults import *
+from django.conf import settings
+from django.contrib import admin
+
+
+admin.autodiscover()
+
+handler404 = 'PROJECT_NAME.views.page_not_found'
+handler500 = 'PROJECT_NAME.views.server_error'
+
+urlpatterns = patterns('',
+    (r'^%sadmin/' % settings.URL_PREFIX, include(admin.site.urls)),
+)
+
+
+if getattr(settings, 'SERVE_STATIC_MEDIA', False):
+    urlpatterns += patterns('', (
+            r'^%s(?P<path>.*)' % settings.MEDIA_URL.lstrip('/'),
+            'django.views.static.serve',
+            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}
+        )
+    )

caktus_django_template/base/views.py

+from django import http
+from django.template import Context, RequestContext, loader
+
+
+# in lieu of http://code.djangoproject.com/ticket/5617
+def render_safe(request, template_name):
+    """
+    Try to render the given template using RequestContext.  If that fails,
+    use an empty Context instead.
+    """
+    t = loader.get_template(template_name)
+    try:
+        context = RequestContext(request, {'request_path': request.path})
+        return t.render(context)
+    except:
+        return t.render(Context({}))
+
+
+def page_not_found(request, template_name='404.html'):
+    """
+    Default 404 handler.
+
+    Templates: `404.html`
+    Context:
+        request_path
+            The path of the requested URL (e.g., '/app/pages/bad_page/')
+    """
+    return http.HttpResponseNotFound(render_safe(request, template_name))
+
+
+def server_error(request, template_name='500.html'):
+    """
+    500 error handler.
+
+    Templates: `500.html`
+    Context: None
+    """
+    return http.HttpResponseServerError(render_safe(request, template_name))

caktus_django_template/basic/__init__.py

Empty file added.

caktus_django_template/basic/requirements/apps.txt

+-e svn+http://code.djangoproject.com/svn/django/trunk/#egg=django
+-e svn+http://django-mptt.googlecode.com/svn/trunk@121#egg=django-mptt
+-e svn+http://django-pagelets.googlecode.com/svn/trunk@61#egg=django-pagelets
+-e svn+http://django-treenav.googlecode.com/svn/trunk@38#egg=django-treenav
+-e svn+http://django-crumbs.googlecode.com/svn/trunk@5#egg=django-crumbs

caktus_django_template/basic/settings.py

+# Django settings for PROJECT_NAME project.
+
+from os import path
+
+PROJECT_PATH = path.abspath('%s' % path.dirname(__file__))
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale
+USE_L10N = True
+
+URL_PREFIX = ''
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = '%s/media/' % PROJECT_PATH
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = '/%smedia/' % URL_PREFIX
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/admin-media/'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+#     'django.template.loaders.eggs.Loader',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = [
+    'django.contrib.auth.context_processors.auth',
+    'django.core.context_processors.debug',
+    'django.core.context_processors.i18n',
+    'django.core.context_processors.media',
+    'django.core.context_processors.request',
+    'django.contrib.messages.context_processors.messages',
+]
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+ROOT_URLCONF = 'PROJECT_NAME.urls'
+
+TEMPLATE_DIRS = (
+    '%s/templates' % PROJECT_PATH,
+)
+
+INSTALLED_APPS = [
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.admin',
+    'pagelets',
+    'mptt',
+    'treenav',
+    'crumbs',
+]

caktus_django_template/basic/urls.py

+from django.conf.urls.defaults import *
+from django.conf import settings
+from django.contrib import admin
+
+
+admin.autodiscover()
+
+handler404 = 'PROJECT_NAME.views.page_not_found'
+handler500 = 'PROJECT_NAME.views.server_error'
+
+urlpatterns = patterns('',
+    (r'^%sadmin/' % settings.URL_PREFIX, include(admin.site.urls)),
+    (r'^%streenav/' % settings.URL_PREFIX, include('treenav.urls.admin')),
+)
+
+
+if getattr(settings, 'SERVE_STATIC_MEDIA', False):
+    urlpatterns += patterns('', (
+            r'^%s(?P<path>.*)' % settings.MEDIA_URL.lstrip('/'),
+            'django.views.static.serve',
+            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}
+        )
+    )
+    
+urlpatterns += patterns('',
+    (r'^%spagelets/' % settings.URL_PREFIX, include('pagelets.urls.management')),
+    (r'^%s' % settings.URL_PREFIX, include('pagelets.urls.content')),
+)

caktus_django_template/features/requirements/apps.txt

+sorl-thumbnail==3.2.5
+django-robots==0.6.1
+-e svn+http://code.djangoproject.com/svn/django/trunk/#egg=django
+-e svn+http://django-mptt.googlecode.com/svn/trunk@121#egg=django-mptt
+-e svn+http://django-pagelets.googlecode.com/svn/trunk@61#egg=django-pagelets
+-e svn+http://django-treenav.googlecode.com/svn/trunk@38#egg=django-treenav
+-e svn+http://django-crumbs.googlecode.com/svn/trunk@5#egg=django-crumbs
+-e git://github.com/clintecker/django-google-analytics.git#egg=django-google-analytics

caktus_django_template/features/settings.py

+# Django settings for PROJECT_NAME project.
+
+from os import path
+
+PROJECT_PATH = path.abspath('%s' % path.dirname(__file__))
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'America/Chicago'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale
+USE_L10N = True
+
+URL_PREFIX = ''
+
+# Absolute path to the directory that holds media.
+# Example: "/home/media/media.lawrence.com/"
+MEDIA_ROOT = '%s/media/' % PROJECT_PATH
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = '/%smedia/' % URL_PREFIX
+
+# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
+# trailing slash.
+# Examples: "http://foo.com/media/", "/media/".
+ADMIN_MEDIA_PREFIX = '/admin-media/'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+#     'django.template.loaders.eggs.Loader',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = [
+    'django.contrib.auth.context_processors.auth',
+    'django.core.context_processors.debug',
+    'django.core.context_processors.i18n',
+    'django.core.context_processors.media',
+    'django.core.context_processors.request',
+    'django.contrib.messages.context_processors.messages',
+]
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+ROOT_URLCONF = 'PROJECT_NAME.urls'
+
+TEMPLATE_DIRS = (
+    '%s/templates' % PROJECT_PATH,
+)
+
+INSTALLED_APPS = [
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.admin',
+    'pagelets',
+    'mptt',
+    'treenav',
+    'crumbs',
+    'robots',
+    'google_analytics',
+]

caktus_django_template/features/urls.py

+from django.conf.urls.defaults import *
+from django.conf import settings
+from django.contrib import admin
+
+
+admin.autodiscover()
+
+handler404 = 'PROJECT_NAME.views.page_not_found'
+handler500 = 'PROJECT_NAME.views.server_error'
+
+urlpatterns = patterns('',
+    (r'^%sadmin/' % settings.URL_PREFIX, include(admin.site.urls)),
+    (r'^%streenav/' % settings.URL_PREFIX, include('treenav.urls.admin')),
+    (r'^%srobots.txt$' % settings.URL_PREFIX, include('robots.urls')),
+)
+
+
+if getattr(settings, 'SERVE_STATIC_MEDIA', False):
+    urlpatterns += patterns('', (
+            r'^%s(?P<path>.*)' % settings.MEDIA_URL.lstrip('/'),
+            'django.views.static.serve',
+            {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}
+        )
+    )
+    
+urlpatterns += patterns('',
+    (r'^%spagelets/' % settings.URL_PREFIX, include('pagelets.urls.management')),
+    (r'^%s' % settings.URL_PREFIX, include('pagelets.urls.content')),
+)

caktus_django_template/template/__init__.py

Empty file removed.

caktus_django_template/template/apache/production.conf

-<VirtualHost *>
-    ServerName www.caktusgroup.com
-    ServerAlias caktusgroup.com
-
-    WSGIScriptReloading On
-    WSGIReloadMechanism Process
-    WSGIDaemonProcess PROJECT_NAME-prod
-    WSGIProcessGroup PROJECT_NAME-prod
-    WSGIApplicationGroup PROJECT_NAME-prod
-    WSGIPassAuthorization On
-    
-    WSGIScriptAlias / /var/www/PROJECT_NAME/production/PROJECT_NAME/apache/production.wsgi/
-    
-    <Location "/">
-        Order Allow,Deny
-        Allow from all
-    </Location>
-    
-    <Location "/media">
-        SetHandler None
-    </Location>
-
-    Alias /media /var/www/PROJECT_NAME/production/PROJECT_NAME/media
-    
-    <Location "/admin-media">
-        SetHandler None
-    </Location>
-    
-    Alias /admin-media /var/www/PROJECT_NAME/production/PROJECT_NAME/media/admin
-    
-    Alias /blog /var/www/PROJECT_NAME/wordpress
-    <Directory /var/www/PROJECT_NAME/wordpress>
-        Options FollowSymLinks
-        AllowOverride Limit Options FileInfo
-        DirectoryIndex index.php
-    </Directory>
-    
-    ErrorLog /var/www/PROJECT_NAME/log/error.log
-    LogLevel warn
-    CustomLog /var/www/PROJECT_NAME/log/access.log combined
-</VirtualHost>

caktus_django_template/template/apache/production.wsgi

-import os
-import sys
-import site
-
-sp = '/var/www/PROJECT_NAME/production/env/lib/python2.5/site-packages'
-site.addsitedir(sp)
-
-#Calculate the project path based on the location of the WSGI script.
-PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
-sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
-
-SHOW_UPGRADE_MESSAGE = False
-ADMIN_IPS = ('127.0.0.1', )
-UPGRADE_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'upgrade.html')
-ERROR_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'server_error.html')
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT_NAME.settings_production'
-
-
-try:
-    import django.core.handlers.wsgi
-    django_app = django.core.handlers.wsgi.WSGIHandler()
-except:
-    import traceback
-    traceback.print_exc(file=sys.stderr)
-    django_app = None
-
-
-def static_response(environ, start_response, status, file, default_message=''):
-    response_headers = [('Retry-After', '120')] # Retry-After: <seconds>
-    if os.path.exists(file):
-        response_headers.append(('Content-type', 'text/html'))
-        response = open(file).read()
-    else:
-        response_headers.append(('Content-type', 'text/plain'))
-        response = default_message
-    start_response(status, response_headers)
-    return [response]
-
-
-def server_error(environ, start_response):
-    status = '500 Internal Server Error'
-    msg = 'Internal Server Error...please retry in a few minutes.'
-    return static_response(environ, start_response, status, ERROR_FILE, msg)
-
-
-def upgrade_in_progress(environ, start_response):
-    if environ['REMOTE_ADDR'] in ADMIN_IPS and django_app:
-        return django_app(environ, start_response)
-
-    if environ['REQUEST_METHOD'] == 'GET':
-        status = '503 Service Unavailable'
-    else:
-        status = '405 Method Not Allowed'
-
-    msg = 'Upgrade in progress...please retry in a few minutes.'
-    return static_response(environ, start_response, status, UPGRADE_FILE, msg)
-
-
-class LoggingMiddleware(object):
-
-    def __init__(self, application):
-        self.__application = application
-
-    def __call__(self, environ, start_response):
-        try:
-            return self.__application(environ, start_response)
-        except:
-            import traceback
-            traceback.print_exc(file=sys.stderr)
-            return server_error(environ, start_response)
-
-
-if SHOW_UPGRADE_MESSAGE:
-    application = upgrade_in_progress
-elif not django_app:
-    application = server_error
-else:
-    application = LoggingMiddleware(django_app)

caktus_django_template/template/apache/staging.conf

-<VirtualHost *:80>
-    ServerName dev.caktusgroup.com
-    
-    WSGIScriptReloading On
-    WSGIReloadMechanism Process
-    WSGIDaemonProcess PROJECT_NAME-staging
-    WSGIProcessGroup PROJECT_NAME-staging
-    WSGIApplicationGroup PROJECT_NAME-staging
-    WSGIPassAuthorization On
-    
-    WSGIScriptAlias / /home/PROJECT_NAME/www/staging/PROJECT_NAME/apache/staging.wsgi/
-    
-    <Location "/">
-        #Order Allow,Deny
-        #Allow from all
-        Order deny,allow
-        Allow from none 
-        AuthType basic
-        AuthName "Caktus Staging Authentication"
-        AuthUserFile "/home/passwords"
-        Require valid-user
-    </Location>
-    
-    <Location "/PROJECT_NAME/media">
-        SetHandler None
-    </Location>
-
-    Alias /media /home/PROJECT_NAME/www/staging/PROJECT_NAME/media
-    
-    <Location "/admin-media">
-        SetHandler None
-    </Location>
-    
-    Alias /admin-media /home/PROJECT_NAME/www/staging/PROJECT_NAME/media/admin
-    
-    ErrorLog /home/PROJECT_NAME/www/log/error.log
-    LogLevel info
-    CustomLog /home/PROJECT_NAME/www/log/access.log combined
-</VirtualHost>

caktus_django_template/template/apache/staging.wsgi

-import os
-import sys
-import site
-
-sp = '/home/PROJECT_NAME/www/staging/env/lib/python2.6/site-packages'
-site.addsitedir(sp)
-
-#Calculate the project path based on the location of the WSGI script.
-PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
-sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
-
-SHOW_UPGRADE_MESSAGE = False
-ADMIN_IPS = ('127.0.0.1', )
-UPGRADE_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'upgrade.html')
-ERROR_FILE = os.path.join(PROJECT_ROOT, 'media', 'html', 'server_error.html')
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECT_NAME.settings_staging'
-
-
-try:
-    import django.core.handlers.wsgi
-    django_app = django.core.handlers.wsgi.WSGIHandler()
-except:
-    import traceback
-    traceback.print_exc(file=sys.stderr)
-    django_app = None
-
-
-def static_response(environ, start_response, status, file, default_message=''):
-    response_headers = [('Retry-After', '120')] # Retry-After: <seconds>
-    if os.path.exists(file):
-        response_headers.append(('Content-type', 'text/html'))
-        response = open(file).read()
-    else:
-        response_headers.append(('Content-type', 'text/plain'))
-        response = default_message
-    start_response(status, response_headers)
-    return [response]
-
-
-def server_error(environ, start_response):
-    status = '500 Internal Server Error'
-    msg = 'Internal Server Error...please retry in a few minutes.'
-    return static_response(environ, start_response, status, ERROR_FILE, msg)
-
-
-def upgrade_in_progress(environ, start_response):
-    if environ['REMOTE_ADDR'] in ADMIN_IPS and django_app:
-        return django_app(environ, start_response)
-
-    if environ['REQUEST_METHOD'] == 'GET':
-        status = '503 Service Unavailable'
-    else:
-        status = '405 Method Not Allowed'
-
-    msg = 'Upgrade in progress...please retry in a few minutes.'
-    return static_response(environ, start_response, status, UPGRADE_FILE, msg)
-
-
-class LoggingMiddleware(object):
-
-    def __init__(self, application):
-        self.__application = application
-
-    def __call__(self, environ, start_response):
-        try:
-            return self.__application(environ, start_response)
-        except:
-            import traceback
-            traceback.print_exc(file=sys.stderr)
-            return server_error(environ, start_response)
-
-
-if SHOW_UPGRADE_MESSAGE:
-    application = upgrade_in_progress
-elif not django_app:
-    application = server_error
-else:
-    application = LoggingMiddleware(django_app)

caktus_django_template/template/bootstrap.py

-#!/usr/bin/env python
-# bootstrap.py
-# Bootstrap and setup a virtualenv with the specified requirements.txt
-import os
-import sys
-import shutil
-import subprocess
-from optparse import OptionParser
-
-
-usage = """usage: %prog [options]"""
-parser = OptionParser(usage=usage)
-parser.add_option("-c", "--clear", dest="clear", action="store_true",
-                  help="clear out existing virtualenv")
-
-
-def main():
-    if "VIRTUAL_ENV" not in os.environ:
-        sys.stderr.write("$VIRTUAL_ENV not found.\n\n")
-        parser.print_usage()
-        sys.exit(-1)
-    (options, pos_args) = parser.parse_args()
-    virtualenv = os.environ["VIRTUAL_ENV"]
-    if options.clear:
-        subprocess.call(["virtualenv", "--clear", "--distribute",
-                        virtualenv])
-    file_path = os.path.dirname(__file__)
-    subprocess.call(["pip", "install", "-E", virtualenv, "--requirement",
-                     os.path.join(file_path, "requirements/apps.txt")])
-
-
-if __name__ == "__main__":
-    main()
-    sys.exit(0)

caktus_django_template/template/fabfile.py

-import os
-
-from fabric.api import *
-from fabric.contrib.project import rsync_project
-from fabric.contrib import files, console
-from fabric import utils
-from fabric.decorators import hosts
-
-
-RSYNC_EXCLUDE = (
-    '.DS_Store',
-    '.svn',
-    '*.pyc',
-    '*.example',
-    'media/admin',
-    'media/photologue',
-    'media/upload',
-    'media/team_photos',
-    'passwords.py',
-    'local_settings.py',
-    'fabfile.py',
-    'bootstrap.py',
-    'hudson_test_settings.py',
-)
-env.home = '/home/PROJECT_NAME/'
-env.project = 'PROJECT_NAME'
-# remove -l from env.shell, "mesg n" in ~/.profile was causing issues
-# see Why do I sometimes see ``err: stdin: is not a tty``?
-# http://github.com/bitprophet/fabric/blob/master/FAQ
-env.shell = '/bin/bash -c'
-
-
-def setup_path():
-    env.code_root = os.path.join(env.root, env.project)
-    env.virtualenv_root = os.path.join(env.root, 'env')
-    env.db = '%s_%s' % (env.project, env.environment)
-    env.settings = '%(project)s.settings_%(environment)s' % env
-
-
-def staging():
-    env.user = ''
-    env.environment = 'staging'
-    env.hosts = ['']
-    env.root = os.path.join(env.home, 'www', env.environment)
-    setup_path()
-
-
-def production():
-    env.home = ''
-    env.user = ''
-    env.environment = 'production'
-    env.hosts = ['']
-    env.root = os.path.join(env.home, env.environment)
-    setup_path()
-
-
-def create_virtualenv():
-    args = '--clear --distribute'
-    run('virtualenv %s %s' % (args, env.virtualenv_root))
-
-
-def update_requirements():
-    requirements = os.path.join(env.code_root, 'requirements')
-    with cd(requirements):
-        cmd = ['pip install']
-        cmd += ['-E %(virtualenv_root)s' % env]
-        cmd += ['--requirement %s' % os.path.join(requirements, 'apps.txt')]
-        run(' '.join(cmd))
-
-
-def deploy():
-    if env.environment == 'production':
-        if not console.confirm('Are you sure you want to deploy production?',
-                               default=False):
-            utils.abort('Production deployment aborted.')
-    # run_tests()
-    # defaults rsync options:
-    # -pthrvz
-    # -p preserve permissions
-    # -t preserve times
-    # -h output numbers in a human-readable format
-    # -r recurse into directories
-    # -v increase verbosity
-    # -z compress file data during the transfer
-    extra_opts = '--omit-dir-times'
-    rsync_project(
-        env.root,
-        exclude=RSYNC_EXCLUDE,
-        delete=True,
-        extra_opts=extra_opts,
-    )
-    touch()
-
-
-def run_tests():
-    local('./manage.py test', capture=False)
-
-
-def touch():
-    apache_dir = os.path.join(env.code_root, 'apache')
-    with cd(apache_dir):
-        run('touch %s.wsgi' % env.environment)
-
-
-def syncdb():
-    with cd(env.code_root):
-        activate = os.path.join(env.virtualenv_root, 'bin', 'activate')
-        activate = 'source %s' % activate
-        cmd = './manage.py syncdb --noinput --settings=%s' % env.settings
-        run('%s && %s' % (activate, cmd))
-
-
-def update_apache_conf():
-    source = os.path.join('apache', '%(environment)s.conf' % env)
-    dest = os.path.join(env.home, 'apache.conf.d')
-    put(source, dest, mode=0755)
-    apache_reload()
-
-
-def configtest():
-    run('apache2ctl configtest')
-
-
-def apache_reload():
-    run('sudo /etc/init.d/apache2 reload')
-
-
-def apache_restart():
-    run('sudo /etc/init.d/apache2 restart')
-
-
-def mkdirs():
-    run('mkdir -p %(root)s' % env)
-    
-    run('mkdir -p %s' % os.path.join(env.home, 'www', 'log'))
-
-
-def _get_pg_password():
-    password_file = os.path.join(env.home, '.pg_password')
-    with settings(warn_only=True):
-        if files.exists(password_file):
-            password = run('cat %s' % password_file)
-        else:
-            run('pwgen 20 1 > %s' % password_file)
-            password = run('cat %s' % password_file)
-            sql = "ALTER ROLE %s WITH PASSWORD \'%s\'" % (env.project,
-                                                          password)
-            run('psql -c "%s"' % sql)
-    return password
-
-
-def symlink_django():
-    admin_media = os.path.join(env.virtualenv_root,
-                               'src/django/django/contrib/admin/media/')
-    media = os.path.join(env.code_root, 'media/admin')
-    if not files.exists(media):
-        run('ln -s %s %s' % (admin_media, media))
-
-
-def createdb():
-    passwords_file = os.path.join(env.code_root, 'passwords.py')
-    if not files.exists(passwords_file):
-        data = {
-            'DATABASE_PASSWORD': _get_pg_password(),
-            'SECRET_KEY': run('pwgen 60 1'),
-        }
-        for key, val in data.iteritems():
-            line = '%s = "%s"' % (key, val)
-            files.append(line, passwords_file)
-    with settings(warn_only=True):
-        run('createdb %s' % env.db)
-
-
-def bootstrap():
-    mkdirs()
-    create_virtualenv()
-    deploy()
-    update_requirements()
-    if env.environment == 'staging':
-        createdb()
-        update_apache_conf()
-
-
-def reset_local_media():
-    """ Reset local media from remote host """
-    require('code_root', provided_by=('production', 'staging'))
-    media = os.path.join(env.code_root, 'media', 'photologue')
-    local('rsync -rvaz %s@%s:%s media/' % (env.user, env.hosts[0], media))
-    media = os.path.join(env.code_root, 'media', 'team_photos')
-    local('rsync -rvaz %s@%s:%s media/' % (env.user, env.hosts[0], media))
-
-
-def reset_local_db():
-    if not console.confirm('Are you sure you want to reset your local '
-                           'database with the production database?',
-                           default=False):
-        utils.abort('Local database reset aborted.')
-    database_server = 'calliope.caktusgroup.com'
-    production_db = 'PROJECT_NAME_prod'
-    settings = 'local_settings.py'
-    local_db = local('grep DATABASE_NAME "%s" | cut -d"\'" -f2' % settings)
-    local('dropdb %s' % local_db)
-    local('createdb %s' % local_db)
-    cmd = 'ssh -C %s pg_dump -Ox %s | psql %s' % (database_server,
-                                                  production_db,
-                                                  local_db)
-    local(cmd)

caktus_django_template/template/local_settings.py.example

-from PROJECT_NAME.settings import *
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': '',                      # Or path to database file if using sqlite3.
-        'USER': '',                      # Not used with sqlite3.
-        'PASSWORD': '',                  # Not used with sqlite3.
-        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
-        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
-    }
-}
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-SERVE_STATIC_MEDIA = True

caktus_django_template/template/manage.py

-#!/usr/bin/env python
-
-import sys
-import os.path
-
-# remove '.' from the path
-sys.path.pop(0)
-# add project directory to path
-PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
-sys.path.insert(0, os.path.dirname(PROJECT_ROOT))
-
-from django.core.management import execute_manager
-try:
-    import PROJECT_NAME.settings # Assumed to be in the same directory.
-except ImportError:
-    import sys
-    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
-    sys.exit(1)
-
-if __name__ == "__main__":
-    execute_manager(PROJECT_NAME.settings)

caktus_django_template/template/requirements/apps.txt

--e svn+http://code.djangoproject.com/svn/django/trunk/#egg=django

caktus_django_template/template/settings.py

-# Django settings for PROJECT_NAME project.
-
-from os import path
-
-PROJECT_PATH = path.abspath('%s' % path.dirname(__file__))
-
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-
-ADMINS = (
-    # ('Your Name', 'your_email@domain.com'),
-)
-
-MANAGERS = ADMINS
-
-# Local time zone for this installation. Choices can be found here:
-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
-# although not all choices may be available on all operating systems.
-# On Unix systems, a value of None will cause Django to use the same
-# timezone as the operating system.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = 'America/Chicago'
-
-# Language code for this installation. All choices can be found here:
-# http://www.i18nguy.com/unicode/language-identifiers.html
-LANGUAGE_CODE = 'en-us'
-
-SITE_ID = 1
-
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = True
-
-# If you set this to False, Django will not format dates, numbers and
-# calendars according to the current locale
-USE_L10N = True
-
-URL_PREFIX = ''
-
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/"
-MEDIA_ROOT = '%s/media/' % PROJECT_PATH
-
-# URL that handles the media served from MEDIA_ROOT. Make sure to use a
-# trailing slash if there is a path component (optional in other cases).
-# Examples: "http://media.lawrence.com", "http://example.com/media/"
-MEDIA_URL = '/%smedia/' % URL_PREFIX
-
-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
-# trailing slash.
-# Examples: "http://foo.com/media/", "/media/".
-ADMIN_MEDIA_PREFIX = '/admin-media/'
-
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.Loader',
-    'django.template.loaders.app_directories.Loader',
-#     'django.template.loaders.eggs.Loader',
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = [
-    'django.contrib.auth.context_processors.auth',
-    'django.core.context_processors.debug',
-    'django.core.context_processors.i18n',
-    'django.core.context_processors.media',
-    'django.core.context_processors.request',
-    'django.contrib.messages.context_processors.messages',
-]
-
-MIDDLEWARE_CLASSES = (
-    'django.middleware.common.CommonMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.middleware.csrf.CsrfViewMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-    'django.contrib.messages.middleware.MessageMiddleware',
-)
-
-ROOT_URLCONF = 'PROJECT_NAME.urls'
-
-TEMPLATE_DIRS = (
-    '%s/templates' % PROJECT_PATH,
-)
-
-INSTALLED_APPS = [
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'django.contrib.messages',
-    'django.contrib.admin',
-]

caktus_django_template/template/settings_production.py

-from PROJECT_NAME.settings import *