common.py 24.1 KB
Newer Older
1 2 3 4
"""
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
5
MITX_FEATURES[...]. Modules that extend this one can change the feature
6 7 8
configuration in an environment specific config file and re-calculate those
values.

9
We should make a method that calls all these config methods so that you just
10
make one call at the end of your site-specific dev file to reset all the
11 12
dependent variables (like INSTALLED_APPS) for you.

13
Longer TODO:
14
1. Right now our treatment of static content in general and in particular
15 16 17
   course-specific static content is haphazard.
2. We should have a more disciplined approach to feature flagging, even if it
   just means that we stick them in a dict called MITX_FEATURES.
18
3. We need to handle configuration for multiple courses. This could be as
19 20
   multiple sites, but we do need a way to map their data assets.
"""
21 22 23 24 25

# We intentionally define lots of variables that aren't used, and
# want to import all variables from base settings files
# pylint: disable=W0401, W0614

26
import sys
27
import os
28

29 30
from path import path

31
from .discussionsettings import *
32

33 34
################################### FEATURES ###################################
COURSEWARE_ENABLED = True
35
ENABLE_JASMINE = False
36

37 38 39
GENERATE_RANDOM_USER_CREDENTIALS = False
PERFSTATS = False

Arjun Singh committed
40 41 42 43
DISCUSSION_SETTINGS = {
    'MAX_COMMENT_DEPTH': 2,
}

44

45 46
# Features
MITX_FEATURES = {
Calen Pennington committed
47 48 49 50 51
    'SAMPLE': False,
    'USE_DJANGO_PIPELINE': True,
    'DISPLAY_HISTOGRAMS_TO_STAFF': True,
    'REROUTE_ACTIVATION_EMAIL': False,		# nonempty string = address for all activation emails
    'DEBUG_LEVEL': 0,				# 0 = lowest level, least verbose, 255 = max level, most verbose
52 53 54

    ## DO NOT SET TO True IN THIS FILE
    ## Doing so will cause all courses to be released on production
55
    'DISABLE_START_DATES': False,  # When True, all courses will be active, regardless of start date
56

57 58 59
    # When True, will only publicly list courses by the subdomain. Expects you
    # to define COURSE_LISTINGS, a dictionary mapping subdomains to lists of
    # course_ids (see dev_int.py for an example)
Calen Pennington committed
60
    'SUBDOMAIN_COURSE_LISTINGS': False,
61

62 63 64 65 66
    # When True, will override certain branding with university specific values
    # Expects a SUBDOMAIN_BRANDING dictionary that maps the subdomain to the
    # university to use for branding purposes
    'SUBDOMAIN_BRANDING': False,

Calen Pennington committed
67
    'FORCE_UNIVERSITY_DOMAIN': False,  	# set this to the university domain to use, as an override to HTTP_HOST
68 69
                                        # set to None to do no university selection

Calen Pennington committed
70
    'ENABLE_TEXTBOOK': True,
71
    'ENABLE_DISCUSSION_SERVICE': True,
72

Calen Pennington committed
73
    'ENABLE_PSYCHOMETRICS': False,  	# real-time psychometrics (eg item response theory analysis in instructor dashboard)
74

75
    'ENABLE_DJANGO_ADMIN_SITE': False,  # set true to enable django's admin site, even on prod (e.g. for course ops)
76 77
    'ENABLE_SQL_TRACKING_LOGS': False,
    'ENABLE_LMS_MIGRATION': False,
78
    'ENABLE_MANUAL_GIT_RELOAD': False,
79

80 81
    'ENABLE_MASQUERADE': True,  # allow course staff to change to student view of courseware

82
    'DISABLE_LOGIN_BUTTON': False,  # used in systems where login is automatic, eg MIT SSL
83

Calen Pennington committed
84
    'STUB_VIDEO_FOR_TESTING': False,   # do not display video when running automated acceptance tests
85

86 87 88
    # extrernal access methods
    'ACCESS_REQUIRE_STAFF_FOR_COURSE': False,
    'AUTH_USE_OPENID': False,
Calen Pennington committed
89
    'AUTH_USE_MIT_CERTIFICATES': False,
90
    'AUTH_USE_OPENID_PROVIDER': False,
91 92

    # analytics experiments
93
    'ENABLE_INSTRUCTOR_ANALYTICS': False,
94

95 96
    # Flip to True when the YouTube iframe API breaks (again)
    'USE_YOUTUBE_OBJECT_API': False,
97

98
    # Give a UI to show a student's submission history in a problem by the
99
    # Staff Debug tool.
100 101
    'ENABLE_STUDENT_HISTORY_VIEW': True,

102
    # Enables the student notes API and UI.
103 104
    'ENABLE_STUDENT_NOTES': True,

105 106
    # Provide a UI to allow users to submit feedback from the LMS
    'ENABLE_FEEDBACK_SUBMISSION': False,
Ned Batchelder committed
107

108 109 110
    # Turn on a page that lets staff enter Python code to be run in the
    # sandbox, for testing whether it's enabled properly.
    'ENABLE_DEBUG_RUN_PYTHON': False,
111 112 113

    # Enable URL that shows information about the status of variuous services
    'ENABLE_SERVICE_STATUS': False,
114 115 116

    # Toggle to indicate use of a custom theme
    'USE_CUSTOM_THEME': False
117 118
}

119 120 121 122 123 124
# 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

125
# Used with XQueue
Calen Pennington committed
126
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5   # seconds
127

128

129
############################# SET PATH INFORMATION #############################
130 131 132 133
PROJECT_ROOT = path(__file__).abspath().dirname().dirname()  # /mitx/lms
REPO_ROOT = PROJECT_ROOT.dirname()
COMMON_ROOT = REPO_ROOT / "common"
ENV_ROOT = REPO_ROOT.dirname()  # virtualenv dir /mitx is in
134 135 136 137
COURSES_ROOT = ENV_ROOT / "data"

DATA_DIR = COURSES_ROOT

138
sys.path.append(REPO_ROOT)
139 140
sys.path.append(PROJECT_ROOT / 'djangoapps')
sys.path.append(PROJECT_ROOT / 'lib')
141
sys.path.append(COMMON_ROOT / 'djangoapps')
142
sys.path.append(COMMON_ROOT / 'lib')
143

144
# For Node.js
145

146
system_node_path = os.environ.get("NODE_PATH", REPO_ROOT / 'node_modules')
147

148
node_paths = [COMMON_ROOT / "static/js/vendor",
149 150
              COMMON_ROOT / "static/coffee/src",
              system_node_path
151
              ]
152
NODE_PATH = ':'.join(node_paths)
153

154

155
# Where to look for a status message
156
STATUS_MESSAGE_PATH = ENV_ROOT / "status_message.json"
157

158
############################ OpenID Provider  ##################################
159
OPENID_PROVIDER_TRUSTED_ROOTS = ['cs50.net', '*.cs50.net']
160

161
################################## MITXWEB #####################################
162 163
# This is where we stick our compiled template files. Most of the app uses Mako
# templates
164 165
from tempdir import mkdtemp_clean
MAKO_MODULE_DIR = mkdtemp_clean('mako')
Piotr Mitros committed
166
MAKO_TEMPLATES = {}
167
MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates',
168
                          COMMON_ROOT / 'templates',
169
                          COMMON_ROOT / 'lib' / 'capa' / 'capa' / 'templates',
170
                          COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / 'templates']
Piotr Mitros committed
171

172
# This is where Django Template lookup is defined. There are a few of these
173
# still left lying around.
174
TEMPLATE_DIRS = [
175
    PROJECT_ROOT / "templates",
176 177 178
    COMMON_ROOT / 'templates',
    COMMON_ROOT / 'lib' / 'capa' / 'capa' / 'templates',
    COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / 'templates',
179
]
180 181 182

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request',
183
    'django.core.context_processors.static',
184
    'django.contrib.messages.context_processors.messages',
185
    #'django.core.context_processors.i18n',
Calen Pennington committed
186 187
    'django.contrib.auth.context_processors.auth',   # this is required for admin
    'django.core.context_processors.csrf',   # necessary for csrf protection
188

189 190 191 192 193
    # Added for django-wiki
    'django.core.context_processors.media',
    'django.core.context_processors.tz',
    'django.contrib.messages.context_processors.messages',
    'sekizai.context_processors.sekizai',
194
    'course_wiki.course_nav.context_processor',
195 196 197

    # Hack to get required link URLs to password reset templates
    'mitxmako.shortcuts.marketing_link_context_processor',
198 199
)

Calen Pennington committed
200
STUDENT_FILEUPLOAD_MAX_SIZE = 4 * 1000 * 1000   # 4 MB
201
MAX_FILEUPLOADS_PER_INPUT = 20
202

203 204
# FIXME:
# We should have separate S3 staged URLs in case we need to make changes to
205
# these assets and test them.
206
LIB_URL = '/static/js/'
207 208 209

# Dev machines shouldn't need the book
# BOOK_URL = '/static/book/'
Calen Pennington committed
210
BOOK_URL = 'https://mitxstatic.s3.amazonaws.com/book_images/'   # For AWS deploys
211
# RSS_URL = r'lms/templates/feed.rss'
212
# PRESS_URL = r''
213
RSS_TIMEOUT = 600
214

215 216 217 218
# Configuration option for when we want to grab server error pages
STATIC_GRAB = False
DEV_CONTENT = True

219
# FIXME: Should we be doing this truncation?
220
TRACK_MAX_EVENT = 10000
221
DEBUG_TRACK_LOG = False
222

223 224
MITX_ROOT_URL = ''

225 226 227
LOGIN_REDIRECT_URL = MITX_ROOT_URL + '/accounts/login'
LOGIN_URL = MITX_ROOT_URL + '/accounts/login'

228 229 230 231
COURSE_NAME = "6.002_Spring_2012"
COURSE_NUMBER = "6.002x"
COURSE_TITLE = "Circuits and Electronics"

232
### Dark code. Should be enabled in local settings for devel.
233 234 235

ENABLE_MULTICOURSE = False     # set to False to disable multicourse display (see lib.util.views.mitxhome)

236 237
WIKI_ENABLED = False

238 239
###

240
COURSE_DEFAULT = '6.002x_Fall_2012'
241 242
COURSE_SETTINGS =  {'6.002x_Fall_2012': {'number': '6.002x',
                                          'title': 'Circuits and Electronics',
243
                                          'xmlpath': '6002x/',
244
                                          'location': 'i4x://edx/6002xs12/course/6.002x_Fall_2012',
245 246 247
                                          }
                    }

Victor Shnayder committed
248 249 250
# IP addresses that are allowed to reload the course, etc.
# TODO (vshnayder): Will probably need to change as we get real access control in.
LMS_MIGRATION_ALLOWED_IPS = []
251

252 253 254 255 256
######################## subdomain specific settings ###########################
COURSE_LISTINGS = {}
SUBDOMAIN_BRANDING = {}


257
############################### XModule Store ##################################
258
MODULESTORE = {
259
    'default': {
260
        'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
261 262 263 264 265 266
        'OPTIONS': {
            'data_dir': DATA_DIR,
            'default_class': 'xmodule.hidden_module.HiddenDescriptor',
        }
    }
}
267
CONTENTSTORE = None
268

269 270 271 272 273 274 275
#################### Python sandbox ############################################

CODE_JAIL = {
    # Path to a sandboxed Python executable.  None means don't bother.
    'python_bin': None,
    # User to run as in the sandbox.
    'user': 'sandbox',
276 277 278 279 280 281

    # Configurable limits.
    'limits': {
        # How many CPU seconds can jailed code use?
        'CPU': 1,
    },
282 283
}

284 285 286 287 288 289 290 291 292
# Some courses are allowed to run unsafe code. This is a list of regexes, one
# of them must match the course id for that course to run unsafe code.
#
# For example:
#
#   COURSES_WITH_UNSAFE_CODE = [
#       r"Harvard/XY123.1/.*"
#   ]
COURSES_WITH_UNSAFE_CODE = []
293

294 295 296
############################ SIGNAL HANDLERS ################################
# This is imported to register the exception signal handling that logs exceptions
import monitoring.exceptions  # noqa
297

298 299 300 301
############################### DJANGO BUILT-INS ###############################
# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here
DEBUG = False
TEMPLATE_DEBUG = False
302

303 304
# Site info
SITE_ID = 1
305
SITE_NAME = "edx.org"
306
HTTPS = 'on'
307
ROOT_URLCONF = 'lms.urls'
308
IGNORABLE_404_ENDS = ('favicon.ico')
309

310
# Email
311
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
312 313
DEFAULT_FROM_EMAIL = 'registration@edx.org'
DEFAULT_FEEDBACK_EMAIL = 'feedback@edx.org'
314
SERVER_EMAIL = 'devops@edx.org'
315
ADMINS = (
316
    ('edX Admins', 'admin@edx.org'),
317 318 319
)
MANAGERS = ADMINS

320
# Static content
321 322
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
323
STATIC_ROOT = ENV_ROOT / "staticfiles"
324

325
STATICFILES_DIRS = [
326
    COMMON_ROOT / "static",
327
    PROJECT_ROOT / "static",
328
]
329

330
# Locale/Internationalization
Calen Pennington committed
331 332
TIME_ZONE = 'America/New_York'   # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
LANGUAGE_CODE = 'en'   # http://www.i18nguy.com/unicode/language-identifiers.html
333 334
USE_I18N = True
USE_L10N = True
335

336 337 338
# Messages
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'

339 340 341 342 343 344
#################################### GITHUB #######################################
# gitreload is used in LMS-workflow to pull content from github
# gitreload requests are only allowed from these IP addresses, which are
# the advertised public IPs of the github WebHook servers.
# These are listed, eg at https://github.com/MITx/mitx/admin/hooks

345
ALLOWED_GITRELOAD_IPS = ['207.97.227.253', '50.57.128.197', '108.171.174.178']
346

347
#################################### AWS #######################################
348
# S3BotoStorage insists on a timeout for uploaded assets. We should make it
349
# permanent instead, but rather than trying to figure out exactly where that
350
# setting is, I'm just bumping the expiration time to something absurd (100
351 352
# years). This is only used if DEFAULT_FILE_STORAGE is overriden to use S3
# in the global settings.py
Calen Pennington committed
353
AWS_QUERYSTRING_EXPIRE = 10 * 365 * 24 * 60 * 60   # 10 years
354

355
################################# SIMPLEWIKI ###################################
356 357
SIMPLE_WIKI_REQUIRE_LOGIN_EDIT = True
SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False
358

359 360
################################# WIKI ###################################
WIKI_ACCOUNT_HANDLING = False
361
WIKI_EDITOR = 'course_wiki.editors.CodeMirror'
Calen Pennington committed
362 363
WIKI_SHOW_MAX_CHILDREN = 0   # We don't use the little menu that shows children of an article in the breadcrumb
WIKI_ANONYMOUS = False   # Don't allow anonymous access until the styling is figured out
364 365 366 367
WIKI_CAN_CHANGE_PERMISSIONS = lambda article, user: user.is_staff or user.is_superuser
WIKI_CAN_ASSIGN = lambda article, user: user.is_staff or user.is_superuser

WIKI_USE_BOOTSTRAP_SELECT_WIDGET = False
368
WIKI_LINK_LIVE_LOOKUPS = False
369
WIKI_LINK_DEFAULT_LEVEL = 2
370

371 372 373
################################# Pearson TestCenter config  ################

PEARSONVUE_SIGNINPAGE_URL = "https://www1.pearsonvue.com/testtaker/signin/SignInPage/EDX"
374
# TESTCENTER_ACCOMMODATION_REQUEST_EMAIL = "exam-help@edx.org"
375

376 377 378 379 380 381 382 383
##### Feedback submission mechanism #####
FEEDBACK_SUBMISSION_EMAIL = None

##### Zendesk #####
ZENDESK_URL = None
ZENDESK_USER = None
ZENDESK_API_KEY = None

384
################################# open ended grading config  #####################
385 386 387

#By setting up the default settings with an incorrect user name and password,
# will get an error when attempting to connect
388
OPEN_ENDED_GRADING_INTERFACE = {
389 390 391
    'url': 'http://sandbox-grader-001.m.edx.org/peer_grading',
    'username': 'incorrect_user',
    'password': 'incorrect_pass',
392 393 394
    'staff_grading' : 'staff_grading',
    'peer_grading' : 'peer_grading',
    'grading_controller' : 'grading_controller'
395 396
    }

397
# Used for testing, debugging peer grading
398
MOCK_PEER_GRADING = False
399

400 401 402
# Used for testing, debugging staff grading
MOCK_STAFF_GRADING = False

403
################################# Jasmine ###################################
404
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
405

406 407 408 409
################################# Middleware ###################################
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
410 411
    'staticfiles.finders.FileSystemFinder',
    'staticfiles.finders.AppDirectoriesFinder',
412 413 414 415
)

# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
416 417
    'mitxmako.makoloader.MakoFilesystemLoader',
    'mitxmako.makoloader.MakoAppDirectoriesLoader',
418

419 420
    # 'django.template.loaders.filesystem.Loader',
    # 'django.template.loaders.app_directories.Loader',
421

422 423 424
)

MIDDLEWARE_CLASSES = (
425
    'contentserver.middleware.StaticContentServer',
426
    'request_cache.middleware.RequestCache',
Rocky Duan committed
427
    'django_comment_client.middleware.AjaxExceptionMiddleware',
428 429 430
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
431 432

    # Instead of AuthenticationMiddleware, we use a cached backed version
433 434
    #'django.contrib.auth.middleware.AuthenticationMiddleware',
    'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware',
435

436 437 438
    'django.contrib.messages.middleware.MessageMiddleware',
    'track.middleware.TrackMiddleware',
    'mitxmako.middleware.MakoMiddleware',
439

440
    'course_wiki.course_nav.Middleware',
441

442
    'django.middleware.transaction.TransactionMiddleware',
443
    # 'debug_toolbar.middleware.DebugToolbarMiddleware',
444 445

    'django_comment_client.utils.ViewNameMiddleware',
446
    'codejail.django_integration.ConfigureCodeJailMiddleware',
447 448
)

449 450 451 452
############################### Pipeline #######################################

STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'

453
from rooted_paths import rooted_glob
454

455 456
courseware_js = (
    [
457
        'coffee/src/' + pth + '.js'
458 459
        for pth in ['courseware', 'histogram', 'navigation', 'time']
    ] +
460
    sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/modules/**/*.js'))
461
)
462

463 464
# 'js/vendor/RequireJS.js' - Require JS wrapper.
# See https://edx-wiki.atlassian.net/wiki/display/LMS/Integration+of+Require+JS+into+the+system
465
main_vendor_js = [
466
  'js/vendor/RequireJS.js',
467
  'js/vendor/json2.js',
468 469 470 471
  'js/vendor/jquery.min.js',
  'js/vendor/jquery-ui.min.js',
  'js/vendor/jquery.cookie.js',
  'js/vendor/jquery.qtip.min.js',
472
  'js/vendor/swfobject/swfobject.js',
473
  'js/vendor/jquery.ba-bbq.min.js',
474 475 476
  'js/vendor/annotator.min.js',
  'js/vendor/annotator.store.min.js',
  'js/vendor/annotator.tags.min.js'
477
]
478

479 480 481
discussion_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/discussion/**/*.js'))
staff_grading_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/staff_grading/**/*.js'))
open_ended_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/open_ended/**/*.js'))
Arthur Barrett committed
482
notes_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/notes/**/*.coffee'))
483

484 485
PIPELINE_CSS = {
    'application': {
486
        'source_filenames': ['sass/application.css'],
487
        'output_filename': 'css/lms-application.css',
488
    },
Kyle Fiedler committed
489
    'course': {
490 491 492 493 494
        'source_filenames': [
            'js/vendor/CodeMirror/codemirror.css',
            'css/vendor/jquery.treeview.css',
            'css/vendor/ui-lightness/jquery-ui-1.8.22.custom.css',
            'css/vendor/jquery.qtip.min.css',
495
            'css/vendor/annotator.min.css',
496 497
            'sass/course.css',
            'xmodule/modules.css',
498 499 500
        ],
        'output_filename': 'css/lms-course.css',
    },
501
    'ie-fixes': {
502
        'source_filenames': ['sass/ie.css'],
503
        'output_filename': 'css/lms-ie.css',
504
    },
505
}
506

507 508 509

# test_order: Determines the position of this chunk of javascript on
# the jasmine test page
510 511
PIPELINE_JS = {
    'application': {
512

513
        # Application will contain all paths not in courseware_only_js
514
        'source_filenames': sorted(
515 516
            set(rooted_glob(COMMON_ROOT / 'static', 'coffee/src/**/*.js') +
                rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/**/*.js')) -
Arthur Barrett committed
517
            set(courseware_js + discussion_js + staff_grading_js + open_ended_js + notes_js)
518
        ) + [
519 520 521 522
            'js/form.ext.js',
            'js/my_courses_dropdown.js',
            'js/toggle_login_modal.js',
            'js/sticky_filter.js',
523
            'js/query-params.js',
524
        ],
525 526 527
        'output_filename': 'js/lms-application.js',

        'test_order': 1,
528
    },
529
    'courseware': {
530
        'source_filenames': courseware_js,
531 532
        'output_filename': 'js/lms-courseware.js',
        'test_order': 2,
533
    },
534 535
    'main_vendor': {
        'source_filenames': main_vendor_js,
536
        'output_filename': 'js/lms-main_vendor.js',
537
        'test_order': 0,
538
    },
539
    'module-js': {
540
        'source_filenames': rooted_glob(COMMON_ROOT / 'static', 'xmodule/modules/js/*.js'),
541
        'output_filename': 'js/lms-modules.js',
542
        'test_order': 3,
543
    },
544 545
    'discussion': {
        'source_filenames': discussion_js,
546 547
        'output_filename': 'js/discussion.js',
        'test_order': 4,
548
    },
Calen Pennington committed
549
    'staff_grading': {
550
        'source_filenames': staff_grading_js,
551 552
        'output_filename': 'js/staff_grading.js',
        'test_order': 5,
553
    },
Calen Pennington committed
554
    'open_ended': {
555
        'source_filenames': open_ended_js,
556 557
        'output_filename': 'js/open_ended.js',
        'test_order': 6,
Arthur Barrett committed
558 559 560
    },
    'notes': {
        'source_filenames': notes_js,
561 562
        'output_filename': 'js/notes.js',
        'test_order': 7
Arthur Barrett committed
563
    },
564 565
}

566 567
PIPELINE_DISABLE_WRAPPER = True

568 569 570
# Compile all coffee files in course data directories if they are out of date.
# TODO: Remove this once we move data into Mongo. This is only temporary while
# course data directories are still in use.
571 572 573 574 575 576 577 578 579 580 581 582 583
if os.path.isdir(DATA_DIR):
    for course_dir in os.listdir(DATA_DIR):
        js_dir = DATA_DIR / course_dir / "js"
        if not os.path.isdir(js_dir):
            continue
        for filename in os.listdir(js_dir):
            if filename.endswith('coffee'):
                new_filename = os.path.splitext(filename)[0] + ".js"
                if os.path.exists(js_dir / new_filename):
                    coffee_timestamp = os.stat(js_dir / filename).st_mtime
                    js_timestamp     = os.stat(js_dir / new_filename).st_mtime
                    if coffee_timestamp <= js_timestamp:
                        continue
584
                os.system("rm %s" % (js_dir / new_filename))
585 586
                os.system("coffee -c %s" % (js_dir / filename))

587 588

PIPELINE_CSS_COMPRESSOR = None
589
PIPELINE_JS_COMPRESSOR = None
590

591
STATICFILES_IGNORE_PATTERNS = (
592 593
    "sass/*",
    "coffee/*",
594 595
)

596
PIPELINE_YUI_BINARY = 'yui-compressor'
597

598 599 600
# Setting that will only affect the MITx version of django-pipeline until our changes are merged upstream
PIPELINE_COMPILE_INPLACE = True

601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
################################# CELERY ######################################

# Message configuration

CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

CELERY_MESSAGE_COMPRESSION = 'gzip'

# Results configuration

CELERY_IGNORE_RESULT = False
CELERY_STORE_ERRORS_EVEN_IF_IGNORED = True

# Events configuration

CELERY_TRACK_STARTED = True

CELERY_SEND_EVENTS = True
CELERY_SEND_TASK_SENT_EVENT = True

# Exchange configuration

CELERY_DEFAULT_EXCHANGE = 'edx.core'
CELERY_DEFAULT_EXCHANGE_TYPE = 'direct'

# Queues configuration

HIGH_PRIORITY_QUEUE = 'edx.core.high'
DEFAULT_PRIORITY_QUEUE = 'edx.core.default'
LOW_PRIORITY_QUEUE = 'edx.core.low'

CELERY_QUEUE_HA_POLICY = 'all'

CELERY_CREATE_MISSING_QUEUES = True

CELERY_DEFAULT_QUEUE = DEFAULT_PRIORITY_QUEUE
CELERY_DEFAULT_ROUTING_KEY = DEFAULT_PRIORITY_QUEUE

CELERY_QUEUES = {
    HIGH_PRIORITY_QUEUE: {},
    LOW_PRIORITY_QUEUE: {},
    DEFAULT_PRIORITY_QUEUE: {}
}

################################### APPS ######################################
647 648 649 650 651 652 653 654
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',
655
    'djcelery',
656 657
    'south',

658 659 660
    # Monitor the status of services
    'service_status',

661 662 663
    # For asset pipelining
    'pipeline',
    'staticfiles',
664
    'static_replace',
665

666 667 668 669 670 671 672 673 674 675
    # Our courseware
    'circuit',
    'courseware',
    'perfstats',
    'student',
    'static_template_view',
    'staticbook',
    'simplewiki',
    'track',
    'util',
676
    'certificates',
677
    'instructor',
678
    'open_ended_grading',
679
    'psychometrics',
680
    'licenses',
681
    'course_groups',
682

683
    #For the wiki
Calen Pennington committed
684
    'wiki',   # The new django-wiki from benjaoming
685
    'django_notify',
Calen Pennington committed
686
    'course_wiki',   # Our customizations
687 688
    'mptt',
    'sekizai',
689
    #'wiki.plugins.attachments',
690
    'wiki.plugins.links',
691
    'wiki.plugins.notifications',
692
    'course_wiki.plugins.markdownedx',
693

Victor Shnayder committed
694 695 696
    # foldit integration
    'foldit',

697
    # For testing
698
    'django.contrib.admin',   # only used in DEBUG mode
699
    'debug',
700

701
    # Discussion forums
702
    'django_comment_client',
703
    'django_comment_common',
704
    'notes',
705
)
706

707 708
######################### MARKETING SITE ###############################
EDXMKTG_COOKIE_NAME = 'edxloggedin'
709
MKTG_URLS = {}
710 711 712 713 714 715
MKTG_URL_LINK_MAP = {
    'ABOUT': 'about_edx',
    'CONTACT': 'contact',
    'FAQ': 'help_edx',
    'COURSES': 'courses',
    'ROOT': 'root',
716 717 718
    'TOS': 'tos',
    'HONOR': 'honor',
    'PRIVACY': 'privacy_edx',
719
}
720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747

############################### THEME ################################
def enable_theme(theme_name):
    """
    Enable the settings for a custom theme, whose files should be stored
    in ENV_ROOT/themes/THEME_NAME (e.g., edx_all/themes/stanford).

    The THEME_NAME setting should be configured separately since it can't
    be set here (this function closes too early). An idiom for doing this
    is:

    THEME_NAME = "stanford"
    enable_theme(THEME_NAME)
    """
    MITX_FEATURES['USE_CUSTOM_THEME'] = True

    # Calculate the location of the theme's files
    theme_root = ENV_ROOT / "themes" / theme_name

    # Include the theme's templates in the template search paths
    TEMPLATE_DIRS.append(theme_root / 'templates')
    MAKO_TEMPLATES['main'].append(theme_root / 'templates')

    # Namespace the theme's static files to 'themes/<theme_name>' to
    # avoid collisions with default edX static files
    STATICFILES_DIRS.append((u'themes/%s' % theme_name,
                             theme_root / 'static'))