From bff105aac3e1f6dd25ad7786c38e773d06e55047 Mon Sep 17 00:00:00 2001 From: Seth Woodworth Date: Wed, 2 Jan 2013 13:55:16 -0500 Subject: [PATCH] basing the django project on rdegges' django-skel --- .gitignore | 27 +++- Procfile | 3 + README.md | 4 - README.rst | 35 +++++ docs/Makefile | 153 +++++++++++++++++++ fabfile.py | 123 +++++++++++++++ gunicorn.py.ini | 15 ++ karmaworld/__init__.py | 0 karmaworld/apps/__init__.py | 0 karmaworld/libs/__init__.py | 0 karmaworld/settings/__init__.py | 0 karmaworld/settings/common.py | 259 ++++++++++++++++++++++++++++++++ karmaworld/settings/dev.py | 68 +++++++++ karmaworld/settings/prod.py | 131 ++++++++++++++++ karmaworld/templates/404.html | 0 karmaworld/templates/500.html | 0 karmaworld/urls.py | 14 ++ manage.py | 10 ++ reqs/common.txt | 6 + reqs/dev.txt | 2 + reqs/prod.txt | 11 ++ requirements.txt | 2 + wsgi.py | 28 ++++ 23 files changed, 886 insertions(+), 5 deletions(-) create mode 100644 Procfile delete mode 100644 README.md create mode 100644 README.rst create mode 100644 docs/Makefile create mode 100644 fabfile.py create mode 100644 gunicorn.py.ini create mode 100644 karmaworld/__init__.py create mode 100644 karmaworld/apps/__init__.py create mode 100644 karmaworld/libs/__init__.py create mode 100644 karmaworld/settings/__init__.py create mode 100644 karmaworld/settings/common.py create mode 100644 karmaworld/settings/dev.py create mode 100644 karmaworld/settings/prod.py create mode 100644 karmaworld/templates/404.html create mode 100644 karmaworld/templates/500.html create mode 100644 karmaworld/urls.py create mode 100644 manage.py create mode 100644 reqs/common.txt create mode 100644 reqs/dev.txt create mode 100644 reqs/prod.txt create mode 100644 requirements.txt create mode 100644 wsgi.py diff --git a/.gitignore b/.gitignore index d9437c3..1a29963 100644 --- a/.gitignore +++ b/.gitignore @@ -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 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 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 index 0000000..5727db0 --- /dev/null +++ b/README.rst @@ -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 index 0000000..ffe2347 --- /dev/null +++ b/docs/Makefile @@ -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 ' where 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 index 0000000..2ba37d3 --- /dev/null +++ b/fabfile.py @@ -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!&^7l28k&nrm2ek(qqo&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 index 0000000..ea0062f --- /dev/null +++ b/gunicorn.py.ini @@ -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 index 0000000..e69de29 diff --git a/karmaworld/apps/__init__.py b/karmaworld/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/karmaworld/libs/__init__.py b/karmaworld/libs/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/karmaworld/settings/__init__.py b/karmaworld/settings/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/karmaworld/settings/common.py b/karmaworld/settings/common.py new file mode 100644 index 0000000..0aecfb4 --- /dev/null +++ b/karmaworld/settings/common.py @@ -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!&^7l28k&nrm2ek(qqo&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 index 0000000..2fd3297 --- /dev/null +++ b/karmaworld/settings/dev.py @@ -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 index 0000000..0cdad93 --- /dev/null +++ b/karmaworld/settings/prod.py @@ -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 index 0000000..e69de29 diff --git a/karmaworld/templates/500.html b/karmaworld/templates/500.html new file mode 100644 index 0000000..e69de29 diff --git a/karmaworld/urls.py b/karmaworld/urls.py new file mode 100644 index 0000000..27242b9 --- /dev/null +++ b/karmaworld/urls.py @@ -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 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 index 0000000..79a8f5b --- /dev/null +++ b/reqs/common.txt @@ -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 index 0000000..bae42f8 --- /dev/null +++ b/reqs/dev.txt @@ -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 index 0000000..0f18164 --- /dev/null +++ b/reqs/prod.txt @@ -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 index 0000000..903625d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +-r reqs/prod.txt +pylibmc==1.2.3 diff --git a/wsgi.py b/wsgi.py new file mode 100644 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) -- 2.25.1