basing the django project on rdegges' django-skel
authorSeth Woodworth <seth@sethish.com>
Wed, 2 Jan 2013 18:55:16 +0000 (13:55 -0500)
committerSeth Woodworth <seth@sethish.com>
Wed, 2 Jan 2013 18:55:16 +0000 (13:55 -0500)
23 files changed:
.gitignore
Procfile [new file with mode: 0644]
README.md [deleted file]
README.rst [new file with mode: 0644]
docs/Makefile [new file with mode: 0644]
fabfile.py [new file with mode: 0644]
gunicorn.py.ini [new file with mode: 0644]
karmaworld/__init__.py [new file with mode: 0644]
karmaworld/apps/__init__.py [new file with mode: 0644]
karmaworld/libs/__init__.py [new file with mode: 0644]
karmaworld/settings/__init__.py [new file with mode: 0644]
karmaworld/settings/common.py [new file with mode: 0644]
karmaworld/settings/dev.py [new file with mode: 0644]
karmaworld/settings/prod.py [new file with mode: 0644]
karmaworld/templates/404.html [new file with mode: 0644]
karmaworld/templates/500.html [new file with mode: 0644]
karmaworld/urls.py [new file with mode: 0644]
manage.py [new file with mode: 0644]
reqs/common.txt [new file with mode: 0644]
reqs/dev.txt [new file with mode: 0644]
reqs/prod.txt [new file with mode: 0644]
requirements.txt [new file with mode: 0644]
wsgi.py [new file with mode: 0644]

index d9437c313b18796111867fa421ede31c16ad69dc..1a29963c325cf0507b2d12bb31037edadfb6d210 100644 (file)
@@ -1,4 +1,29 @@
+# Python bytecode:
+*.py[co]
+
+# Packaging files:
+*.egg*
+
+# Editor temp files:
+*.swp
+*.swo
+*~
+
+# Sphinx docs:
+build
+
+# SQLite3 database files:
+*.db
+
+# Celerybeat scheduler file:
+celerybeat-schedule
+
+# log files:
+log
 *.log
+
+# Translations:
 *.pot
-*.pyc
+
+# deployment specific django files:
 local_settings.py
diff --git a/Procfile b/Procfile
new file mode 100644 (file)
index 0000000..7095cd1
--- /dev/null
+++ b/Procfile
@@ -0,0 +1,3 @@
+web: newrelic-admin run-program gunicorn -c gunicorn.py.ini wsgi:application
+scheduler: python manage.py celery worker -B -E --maxtasksperchild=1000
+worker: python manage.py celery worker -E --maxtasksperchild=1000
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index 90d9af3..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-karmaworld
-==========
-
-KarmaNotes.org v3.0
\ No newline at end of file
diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..5727db0
--- /dev/null
@@ -0,0 +1,35 @@
+==========
+KarmaWorld
+==========
+:Description: A django application for sharing and uploading class notes.
+:Copyright: FinalsClub, a 501c3 non-profit organization
+:License: GPLv3 except where otherwise noted
+:Contact: info@karmanotes.org
+
+v3.0 of the karmanotes.org website from the FinalsClub 
+
+
+
+
+Purpose
+=======
+
+TODO: Explain what problems KarmaNotes is solving
+
+Docs
+====
+
+TODO: see `./docs/`
+TODO: Put docs on [RTFD](https://readthedocs.org/)
+
+
+Install
+=======
+
+
+Thanks
+======
+
+* TODO: Add funders
+* [rdegges](https://github.com/rdegges/django-skel) for the django-skel template
+
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644 (file)
index 0000000..ffe2347
--- /dev/null
@@ -0,0 +1,153 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+       @echo "Please use \`make <target>' where <target> is one of"
+       @echo "  html       to make standalone HTML files"
+       @echo "  dirhtml    to make HTML files named index.html in directories"
+       @echo "  singlehtml to make a single large HTML file"
+       @echo "  pickle     to make pickle files"
+       @echo "  json       to make JSON files"
+       @echo "  htmlhelp   to make HTML files and a HTML help project"
+       @echo "  qthelp     to make HTML files and a qthelp project"
+       @echo "  devhelp    to make HTML files and a Devhelp project"
+       @echo "  epub       to make an epub"
+       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+       @echo "  text       to make text files"
+       @echo "  man        to make manual pages"
+       @echo "  texinfo    to make Texinfo files"
+       @echo "  info       to make Texinfo files and run them through makeinfo"
+       @echo "  gettext    to make PO message catalogs"
+       @echo "  changes    to make an overview of all changed/added/deprecated items"
+       @echo "  linkcheck  to check all external links for integrity"
+       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+       -rm -rf $(BUILDDIR)/*
+
+html:
+       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+       @echo
+       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+       @echo
+       @echo "Build finished; now you can process the pickle files."
+
+json:
+       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+       @echo
+       @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+       @echo
+       @echo "Build finished; now you can run HTML Help Workshop with the" \
+             ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+       @echo
+       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-skel.qhcp"
+       @echo "To view the help file:"
+       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-skel.qhc"
+
+devhelp:
+       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+       @echo
+       @echo "Build finished."
+       @echo "To view the help file:"
+       @echo "# mkdir -p $$HOME/.local/share/devhelp/django-skel"
+       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-skel"
+       @echo "# devhelp"
+
+epub:
+       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+       @echo
+       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo
+       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+       @echo "Run \`make' in that directory to run these through (pdf)latex" \
+             "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through pdflatex..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf
+       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+       @echo
+       @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+       @echo
+       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo
+       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+       @echo "Run \`make' in that directory to run these through makeinfo" \
+             "(use \`make info' here to do that automatically)."
+
+info:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo "Running Texinfo files through makeinfo..."
+       make -C $(BUILDDIR)/texinfo info
+       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+       @echo
+       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+       @echo
+       @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+       @echo
+       @echo "Link check complete; look for any errors in the above output " \
+             "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+       @echo "Testing of doctests in the sources finished, look at the " \
+             "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/fabfile.py b/fabfile.py
new file mode 100644 (file)
index 0000000..2ba37d3
--- /dev/null
@@ -0,0 +1,123 @@
+"""Management utilities."""
+
+
+from fabric.contrib.console import confirm
+from fabric.api import abort, env, local, settings, task
+
+
+########## GLOBALS
+env.run = 'heroku run python manage.py'
+HEROKU_ADDONS = (
+    'cloudamqp:lemur',
+    'heroku-postgresql:dev',
+    'scheduler:standard',
+    'memcache:5mb',
+    'newrelic:standard',
+    'pgbackups:auto-month',
+    'sentry:developer',
+)
+HEROKU_CONFIGS = (
+    'DJANGO_SETTINGS_MODULE=karmaworld.settings.prod',
+    'SECRET_KEY=(s1k!&amp;^7l28k&amp;nrm2ek(qqo&amp;19%y(zn#=^zq_*ur2@irjun0x4'
+    'AWS_ACCESS_KEY_ID=xxx',
+    'AWS_SECRET_ACCESS_KEY=xxx',
+    'AWS_STORAGE_BUCKET_NAME=xxx',
+)
+########## END GLOBALS
+
+
+########## HELPERS
+def cont(cmd, message):
+    """Given a command, ``cmd``, and a message, ``message``, allow a user to
+    either continue or break execution if errors occur while executing ``cmd``.
+
+    :param str cmd: The command to execute on the local system.
+    :param str message: The message to display to the user on failure.
+
+    .. note::
+        ``message`` should be phrased in the form of a question, as if ``cmd``'s
+        execution fails, we'll ask the user to press 'y' or 'n' to continue or
+        cancel exeuction, respectively.
+
+    Usage::
+
+        cont('heroku run ...', "Couldn't complete %s. Continue anyway?" % cmd)
+    """
+    with settings(warn_only=True):
+        result = local(cmd, capture=True)
+
+    if message and result.failed and not confirm(message):
+        abort('Stopped execution per user request.')
+########## END HELPERS
+
+
+########## DATABASE MANAGEMENT
+@task
+def syncdb():
+    """Run a syncdb."""
+    local('%(run)s syncdb --noinput' % env)
+
+
+@task
+def migrate(app=None):
+    """Apply one (or more) migrations. If no app is specified, fabric will
+    attempt to run a site-wide migration.
+
+    :param str app: Django app name to migrate.
+    """
+    if app:
+        local('%s migrate %s --noinput' % (env.run, app))
+    else:
+        local('%(run)s migrate --noinput' % env)
+########## END DATABASE MANAGEMENT
+
+
+########## FILE MANAGEMENT
+@task
+def collectstatic():
+    """Collect all static files, and copy them to S3 for production usage."""
+    local('%(run)s collectstatic --noinput' % env)
+########## END FILE MANAGEMENT
+
+
+########## HEROKU MANAGEMENT
+@task
+def bootstrap():
+    """Bootstrap your new application with Heroku, preparing it for a production
+    deployment. This will:
+
+        - Create a new Heroku application.
+        - Install all ``HEROKU_ADDONS``.
+        - Sync the database.
+        - Apply all database migrations.
+        - Initialize New Relic's monitoring add-on.
+    """
+    cont('heroku create', "Couldn't create the Heroku app, continue anyway?")
+
+    for addon in HEROKU_ADDONS:
+        cont('heroku addons:add %s' % addon,
+            "Couldn't add %s to your Heroku app, continue anyway?" % addon)
+
+    for config in HEROKU_CONFIGS:
+        cont('heroku config:add %s' % config,
+            "Couldn't add %s to your Heroku app, continue anyway?" % config)
+
+    cont('git push heroku master',
+            "Couldn't push your application to Heroku, continue anyway?")
+
+    syncdb()
+    migrate()
+
+    cont('%(run)s newrelic-admin validate-config - stdout' % env,
+            "Couldn't initialize New Relic, continue anyway?")
+
+
+@task
+def destroy():
+    """Destroy this Heroku application. Wipe it from existance.
+
+    .. note::
+        This really will completely destroy your application. Think twice.
+    """
+    local('heroku apps:destroy')
+########## END HEROKU MANAGEMENT
diff --git a/gunicorn.py.ini b/gunicorn.py.ini
new file mode 100644 (file)
index 0000000..ea0062f
--- /dev/null
@@ -0,0 +1,15 @@
+"""gunicorn WSGI server configuration."""
+
+
+from multiprocessing import cpu_count
+from os import environ
+
+
+def max_workers():
+    return cpu_count()
+
+
+bind = '0.0.0.0:' + environ.get('PORT', '8000')
+max_requests = 1000
+worker_class = 'gevent'
+workers = max_workers()
diff --git a/karmaworld/__init__.py b/karmaworld/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/apps/__init__.py b/karmaworld/apps/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/libs/__init__.py b/karmaworld/libs/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/settings/__init__.py b/karmaworld/settings/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/settings/common.py b/karmaworld/settings/common.py
new file mode 100644 (file)
index 0000000..0aecfb4
--- /dev/null
@@ -0,0 +1,259 @@
+"""Common settings and globals."""
+
+
+from datetime import timedelta
+from os.path import abspath, basename, dirname, join, normpath
+from sys import path
+
+from djcelery import setup_loader
+
+
+########## PATH CONFIGURATION
+# Absolute filesystem path to the Django project directory:
+DJANGO_ROOT = dirname(dirname(abspath(__file__)))
+
+# Absolute filesystem path to the top-level project folder:
+SITE_ROOT = dirname(DJANGO_ROOT)
+
+# Site name:
+SITE_NAME = basename(DJANGO_ROOT)
+
+# Add our project to our pythonpath, this way we don't need to type our project
+# name in our dotted import paths:
+path.append(DJANGO_ROOT)
+########## END PATH CONFIGURATION
+
+
+########## DEBUG CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
+DEBUG = False
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
+TEMPLATE_DEBUG = DEBUG
+########## END DEBUG CONFIGURATION
+
+
+########## MANAGER CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
+ADMINS = (
+    ('Your Name', 'your_email@example.com'),
+)
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
+MANAGERS = ADMINS
+########## END MANAGER CONFIGURATION
+
+
+########## DATABASE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.',
+        'NAME': '',
+        'USER': '',
+        'PASSWORD': '',
+        'HOST': '',
+        'PORT': '',
+    }
+}
+########## END DATABASE CONFIGURATION
+
+
+########## GENERAL CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
+TIME_ZONE = 'America/Los_Angeles'
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
+LANGUAGE_CODE = 'en-us'
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
+SITE_ID = 1
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
+USE_I18N = True
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
+USE_L10N = True
+########## END GENERAL CONFIGURATION
+
+
+########## MEDIA CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
+MEDIA_ROOT = normpath(join(DJANGO_ROOT, 'media'))
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
+MEDIA_URL = '/media/'
+########## END MEDIA CONFIGURATION
+
+
+########## STATIC FILE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
+STATIC_ROOT = normpath(join(DJANGO_ROOT, 'static'))
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
+STATIC_URL = '/static/'
+
+# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
+STATICFILES_DIRS = (
+    normpath(join(DJANGO_ROOT, 'assets')),
+)
+
+# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
+STATICFILES_FINDERS = (
+    'django.contrib.staticfiles.finders.FileSystemFinder',
+    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+    'compressor.finders.CompressorFinder',
+)
+########## END STATIC FILE CONFIGURATION
+
+
+########## SECRET CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
+SECRET_KEY = r"(s1k!&amp;^7l28k&amp;nrm2ek(qqo&amp;19%y(zn#=^zq_*ur2@irjun0x4"
+########## END SECRET CONFIGURATION
+
+
+########## FIXTURE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
+FIXTURE_DIRS = (
+    normpath(join(DJANGO_ROOT, 'fixtures')),
+)
+########## END FIXTURE CONFIGURATION
+
+
+########## TEMPLATE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
+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.static',
+    'django.core.context_processors.tz',
+    'django.contrib.messages.context_processors.messages',
+    'django.core.context_processors.request',
+)
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+)
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
+TEMPLATE_DIRS = (
+    normpath(join(DJANGO_ROOT, 'templates')),
+)
+########## END TEMPLATE CONFIGURATION
+
+
+########## MIDDLEWARE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
+MIDDLEWARE_CLASSES = (
+    # Use GZip compression to reduce bandwidth.
+    'django.middleware.gzip.GZipMiddleware',
+
+    # Default Django middleware.
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+########## END MIDDLEWARE CONFIGURATION
+
+
+########## URL CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
+ROOT_URLCONF = '%s.urls' % SITE_NAME
+########## END URL CONFIGURATION
+
+
+########## APP CONFIGURATION
+DJANGO_APPS = (
+    # Default Django apps:
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+
+    # Useful template tags:
+    'django.contrib.humanize',
+
+    # Admin panel and documentation:
+    'django.contrib.admin',
+    'django.contrib.admindocs',
+)
+
+THIRD_PARTY_APPS = (
+    # Database migration helpers:
+    'south',
+
+    # Static file management:
+    'compressor',
+
+    # Asynchronous task queue:
+    'djcelery',
+)
+
+LOCAL_APPS = (
+)
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
+INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
+########## END APP CONFIGURATION
+
+
+########## LOGGING CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler'
+        }
+    },
+    'loggers': {
+        'django.request': {
+            'handlers': ['mail_admins'],
+            'level': 'ERROR',
+            'propagate': True,
+        },
+    }
+}
+########## END LOGGING CONFIGURATION
+
+
+########## CELERY CONFIGURATION
+# See: http://celery.readthedocs.org/en/latest/configuration.html#celery-task-result-expires
+CELERY_TASK_RESULT_EXPIRES = timedelta(minutes=30)
+
+# See: http://celery.github.com/celery/django/
+setup_loader()
+########## END CELERY CONFIGURATION
+
+
+########## WSGI CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
+WSGI_APPLICATION = 'wsgi.application'
+########## END WSGI CONFIGURATION
+
+
+########## COMPRESSION CONFIGURATION
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED
+COMPRESS_ENABLED = True
+
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_CSS_FILTERS
+COMPRESS_CSS_FILTERS = [
+    'compressor.filters.template.TemplateFilter',
+]
+
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_JS_FILTERS
+COMPRESS_JS_FILTERS = [
+    'compressor.filters.template.TemplateFilter',
+]
+########## END COMPRESSION CONFIGURATION
diff --git a/karmaworld/settings/dev.py b/karmaworld/settings/dev.py
new file mode 100644 (file)
index 0000000..2fd3297
--- /dev/null
@@ -0,0 +1,68 @@
+"""Development settings and globals."""
+
+
+from os.path import join, normpath
+
+from common import *
+
+
+########## DEBUG CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
+DEBUG = True
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
+TEMPLATE_DEBUG = DEBUG
+########## END DEBUG CONFIGURATION
+
+
+########## EMAIL CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
+EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+########## END EMAIL CONFIGURATION
+
+
+########## DATABASE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': normpath(join(DJANGO_ROOT, 'default.db')),
+        'USER': '',
+        'PASSWORD': '',
+        'HOST': '',
+        'PORT': '',
+    }
+}
+########## END DATABASE CONFIGURATION
+
+
+########## CACHE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
+    }
+}
+########## END CACHE CONFIGURATION
+
+
+########## CELERY CONFIGURATION
+# See: http://docs.celeryq.org/en/latest/configuration.html#celery-always-eager
+CELERY_ALWAYS_EAGER = True
+########## END CELERY CONFIGURATION
+
+
+########## TOOLBAR CONFIGURATION
+# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation
+INSTALLED_APPS += (
+    'debug_toolbar',
+)
+
+# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation
+INTERNAL_IPS = ('127.0.0.1',)
+
+# See: https://github.com/django-debug-toolbar/django-debug-toolbar#installation
+MIDDLEWARE_CLASSES += (
+    'debug_toolbar.middleware.DebugToolbarMiddleware',
+)
+########## END TOOLBAR CONFIGURATION
diff --git a/karmaworld/settings/prod.py b/karmaworld/settings/prod.py
new file mode 100644 (file)
index 0000000..0cdad93
--- /dev/null
@@ -0,0 +1,131 @@
+"""Production settings and globals."""
+
+
+from os import environ
+
+from memcacheify import memcacheify
+from postgresify import postgresify
+from S3 import CallingFormat
+
+from common import *
+
+
+########## EMAIL CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
+EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-host
+EMAIL_HOST = environ.get('EMAIL_HOST', 'smtp.gmail.com')
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-host-password
+EMAIL_HOST_PASSWORD = environ.get('EMAIL_HOST_PASSWORD', '')
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-host-user
+EMAIL_HOST_USER = environ.get('EMAIL_HOST_USER', 'your_email@example.com')
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-port
+EMAIL_PORT = environ.get('EMAIL_PORT', 587)
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-subject-prefix
+EMAIL_SUBJECT_PREFIX = '[%s] ' % SITE_NAME
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#email-use-tls
+EMAIL_USE_TLS = True
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#server-email
+SERVER_EMAIL = EMAIL_HOST_USER
+########## END EMAIL CONFIGURATION
+
+
+########## DATABASE CONFIGURATION
+DATABASES = postgresify()
+########## END DATABASE CONFIGURATION
+
+
+########## CACHE CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#caches
+CACHES = memcacheify()
+########## END CACHE CONFIGURATION
+
+
+########## CELERY CONFIGURATION
+# See: http://docs.celeryproject.org/en/latest/configuration.html#broker-transport
+BROKER_TRANSPORT = 'amqplib'
+
+# Set this number to the amount of allowed concurrent connections on your AMQP
+# provider, divided by the amount of active workers you have.
+#
+# For example, if you have the 'Little Lemur' CloudAMQP plan (their free tier),
+# they allow 3 concurrent connections. So if you run a single worker, you'd
+# want this number to be 3. If you had 3 workers running, you'd lower this
+# number to 1, since 3 workers each maintaining one open connection = 3
+# connections total.
+#
+# See: http://docs.celeryproject.org/en/latest/configuration.html#broker-pool-limit
+BROKER_POOL_LIMIT = 3
+
+# See: http://docs.celeryproject.org/en/latest/configuration.html#broker-connection-max-retries
+BROKER_CONNECTION_MAX_RETRIES = 0
+
+# See: http://docs.celeryproject.org/en/latest/configuration.html#broker-url
+BROKER_URL = environ.get('RABBITMQ_URL') or environ.get('CLOUDAMQP_URL')
+
+# See: http://docs.celeryproject.org/en/latest/configuration.html#celery-result-backend
+CELERY_RESULT_BACKEND = 'amqp'
+########## END CELERY CONFIGURATION
+
+
+########## STORAGE CONFIGURATION
+# See: http://django-storages.readthedocs.org/en/latest/index.html
+INSTALLED_APPS += (
+    'storages',
+)
+
+# See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings
+STATICFILES_STORAGE = DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
+
+# See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings
+AWS_CALLING_FORMAT = CallingFormat.SUBDOMAIN
+
+# See: http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html#settings
+AWS_ACCESS_KEY_ID = environ.get('AWS_ACCESS_KEY_ID', '')
+AWS_SECRET_ACCESS_KEY = environ.get('AWS_SECRET_ACCESS_KEY', '')
+AWS_STORAGE_BUCKET_NAME = environ.get('AWS_STORAGE_BUCKET_NAME', '')
+AWS_AUTO_CREATE_BUCKET = True
+AWS_QUERYSTRING_AUTH = False
+
+# AWS cache settings, don't change unless you know what you're doing:
+AWS_EXPIREY = 60 * 60 * 24 * 7
+AWS_HEADERS = {
+    'Cache-Control': 'max-age=%d, s-maxage=%d, must-revalidate' % (AWS_EXPIREY,
+        AWS_EXPIREY)
+}
+
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
+STATIC_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
+########## END STORAGE CONFIGURATION
+
+
+########## COMPRESSION CONFIGURATION
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE
+COMPRESS_OFFLINE = True
+
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE
+COMPRESS_STORAGE = DEFAULT_FILE_STORAGE
+
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_CSS_FILTERS
+COMPRESS_CSS_FILTERS += [
+    'compressor.filters.cssmin.CSSMinFilter',
+]
+
+# See: http://django_compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_JS_FILTERS
+COMPRESS_JS_FILTERS += [
+    'compressor.filters.jsmin.JSMinFilter',
+]
+########## END COMPRESSION CONFIGURATION
+
+
+########## SECRET CONFIGURATION
+# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
+SECRET_KEY = environ.get('SECRET_KEY', SECRET_KEY)
+########## END SECRET CONFIGURATION
diff --git a/karmaworld/templates/404.html b/karmaworld/templates/404.html
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/templates/500.html b/karmaworld/templates/500.html
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/karmaworld/urls.py b/karmaworld/urls.py
new file mode 100644 (file)
index 0000000..27242b9
--- /dev/null
@@ -0,0 +1,14 @@
+from django.contrib import admin
+from django.conf.urls.defaults import patterns, include, url
+
+
+# See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#hooking-adminsite-instances-into-your-urlconf
+admin.autodiscover()
+
+
+# See: https://docs.djangoproject.com/en/dev/topics/http/urls/
+urlpatterns = patterns('',
+    # Admin panel and documentation:
+    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+    url(r'^admin/', include(admin.site.urls)),
+)
diff --git a/manage.py b/manage.py
new file mode 100644 (file)
index 0000000..ba39bf6
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "karmaworld.settings.dev")
+
+    from django.core.management import execute_from_command_line
+
+    execute_from_command_line(sys.argv)
diff --git a/reqs/common.txt b/reqs/common.txt
new file mode 100644 (file)
index 0000000..79a8f5b
--- /dev/null
@@ -0,0 +1,6 @@
+Django>=1.4.0,<=1.4.9
+django-celery==3.0.11
+django-compressor==1.2
+Fabric==1.4.3
+South==0.7.6
+Sphinx==1.1.3
diff --git a/reqs/dev.txt b/reqs/dev.txt
new file mode 100644 (file)
index 0000000..bae42f8
--- /dev/null
@@ -0,0 +1,2 @@
+-r common.txt
+django-debug-toolbar==0.9.4
diff --git a/reqs/prod.txt b/reqs/prod.txt
new file mode 100644 (file)
index 0000000..0f18164
--- /dev/null
@@ -0,0 +1,11 @@
+-r common.txt
+boto==2.6.0
+cssmin==0.1.4
+django-heroku-memcacheify==0.3
+django-heroku-postgresify==0.2
+django-storages==1.1.4
+gevent==0.13.8
+gunicorn==0.14.3
+jsmin==2.0.2
+newrelic==1.3.0.289
+psycopg2==2.4.5
diff --git a/requirements.txt b/requirements.txt
new file mode 100644 (file)
index 0000000..903625d
--- /dev/null
@@ -0,0 +1,2 @@
+-r reqs/prod.txt
+pylibmc==1.2.3
diff --git a/wsgi.py b/wsgi.py
new file mode 100644 (file)
index 0000000..86b0b88
--- /dev/null
+++ b/wsgi.py
@@ -0,0 +1,28 @@
+"""
+WSGI config for karmaworld project.
+
+This module contains the WSGI application used by Django's development server
+and any production WSGI deployments. It should expose a module-level variable
+named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
+this application via the ``WSGI_APPLICATION`` setting.
+
+Usually you will have the standard Django WSGI application here, but it also
+might make sense to replace the whole Django WSGI application with a custom one
+that later delegates to the Django one. For example, you could introduce WSGI
+middleware here, or combine a Django application with an application of another
+framework.
+
+"""
+import os
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "karmaworld.settings.dev")
+
+# This application object is used by any WSGI server configured to use this
+# file. This includes Django's development server, if the WSGI_APPLICATION
+# setting points here.
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
+
+# Apply WSGI middleware here.
+# from helloworld.wsgi import HelloWorldApplication
+# application = HelloWorldApplication(application)