Merge pull request #11 from MITx/move_settings
Reorganize settings files for different environments
This commit is contained in:
@@ -23,7 +23,7 @@ from django_future.csrf import ensure_csrf_cookie
|
||||
|
||||
from models import Registration, UserProfile, PendingNameChange, PendingEmailChange
|
||||
|
||||
log = logging.getLogger("mitx.user")
|
||||
log = logging.getLogger("mitx.student")
|
||||
|
||||
def csrf_token(context):
|
||||
''' A csrf token that can be included in a form.
|
||||
|
||||
14
envs/README.txt
Normal file
14
envs/README.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Transitional for moving to new settings scheme.
|
||||
|
||||
To use:
|
||||
django-admin.py runserver --settings=envs.dev --pythonpath=.
|
||||
|
||||
NOTE: Using manage.py will automatically run mitx/settings.py first, regardless
|
||||
of what you send it for an explicit --settings flag. It still works, but might
|
||||
have odd side effects. Using django-admin.py avoids that problem.
|
||||
django-admin.py is installed by default when you install Django.
|
||||
|
||||
To use with gunicorn_django in debug mode:
|
||||
|
||||
gunicorn_django envs/dev.py
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
# askbot livesettings
|
||||
"""
|
||||
There are other askbot settings in common.py that covers things like where the
|
||||
templates are located, etc. This file is purely for askbot forum *behavior*.
|
||||
This means things like karma limits, the ability to post questions as wikis,
|
||||
anonymous questions, etc.
|
||||
"""
|
||||
|
||||
LIVESETTINGS_OPTIONS = {
|
||||
1: {
|
||||
'DB' : False,
|
||||
@@ -88,9 +94,9 @@ LIVESETTINGS_OPTIONS = {
|
||||
'MIN_TITLE_LENGTH' : 1,
|
||||
'MIN_QUESTION_BODY_LENGTH' : 1,
|
||||
'MIN_ANSWER_BODY_LENGTH' : 1,
|
||||
'WIKI_ON' : True,
|
||||
'WIKI_ON' : False,
|
||||
'ALLOW_ASK_ANONYMOUSLY' : True,
|
||||
'ALLOW_POSTING_BEFORE_LOGGING_IN' : True,
|
||||
'ALLOW_POSTING_BEFORE_LOGGING_IN' : False,
|
||||
'ALLOW_SWAPPING_QUESTION_WITH_ANSWER' : False,
|
||||
'MAX_TAG_LENGTH' : 20,
|
||||
'MIN_TITLE_LENGTH' : 1,
|
||||
@@ -172,8 +178,8 @@ LIVESETTINGS_OPTIONS = {
|
||||
},
|
||||
'MARKUP' : {
|
||||
'MARKUP_CODE_FRIENDLY' : False,
|
||||
'ENABLE_MATHJAX' : False, # FIXME: Test with this enabled
|
||||
'MATHJAX_BASE_URL' : u'',
|
||||
'ENABLE_MATHJAX' : True,
|
||||
'MATHJAX_BASE_URL' : u'/static/js/mathjax-MathJax-c9db6ac/',
|
||||
'ENABLE_AUTO_LINKING' : False,
|
||||
'AUTO_LINK_PATTERNS' : u'',
|
||||
'AUTO_LINK_URLS' : u'',
|
||||
@@ -181,21 +187,21 @@ LIVESETTINGS_OPTIONS = {
|
||||
'MIN_REP' : {
|
||||
'MIN_REP_TO_ACCEPT_OWN_ANSWER' : 1,
|
||||
'MIN_REP_TO_ANSWER_OWN_QUESTION' : 1,
|
||||
'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS' : 100,
|
||||
'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS' : 1200,
|
||||
'MIN_REP_TO_CLOSE_OWN_QUESTIONS' : 1,
|
||||
'MIN_REP_TO_DELETE_OTHERS_COMMENTS' : 2000,
|
||||
'MIN_REP_TO_DELETE_OTHERS_POSTS' : 5000,
|
||||
'MIN_REP_TO_EDIT_OTHERS_POSTS' : 2000,
|
||||
'MIN_REP_TO_EDIT_WIKI' : 1,
|
||||
'MIN_REP_TO_DELETE_OTHERS_COMMENTS' : 5000,
|
||||
'MIN_REP_TO_DELETE_OTHERS_POSTS' : 10000,
|
||||
'MIN_REP_TO_EDIT_OTHERS_POSTS' : 5000,
|
||||
'MIN_REP_TO_EDIT_WIKI' : 200,
|
||||
'MIN_REP_TO_FLAG_OFFENSIVE' : 1,
|
||||
'MIN_REP_TO_HAVE_STRONG_URL' : 250,
|
||||
'MIN_REP_TO_LEAVE_COMMENTS' : 1,
|
||||
'MIN_REP_TO_LOCK_POSTS' : 4000,
|
||||
'MIN_REP_TO_LOCK_POSTS' : 10000,
|
||||
'MIN_REP_TO_REOPEN_OWN_QUESTIONS' : 1,
|
||||
'MIN_REP_TO_RETAG_OTHERS_QUESTIONS' : 1,
|
||||
'MIN_REP_TO_RETAG_OTHERS_QUESTIONS' : 100,
|
||||
'MIN_REP_TO_UPLOAD_FILES' : 1,
|
||||
'MIN_REP_TO_VIEW_OFFENSIVE_FLAGS' : 2000,
|
||||
'MIN_REP_TO_VOTE_DOWN' : 1,
|
||||
'MIN_REP_TO_VOTE_DOWN' : 15,
|
||||
'MIN_REP_TO_VOTE_UP' : 1,
|
||||
},
|
||||
'QA_SITE_SETTINGS' : {
|
||||
@@ -275,7 +281,7 @@ LIVESETTINGS_OPTIONS = {
|
||||
'VOTE_RULES' : {
|
||||
'MAX_VOTES_PER_USER_PER_DAY' : 30,
|
||||
'MAX_FLAGS_PER_USER_PER_DAY' : 5,
|
||||
'MIN_DAYS_FOR_STAFF_TO_ACCEPT_ANSWER' : 7,
|
||||
'MIN_DAYS_FOR_STAFF_TO_ACCEPT_ANSWER' : 0,
|
||||
'MIN_DAYS_TO_ANSWER_OWN_QUESTION' : 0,
|
||||
'MIN_FLAGS_TO_DELETE_POST' : 5,
|
||||
'MIN_FLAGS_TO_HIDE_POST' : 3,
|
||||
@@ -284,4 +290,4 @@ LIVESETTINGS_OPTIONS = {
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
50
envs/aws.py
Normal file
50
envs/aws.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
This is the default template for our main set of AWS servers. This does NOT
|
||||
cover the content machines, which use content.py
|
||||
|
||||
Common traits:
|
||||
* Use memcached, and cache-backed sessions
|
||||
* Use a MySQL 5.1 database
|
||||
"""
|
||||
import json
|
||||
|
||||
from common import *
|
||||
|
||||
############################### ALWAYS THE SAME ################################
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = False
|
||||
|
||||
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
|
||||
|
||||
########################### NON-SECURE ENV CONFIG ##############################
|
||||
# Things like server locations, ports, etc.
|
||||
with open(ENV_ROOT / "env.json") as env_file:
|
||||
ENV_TOKENS = json.load(env_file)
|
||||
|
||||
SITE_NAME = ENV_TOKENS['SITE_NAME']
|
||||
CSRF_COOKIE_DOMAIN = ENV_TOKENS['CSRF_COOKIE_DOMAIN']
|
||||
|
||||
BOOK_URL = ENV_TOKENS['BOOK_URL']
|
||||
MEDIA_URL = ENV_TOKENS['MEDIA_URL']
|
||||
LOG_DIR = ENV_TOKENS['LOG_DIR']
|
||||
|
||||
CACHES = ENV_TOKENS['CACHES']
|
||||
|
||||
LOGGING = logsettings.get_logger_config(LOG_DIR,
|
||||
logging_env=ENV_TOKENS['LOGGING_ENV'],
|
||||
syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514),
|
||||
debug=False)
|
||||
|
||||
############################## SECURE AUTH ITEMS ###############################
|
||||
# Secret things: passwords, access keys, etc.
|
||||
with open(ENV_ROOT / "auth.json") as auth_file:
|
||||
AUTH_TOKENS = json.load(auth_file)
|
||||
|
||||
SECRET_KEY = AUTH_TOKENS['SECRET_KEY']
|
||||
|
||||
AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"]
|
||||
AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"]
|
||||
|
||||
DATABASES = AUTH_TOKENS['DATABASES']
|
||||
@@ -2,15 +2,15 @@
|
||||
This is the common settings file, intended to set sane defaults. If you have a
|
||||
piece of configuration that's dependent on a set of feature flags being set,
|
||||
then create a function that returns the calculated value based on the value of
|
||||
MITX_FEATURES[...]. That classes that extend this one can change the feature
|
||||
MITX_FEATURES[...]. Modules that extend this one can change the feature
|
||||
configuration in an environment specific config file and re-calculate those
|
||||
values.
|
||||
|
||||
We should make a method that calls all these config methods so that you just
|
||||
make one call at the end of your site-specific dev file and it reset all the
|
||||
make one call at the end of your site-specific dev file to reset all the
|
||||
dependent variables (like INSTALLED_APPS) for you.
|
||||
|
||||
TODO:
|
||||
Longer TODO:
|
||||
1. Right now our treatment of static content in general and in particular
|
||||
course-specific static content is haphazard.
|
||||
2. We should have a more disciplined approach to feature flagging, even if it
|
||||
@@ -18,15 +18,14 @@ TODO:
|
||||
3. We need to handle configuration for multiple courses. This could be as
|
||||
multiple sites, but we do need a way to map their data assets.
|
||||
"""
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import djcelery
|
||||
from path import path
|
||||
|
||||
from askbotsettings import LIVESETTINGS_OPTIONS
|
||||
from askbotsettings import * # this is where LIVESETTINGS_OPTIONS comes from
|
||||
import logsettings
|
||||
|
||||
################################### FEATURES ###################################
|
||||
COURSEWARE_ENABLED = True
|
||||
@@ -39,21 +38,21 @@ MITX_FEATURES = {
|
||||
'SAMPLE' : False
|
||||
}
|
||||
|
||||
# Used for A/B testing
|
||||
DEFAULT_GROUPS = []
|
||||
|
||||
# If this is true, random scores will be generated for the purpose of debugging the profile graphs
|
||||
GENERATE_PROFILE_SCORES = False
|
||||
|
||||
############################# SET PATH INFORMATION #############################
|
||||
PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /mitxweb
|
||||
ENV_ROOT = PROJECT_ROOT.dirname() # virtualenv dir /mitxweb is in
|
||||
#ASKBOT_ROOT = ENV_ROOT / "3rdparty" / "askbot-devel"
|
||||
ASKBOT_ROOT = ENV_ROOT / "askbot-devel"
|
||||
#COURSES_ROOT = ENV_ROOT / "courses"
|
||||
COURSES_ROOT = ENV_ROOT / "data"
|
||||
|
||||
# FIXME: code shouldn't expect trailing "/"
|
||||
# FIXME: To support multiple courses, we should walk the courses dir at startup
|
||||
#DATA_DIR = COURSES_ROOT / "6002x" / ""
|
||||
DATA_DIR = COURSES_ROOT
|
||||
|
||||
#print DATA_DIR, COURSES_ROOT, ASKBOT_ROOT, ENV_ROOT, PROJECT_ROOT
|
||||
|
||||
sys.path.append(ENV_ROOT)
|
||||
sys.path.append(ASKBOT_ROOT)
|
||||
sys.path.append(ASKBOT_ROOT / "askbot" / "deps")
|
||||
@@ -61,35 +60,50 @@ sys.path.append(PROJECT_ROOT / 'djangoapps')
|
||||
sys.path.append(PROJECT_ROOT / 'lib')
|
||||
|
||||
################################## MITXWEB #####################################
|
||||
# This is where we stick our compiled template files
|
||||
# This is where we stick our compiled template files. Most of the app uses Mako
|
||||
# templates
|
||||
MAKO_MODULE_DIR = tempfile.mkdtemp('mako')
|
||||
MAKO_TEMPLATES = {}
|
||||
MAKO_TEMPLATES['course'] = [DATA_DIR]
|
||||
MAKO_TEMPLATES['sections'] = [DATA_DIR+'/sections']
|
||||
MAKO_TEMPLATES['custom_tags'] = [DATA_DIR+'/custom_tags']
|
||||
MAKO_TEMPLATES['main'] = [ENV_ROOT+'/templates/']
|
||||
MAKO_TEMPLATES['sections'] = [DATA_DIR / 'sections']
|
||||
MAKO_TEMPLATES['custom_tags'] = [DATA_DIR / 'custom_tags']
|
||||
MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates',
|
||||
DATA_DIR / 'info',
|
||||
DATA_DIR / 'problems']
|
||||
|
||||
TEXTBOOK_DIR = ENV_ROOT / "books" / "circuits_agarwal_lang"
|
||||
# This is where Django Template lookup is defined. There are a few of these
|
||||
# still left lying around.
|
||||
TEMPLATE_DIRS = (
|
||||
PROJECT_ROOT / "templates",
|
||||
DATA_DIR / "problems",
|
||||
)
|
||||
|
||||
# FIXME ???????? --
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
'django.core.context_processors.request',
|
||||
'askbot.context.application_settings',
|
||||
#'django.core.context_processors.i18n',
|
||||
'askbot.user_messages.context_processors.user_messages',#must be before auth
|
||||
'django.core.context_processors.auth', #this is required for admin
|
||||
'django.core.context_processors.csrf', #necessary for csrf protection
|
||||
)
|
||||
|
||||
|
||||
# FIXME:
|
||||
# We should have separate S3 staged URLs in case we need to make changes to
|
||||
# these assets and test them.
|
||||
LIB_URL = '/static/lib/'
|
||||
# LIB_URL = 'https://mitxstatic.s3.amazonaws.com/js/' # For AWS deploys
|
||||
LIB_URL = '/static/js/'
|
||||
|
||||
# Dev machines shouldn't need the book
|
||||
# BOOK_URL = '/static/book/'
|
||||
BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/' # For AWS deploys
|
||||
|
||||
# FIXME ??????? What are these exactly?
|
||||
# Configuration option for when we want to grab server error pages
|
||||
STATIC_GRAB = False
|
||||
DEV_CONTENT = True
|
||||
|
||||
# FIXME: Should we be doing this truncation?
|
||||
TRACK_MAX_EVENT = 1000
|
||||
|
||||
GENERATE_PROFILE_SCORES = False
|
||||
TRACK_MAX_EVENT = 10000
|
||||
DEBUG_TRACK_LOG = False
|
||||
|
||||
############################### DJANGO BUILT-INS ###############################
|
||||
# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here
|
||||
@@ -101,8 +115,8 @@ SITE_ID = 1
|
||||
SITE_NAME = "localhost:8000"
|
||||
CSRF_COOKIE_DOMAIN = '127.0.0.1'
|
||||
HTTPS = 'on'
|
||||
#ROOT_URLCONF = 'mitxweb.urls'
|
||||
ROOT_URLCONF = 'mitx.urls'
|
||||
IGNORABLE_404_ENDS = ('favicon.ico')
|
||||
|
||||
# Email
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
@@ -116,47 +130,16 @@ MANAGERS = ADMINS
|
||||
# Static content
|
||||
STATIC_URL = '/static/'
|
||||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
STATIC_ROOT = ENV_ROOT / "staticfiles" # FIXME: Should this and uploads be moved out of the repo?
|
||||
STATIC_ROOT = ENV_ROOT / "staticfiles" # We don't run collectstatic -- this is to appease askbot checks
|
||||
|
||||
# FIXME: We should iterate through the courses we have, adding the static
|
||||
# contents for each of them.
|
||||
# contents for each of them. (Right now we just use symlinks.)
|
||||
STATICFILES_DIRS = (
|
||||
# FIXME: Need to add entries for book, data/images, etc.
|
||||
# PROJECT_ROOT / "static",
|
||||
ENV_ROOT / "static",
|
||||
PROJECT_ROOT / "static",
|
||||
ASKBOT_ROOT / "askbot" / "skins",
|
||||
# ("circuits", DATA_DIR / "images"),
|
||||
# ("handouts", DATA_DIR / "handouts"),
|
||||
# ("subs", DATA_DIR / "subs"),
|
||||
# ("book", TEXTBOOK_DIR)
|
||||
)
|
||||
|
||||
print STATICFILES_DIRS
|
||||
|
||||
# Templates
|
||||
TEMPLATE_DIRS = (
|
||||
ENV_ROOT / "templates",
|
||||
# PROJECT_ROOT / "templates",
|
||||
# DATA_DIR / "problems",
|
||||
)
|
||||
|
||||
TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
'django.core.context_processors.request',
|
||||
'askbot.context.application_settings',
|
||||
#'django.core.context_processors.i18n',
|
||||
'askbot.user_messages.context_processors.user_messages',#must be before auth
|
||||
'django.core.context_processors.auth', #this is required for admin
|
||||
'django.core.context_processors.csrf', #necessary for csrf protection
|
||||
)
|
||||
|
||||
# Storage
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
MEDIA_ROOT = ENV_ROOT / "uploads"
|
||||
MEDIA_URL = "/discussion/upfiles/"
|
||||
FILE_UPLOAD_TEMP_DIR = os.path.join(os.path.dirname(__file__), 'tmp').replace('\\','/')
|
||||
FILE_UPLOAD_HANDLERS = (
|
||||
'django.core.files.uploadhandler.MemoryFileUploadHandler',
|
||||
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
|
||||
# This is how you would use the textbook images locally
|
||||
# ("book", ENV_ROOT / "book_images")
|
||||
)
|
||||
|
||||
# Locale/Internationalization
|
||||
@@ -165,80 +148,6 @@ LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
USE_I18N = True
|
||||
USE_L10N = True
|
||||
|
||||
################################### LOGGING ####################################
|
||||
# Might want to rewrite this to use logger code and push more things to the root
|
||||
# logger.
|
||||
pid = os.getpid() # So we can log which process is creating the log
|
||||
hostname = platform.node().split(".")[0]
|
||||
SYSLOG_ADDRESS = ('syslog.m.i4x.org', 514)
|
||||
|
||||
handlers = ['console']
|
||||
# FIXME: re-enable syslogger later
|
||||
# if not DEBUG:
|
||||
# handlers.append('syslogger')
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': True,
|
||||
'formatters' : {
|
||||
'standard' : {
|
||||
'format' : '%(asctime)s %(levelname)s %(process)d [%(name)s] %(filename)s:%(lineno)d - %(message)s',
|
||||
},
|
||||
'syslog_format' : {
|
||||
'format' : '[%(name)s] %(levelname)s [' + hostname + ' %(process)d] [%(filename)s:%(lineno)d] - %(message)s',
|
||||
},
|
||||
'raw' : {
|
||||
'format' : '%(message)s',
|
||||
}
|
||||
},
|
||||
'handlers' : {
|
||||
'console' : {
|
||||
'level' : 'DEBUG',
|
||||
'class' : 'logging.StreamHandler',
|
||||
'formatter' : 'standard',
|
||||
'stream' : sys.stdout,
|
||||
},
|
||||
'console_err' : {
|
||||
'level' : 'ERROR',
|
||||
'class' : 'logging.StreamHandler',
|
||||
'formatter' : 'standard',
|
||||
'stream' : sys.stderr,
|
||||
},
|
||||
'syslogger' : {
|
||||
'level' : 'INFO',
|
||||
'class' : 'logging.handlers.SysLogHandler',
|
||||
'address' : SYSLOG_ADDRESS,
|
||||
'formatter' : 'syslog_format',
|
||||
},
|
||||
'mail_admins' : {
|
||||
'level': 'ERROR',
|
||||
'class': 'django.utils.log.AdminEmailHandler',
|
||||
},
|
||||
},
|
||||
'loggers' : {
|
||||
'django' : {
|
||||
'handlers' : handlers + ['mail_admins'],
|
||||
'propagate' : True,
|
||||
'level' : 'INFO'
|
||||
},
|
||||
'tracking' : {
|
||||
'handlers' : [] if DEBUG else ['syslogger'], # handlers,
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False,
|
||||
},
|
||||
'root' : {
|
||||
'handlers' : handlers,
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False
|
||||
},
|
||||
'mitx' : {
|
||||
'handlers' : handlers,
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#################################### AWS #######################################
|
||||
# S3BotoStorage insists on a timeout for uploaded assets. We should make it
|
||||
# permanent instead, but rather than trying to figure out exactly where that
|
||||
@@ -288,14 +197,19 @@ TEMPLATE_LOADERS = (
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'util.middleware.ExceptionLoggingMiddleware',
|
||||
'django.middleware.cache.UpdateCacheMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
|
||||
# Instead of AuthenticationMiddleware, we use a cached backed version
|
||||
#'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware',
|
||||
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'track.middleware.TrackMiddleware',
|
||||
'mitxmako.middleware.MakoMiddleware',
|
||||
# 'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||
|
||||
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
|
||||
'askbot.middleware.forum_mode.ForumModeMiddleware',
|
||||
'askbot.middleware.cancel.CancelActionMiddleware',
|
||||
@@ -303,46 +217,41 @@ MIDDLEWARE_CLASSES = (
|
||||
'askbot.middleware.view_log.ViewLogMiddleware',
|
||||
'askbot.middleware.spaceless.SpacelessMiddleware',
|
||||
# 'askbot.middleware.pagesize.QuestionsPageSizeMiddleware',
|
||||
# 'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||
)
|
||||
|
||||
################################### APPS #######################################
|
||||
def installed_apps():
|
||||
"""If you want to get a different set of INSTALLED_APPS out of this, you'll
|
||||
have to set ASKBOT_ENABLED and COURSEWARE_ENABLED to True/False and call
|
||||
this method. We can't just take these as params because other pieces of the
|
||||
code check fo the value of these constants.
|
||||
"""
|
||||
# We always install these
|
||||
STANDARD_APPS = ['django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.humanize',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'track',
|
||||
'util']
|
||||
COURSEWARE_APPS = ['circuit',
|
||||
'courseware',
|
||||
'student',
|
||||
'static_template_view',
|
||||
'staticbook',
|
||||
'simplewiki',
|
||||
'perfstats']
|
||||
ASKBOT_APPS = ['django.contrib.sitemaps',
|
||||
'django.contrib.admin',
|
||||
'south',
|
||||
'askbot.deps.livesettings',
|
||||
'askbot',
|
||||
'keyedcache',
|
||||
'robots',
|
||||
'django_countries',
|
||||
'djcelery',
|
||||
'djkombu',
|
||||
'followit']
|
||||
|
||||
return tuple(STANDARD_APPS +
|
||||
(COURSEWARE_APPS if COURSEWARE_ENABLED else []) +
|
||||
(ASKBOT_APPS if ASKBOT_ENABLED else []))
|
||||
INSTALLED_APPS = (
|
||||
# Standard ones that are always installed...
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.humanize',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.staticfiles',
|
||||
'south',
|
||||
|
||||
INSTALLED_APPS = installed_apps()
|
||||
# Our courseware
|
||||
'circuit',
|
||||
'courseware',
|
||||
'perfstats',
|
||||
'student',
|
||||
'static_template_view',
|
||||
'staticbook',
|
||||
'simplewiki',
|
||||
'track',
|
||||
'util',
|
||||
|
||||
# For Askbot
|
||||
'django.contrib.sitemaps',
|
||||
'django.contrib.admin',
|
||||
'django_countries',
|
||||
'djcelery',
|
||||
'djkombu',
|
||||
'askbot',
|
||||
'askbot.deps.livesettings',
|
||||
'followit',
|
||||
'keyedcache',
|
||||
'robots',
|
||||
)
|
||||
31
envs/content.py
Normal file
31
envs/content.py
Normal file
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
These are debug machines used for content creators, so they're kind of a cross
|
||||
between dev machines and AWS machines.
|
||||
"""
|
||||
from aws import *
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = True
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
################################ DEBUG TOOLBAR #################################
|
||||
INSTALLED_APPS += ('debug_toolbar',)
|
||||
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||
|
||||
DEBUG_TOOLBAR_PANELS = (
|
||||
'debug_toolbar.panels.version.VersionDebugPanel',
|
||||
'debug_toolbar.panels.timer.TimerDebugPanel',
|
||||
'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
|
||||
'debug_toolbar.panels.headers.HeaderDebugPanel',
|
||||
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
|
||||
'debug_toolbar.panels.sql.SQLDebugPanel',
|
||||
'debug_toolbar.panels.signals.SignalDebugPanel',
|
||||
'debug_toolbar.panels.logger.LoggingPanel',
|
||||
|
||||
# Enabling the profiler has a weird bug as of django-debug-toolbar==0.9.4 and
|
||||
# Django=1.3.1/1.4 where requests to views get duplicated (your method gets
|
||||
# hit twice). So you can uncomment when you need to diagnose performance
|
||||
# problems, but you shouldn't leave it on.
|
||||
# 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
|
||||
)
|
||||
81
envs/dev.py
Normal file
81
envs/dev.py
Normal file
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
This config file runs the simplest dev environment using sqlite, and db-based
|
||||
sessions. Assumes structure:
|
||||
|
||||
/envroot/
|
||||
/db # This is where it'll write the database file
|
||||
/mitx # The location of this repo
|
||||
/log # Where we're going to write log files
|
||||
"""
|
||||
from common import *
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = True
|
||||
|
||||
LOGGING = logsettings.get_logger_config(ENV_ROOT / "log",
|
||||
logging_env="dev",
|
||||
tracking_filename="tracking.log",
|
||||
debug=True)
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ENV_ROOT / "db" / "mitx.db",
|
||||
}
|
||||
}
|
||||
|
||||
CACHES = {
|
||||
# This is the cache used for most things. Askbot will not work without a
|
||||
# functioning cache -- it relies on caching to load its settings in places.
|
||||
# In staging/prod envs, the sessions also live here.
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
||||
'LOCATION': 'mitx_loc_mem_cache'
|
||||
},
|
||||
|
||||
# The general cache is what you get if you use our util.cache. It's used for
|
||||
# things like caching the course.xml file for different A/B test groups.
|
||||
# We set it to be a DummyCache to force reloading of course.xml in dev.
|
||||
# In staging environments, we would grab VERSION from data uploaded by the
|
||||
# push process.
|
||||
'general': {
|
||||
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
|
||||
'KEY_PREFIX': 'general',
|
||||
'VERSION': 4,
|
||||
}
|
||||
}
|
||||
|
||||
# Dummy secret key for dev
|
||||
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
################################ DEBUG TOOLBAR #################################
|
||||
INSTALLED_APPS += ('debug_toolbar',)
|
||||
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||
INTERNAL_IPS = ('127.0.0.1',)
|
||||
|
||||
DEBUG_TOOLBAR_PANELS = (
|
||||
'debug_toolbar.panels.version.VersionDebugPanel',
|
||||
'debug_toolbar.panels.timer.TimerDebugPanel',
|
||||
'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
|
||||
'debug_toolbar.panels.headers.HeaderDebugPanel',
|
||||
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
|
||||
'debug_toolbar.panels.sql.SQLDebugPanel',
|
||||
'debug_toolbar.panels.signals.SignalDebugPanel',
|
||||
'debug_toolbar.panels.logger.LoggingPanel',
|
||||
|
||||
# Enabling the profiler has a weird bug as of django-debug-toolbar==0.9.4 and
|
||||
# Django=1.3.1/1.4 where requests to views get duplicated (your method gets
|
||||
# hit twice). So you can uncomment when you need to diagnose performance
|
||||
# problems, but you shouldn't leave it on.
|
||||
# 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
|
||||
)
|
||||
|
||||
############################ FILE UPLOADS (ASKBOT) #############################
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
MEDIA_ROOT = ENV_ROOT / "uploads"
|
||||
MEDIA_URL = "/discussion/upfiles/"
|
||||
FILE_UPLOAD_TEMP_DIR = ENV_ROOT / "uploads"
|
||||
FILE_UPLOAD_HANDLERS = (
|
||||
'django.core.files.uploadhandler.MemoryFileUploadHandler',
|
||||
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
|
||||
)
|
||||
42
envs/devplus.py
Normal file
42
envs/devplus.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
This config file tries to mimic the production environment more closely than the
|
||||
normal dev.py. It assumes you're running a local instance of MySQL 5.1 and that
|
||||
you're running memcached. You'll want to use this to test caching and database
|
||||
migrations.
|
||||
|
||||
Assumptions:
|
||||
* MySQL 5.1 (version important -- askbot breaks on 5.5)
|
||||
|
||||
Dir structure:
|
||||
/envroot/
|
||||
/mitx # The location of this repo
|
||||
/log # Where we're going to write log files
|
||||
|
||||
"""
|
||||
from dev import *
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': 'wwc',
|
||||
'USER': 'root',
|
||||
'PASSWORD': '',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '3306',
|
||||
}
|
||||
}
|
||||
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': '127.0.0.1:11211',
|
||||
},
|
||||
'general': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': '127.0.0.1:11211',
|
||||
'KEY_PREFIX' : 'general',
|
||||
'VERSION' : 5,
|
||||
}
|
||||
}
|
||||
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
86
envs/logsettings.py
Normal file
86
envs/logsettings.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
import os.path
|
||||
import platform
|
||||
import sys
|
||||
|
||||
def get_logger_config(log_dir,
|
||||
logging_env="no_env",
|
||||
tracking_filename=None,
|
||||
syslog_addr=None,
|
||||
debug=False):
|
||||
"""Return the appropriate logging config dictionary. You should assign the
|
||||
result of this to the LOGGING var in your settings. The reason it's done
|
||||
this way instead of registering directly is because I didn't want to worry
|
||||
about resetting the logging state if this is called multiple times when
|
||||
settings are extended."""
|
||||
|
||||
# If we're given an explicit place to put tracking logs, we do that (say for
|
||||
# debugging). However, logging is not safe for multiple processes hitting
|
||||
# the same file. So if it's left blank, we dynamically create the filename
|
||||
# based on the PID of this worker process.
|
||||
if tracking_filename:
|
||||
tracking_file_loc = os.path.join(log_dir, tracking_filename)
|
||||
else:
|
||||
pid = os.getpid() # So we can log which process is creating the log
|
||||
tracking_file_loc = os.path.join(log_dir, "tracking_{0}.log".format(pid))
|
||||
|
||||
hostname = platform.node().split(".")[0]
|
||||
syslog_format = ("[%(name)s][env:{logging_env}] %(levelname)s [{hostname} " +
|
||||
" %(process)d] [%(filename)s:%(lineno)d] - %(message)s").format(
|
||||
logging_env=logging_env, hostname=hostname)
|
||||
|
||||
handlers = ['console'] if debug else ['console', 'syslogger']
|
||||
|
||||
return {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': True,
|
||||
'formatters' : {
|
||||
'standard' : {
|
||||
'format' : '%(asctime)s %(levelname)s %(process)d [%(name)s] %(filename)s:%(lineno)d - %(message)s',
|
||||
},
|
||||
'syslog_format' : { 'format' : syslog_format },
|
||||
'raw' : { 'format' : '%(message)s' },
|
||||
},
|
||||
'handlers' : {
|
||||
'console' : {
|
||||
'level' : 'DEBUG' if debug else 'INFO',
|
||||
'class' : 'logging.StreamHandler',
|
||||
'formatter' : 'standard',
|
||||
'stream' : sys.stdout,
|
||||
},
|
||||
'syslogger' : {
|
||||
'level' : 'INFO',
|
||||
'class' : 'logging.handlers.SysLogHandler',
|
||||
'address' : syslog_addr,
|
||||
'formatter' : 'syslog_format',
|
||||
},
|
||||
'tracking' : {
|
||||
'level' : 'DEBUG',
|
||||
'class' : 'logging.handlers.WatchedFileHandler',
|
||||
'filename' : tracking_file_loc,
|
||||
'formatter' : 'raw',
|
||||
},
|
||||
},
|
||||
'loggers' : {
|
||||
'django' : {
|
||||
'handlers' : handlers,
|
||||
'propagate' : True,
|
||||
'level' : 'INFO'
|
||||
},
|
||||
'tracking' : {
|
||||
'handlers' : ['tracking'],
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False,
|
||||
},
|
||||
'root' : {
|
||||
'handlers' : handlers,
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False
|
||||
},
|
||||
'mitx' : {
|
||||
'handlers' : handlers,
|
||||
'level' : 'DEBUG',
|
||||
'propagate' : False
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
django<1.4
|
||||
pip
|
||||
flup
|
||||
scipy
|
||||
matplotlib
|
||||
markdown
|
||||
@@ -12,3 +11,6 @@ boto
|
||||
mako
|
||||
python-memcached
|
||||
django-celery
|
||||
path.py
|
||||
django_debug_toolbar
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Transitional for moving to new settings scheme.
|
||||
|
||||
To use:
|
||||
django-admin runserver --settings=settings2.dev --pythonpath="."
|
||||
@@ -1,18 +0,0 @@
|
||||
from common import *
|
||||
|
||||
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
|
||||
|
||||
CSRF_COOKIE_DOMAIN = '.mitx.mit.edu'
|
||||
LIB_URL = 'https://mitxstatic.s3.amazonaws.com/js/'
|
||||
BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/'
|
||||
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = False
|
||||
@@ -1,28 +0,0 @@
|
||||
"""
|
||||
This config file runs the simplest dev environment using sqlite, and db-based
|
||||
sessions.
|
||||
"""
|
||||
from common import *
|
||||
|
||||
CSRF_COOKIE_DOMAIN = 'localhost'
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ENV_ROOT / "db" / "mitx.db",
|
||||
}
|
||||
}
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = False
|
||||
|
||||
# This is disabling ASKBOT, but not properly overwriting INSTALLED_APPS. ???
|
||||
# It's because our ASKBOT_ENABLED here is actually shadowing the real one.
|
||||
#
|
||||
# ASKBOT_ENABLED = True
|
||||
# MITX_FEATURES['SAMPLE'] = True # Switch to this system so we get around the shadowing
|
||||
#
|
||||
# INSTALLED_APPS = installed_apps()
|
||||
@@ -1,35 +0,0 @@
|
||||
"""
|
||||
This config file tries to mimic the production environment more closely than the
|
||||
normal dev.py. It assumes you're running a local instance of MySQL 5.1 and that
|
||||
you're running memcached.
|
||||
"""
|
||||
from common import *
|
||||
|
||||
CSRF_COOKIE_DOMAIN = 'localhost'
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': 'wwc', # Or path to database file if using sqlite3.
|
||||
'USER': 'root', # Not used with sqlite3.
|
||||
'PASSWORD': '', # Not used with sqlite3.
|
||||
'HOST': '127.0.0.1', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '3306', # Set to empty string for default. Not used with sqlite3.
|
||||
}
|
||||
}
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': '127.0.0.1:11211',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = True
|
||||
@@ -1,3 +0,0 @@
|
||||
from common import *
|
||||
|
||||
GENERATE_RANDOM_USER_CREDENTIALS = True
|
||||
@@ -1,13 +0,0 @@
|
||||
from aws import *
|
||||
|
||||
# Staging specific overrides
|
||||
SITE_NAME = "staging.mitx.mit.edu"
|
||||
AWS_STORAGE_BUCKET_NAME = 'mitx_askbot_stage'
|
||||
CACHES['default']['LOCATION'] = ['***REMOVED***',
|
||||
'***REMOVED***']
|
||||
|
||||
### Secure Data Below Here ###
|
||||
SECRET_KEY = ""
|
||||
AWS_ACCESS_KEY_ID = ""
|
||||
AWS_SECRET_ACCESS_KEY = ""
|
||||
|
||||
1
static/js/mathjax
Symbolic link
1
static/js/mathjax
Symbolic link
@@ -0,0 +1 @@
|
||||
mathjax-MathJax-c9db6ac/
|
||||
61
urls.py
61
urls.py
@@ -1,6 +1,8 @@
|
||||
from django.conf import settings
|
||||
from django.conf.urls.defaults import patterns, include, url
|
||||
from django.contrib import admin
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
import django.contrib.auth.views
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
@@ -40,38 +42,43 @@ urlpatterns = ('',
|
||||
)
|
||||
|
||||
if settings.PERFSTATS:
|
||||
urlpatterns=urlpatterns + (url(r'^reprofile$','perfstats.views.end_profile'),)
|
||||
urlpatterns += (url(r'^reprofile$','perfstats.views.end_profile'),)
|
||||
|
||||
if settings.COURSEWARE_ENABLED:
|
||||
urlpatterns=urlpatterns + (url(r'^courseware/$', 'courseware.views.index', name="courseware"),
|
||||
url(r'^info$', 'util.views.info'),
|
||||
url(r'^wiki/', include('simplewiki.urls')),
|
||||
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', 'courseware.views.index', name="courseware_section"),
|
||||
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/$', 'courseware.views.index', name="courseware_chapter"),
|
||||
url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index', name="courseware_course"),
|
||||
url(r'^section/(?P<section>[^/]*)/$', 'courseware.views.render_section'),
|
||||
url(r'^modx/(?P<module>[^/]*)/(?P<id>[^/]*)/(?P<dispatch>[^/]*)$', 'courseware.views.modx_dispatch'), #reset_problem'),
|
||||
url(r'^profile$', 'courseware.views.profile'),
|
||||
url(r'^profile/(?P<student_id>[^/]*)/$', 'courseware.views.profile'),
|
||||
url(r'^change_setting$', 'student.views.change_setting'),
|
||||
url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'),
|
||||
url(r'^book/(?P<page>[^/]*)$', 'staticbook.views.index'),
|
||||
url(r'^book-shifted/(?P<page>[^/]*)$', 'staticbook.views.index_shifted'),
|
||||
url(r'^book*$', 'staticbook.views.index'),
|
||||
# url(r'^course_info/$', 'student.views.courseinfo'),
|
||||
# url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'),
|
||||
url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
|
||||
url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
|
||||
url(r'^calculate$', 'util.views.calculate'),
|
||||
)
|
||||
urlpatterns += (
|
||||
url(r'^courseware/$', 'courseware.views.index', name="courseware"),
|
||||
url(r'^info$', 'util.views.info'),
|
||||
url(r'^wiki/', include('simplewiki.urls')),
|
||||
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', 'courseware.views.index', name="courseware_section"),
|
||||
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/$', 'courseware.views.index', name="courseware_chapter"),
|
||||
url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index', name="courseware_course"),
|
||||
url(r'^section/(?P<section>[^/]*)/$', 'courseware.views.render_section'),
|
||||
url(r'^modx/(?P<module>[^/]*)/(?P<id>[^/]*)/(?P<dispatch>[^/]*)$', 'courseware.views.modx_dispatch'), #reset_problem'),
|
||||
url(r'^profile$', 'courseware.views.profile'),
|
||||
url(r'^profile/(?P<student_id>[^/]*)/$', 'courseware.views.profile'),
|
||||
url(r'^change_setting$', 'student.views.change_setting'),
|
||||
url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'),
|
||||
url(r'^book/(?P<page>[^/]*)$', 'staticbook.views.index'),
|
||||
url(r'^book-shifted/(?P<page>[^/]*)$', 'staticbook.views.index_shifted'),
|
||||
url(r'^book*$', 'staticbook.views.index'),
|
||||
# url(r'^course_info/$', 'student.views.courseinfo'),
|
||||
# url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'),
|
||||
url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
|
||||
url(r'^save_circuit/(?P<circuit>[^/]*)$', 'circuit.views.save_circuit'),
|
||||
url(r'^calculate$', 'util.views.calculate'),
|
||||
)
|
||||
|
||||
if settings.ASKBOT_ENABLED:
|
||||
urlpatterns=urlpatterns + (url(r'^%s' % settings.ASKBOT_URL, include('askbot.urls')), \
|
||||
url(r'^admin/', include(admin.site.urls)), \
|
||||
url(r'^settings/', include('askbot.deps.livesettings.urls')), \
|
||||
url(r'^followit/', include('followit.urls')), \
|
||||
# url(r'^robots.txt$', include('robots.urls')),
|
||||
urlpatterns += (url(r'^%s' % settings.ASKBOT_URL, include('askbot.urls')), \
|
||||
url(r'^admin/', include(admin.site.urls)), \
|
||||
url(r'^settings/', include('askbot.deps.livesettings.urls')), \
|
||||
url(r'^followit/', include('followit.urls')), \
|
||||
# url(r'^robots.txt$', include('robots.urls')),
|
||||
)
|
||||
|
||||
urlpatterns = patterns(*urlpatterns)
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += staticfiles_urlpatterns()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user