diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py
index 31be96ad7b..6d653db6cc 100644
--- a/cms/djangoapps/contentstore/views.py
+++ b/cms/djangoapps/contentstore/views.py
@@ -215,9 +215,6 @@ def preview_module_system(request, preview_id, descriptor):
render_template=render_from_lms,
debug=True,
replace_urls=replace_urls,
- # TODO (vshnayder): All CMS users get staff view by default
- # is that what we want?
- is_staff=True,
)
diff --git a/cms/envs/common.py b/cms/envs/common.py
index 6faecafec1..1767202141 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -90,6 +90,16 @@ TEMPLATE_CONTEXT_PROCESSORS = (
################################# Jasmine ###################################
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
+
+#################### CAPA External Code Evaluation #############################
+XQUEUE_INTERFACE = {
+ 'url': 'http://localhost:8888',
+ 'django_auth': {'username': 'local',
+ 'password': 'local'},
+ 'basic_auth': None,
+}
+
+
################################# Middleware ###################################
# List of finder classes that know how to find static files in
# various locations.
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index ea1770109b..b6aa62e03d 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -38,8 +38,8 @@ from xmodule.modulestore.exceptions import ItemNotFoundError
from datetime import date
from collections import namedtuple
-from courseware.courses import (course_staff_group_name, has_staff_access_to_course,
- get_courses_by_university)
+from courseware.courses import get_courses_by_university
+from courseware.access import has_access
log = logging.getLogger("mitx.student")
Article = namedtuple('Article', 'title url author image deck publication publish_date')
@@ -166,22 +166,6 @@ def change_enrollment_view(request):
"""Delegate to change_enrollment to actually do the work."""
return HttpResponse(json.dumps(change_enrollment(request)))
-def enrollment_allowed(user, course):
- """If the course has an enrollment period, check whether we are in it.
- Also respects the DARK_LAUNCH setting"""
- now = time.gmtime()
- start = course.enrollment_start
- end = course.enrollment_end
-
- if (start is None or now > start) and (end is None or now < end):
- # in enrollment period.
- return True
-
- if settings.MITX_FEATURES['DARK_LAUNCH']:
- if has_staff_access_to_course(user, course):
- # if dark launch, staff can enroll outside enrollment window
- return True
- return False
def change_enrollment(request):
@@ -209,18 +193,7 @@ def change_enrollment(request):
.format(user.username, enrollment.course_id))
return {'success': False, 'error': 'The course requested does not exist.'}
- if settings.MITX_FEATURES.get('ACCESS_REQUIRE_STAFF_FOR_COURSE'):
- # require that user be in the staff_* group (or be an
- # overall admin) to be able to enroll eg staff_6.002x or
- # staff_6.00x
- if not has_staff_access_to_course(user, course):
- staff_group = course_staff_group_name(course)
- log.debug('user %s denied enrollment to %s ; not in %s' % (
- user, course.location.url(), staff_group))
- return {'success': False,
- 'error' : '%s membership required to access course.' % staff_group}
-
- if not enrollment_allowed(user, course):
+ if not has_access(user, course, 'enroll'):
return {'success': False,
'error': 'enrollment in {} not allowed at this time'
.format(course.display_name)}
diff --git a/common/lib/capa/capa/xqueue_interface.py b/common/lib/capa/capa/xqueue_interface.py
index 70f086120e..2847968a89 100644
--- a/common/lib/capa/capa/xqueue_interface.py
+++ b/common/lib/capa/capa/xqueue_interface.py
@@ -7,13 +7,10 @@ import logging
import requests
import time
-# TODO: Collection of parameters to be hooked into rest of edX system
-XQUEUE_LMS_AUTH = { 'username': 'LMS',
- 'password': 'PaloAltoCA' }
-XQUEUE_URL = 'http://xqueue.edx.org'
log = logging.getLogger('mitx.' + __name__)
+
def make_hashkey(seed=None):
'''
Generate a string key by hashing
@@ -58,15 +55,15 @@ def parse_xreply(xreply):
return (return_code, content)
-class XqueueInterface:
+class XQueueInterface(object):
'''
Interface to the external grading system
'''
- def __init__(self, url=XQUEUE_URL, auth=XQUEUE_LMS_AUTH):
+ def __init__(self, url, django_auth, requests_auth=None):
self.url = url
- self.auth = auth
- self.session = requests.session()
+ self.auth = django_auth
+ self.session = requests.session(auth=requests_auth)
def send_to_queue(self, header, body, file_to_upload=None):
'''
@@ -117,5 +114,3 @@ class XqueueInterface:
return (1, 'unexpected HTTP status code [%d]' % r.status_code)
return parse_xreply(r.text)
-
-qinterface = XqueueInterface()
diff --git a/common/lib/xmodule/xmodule/abtest_module.py b/common/lib/xmodule/xmodule/abtest_module.py
index 035413a402..ca00db4c9a 100644
--- a/common/lib/xmodule/xmodule/abtest_module.py
+++ b/common/lib/xmodule/xmodule/abtest_module.py
@@ -49,9 +49,9 @@ class ABTestModule(XModule):
return json.dumps({'group': self.group})
def displayable_items(self):
- return [self.system.get_module(child)
- for child
- in self.definition['data']['group_content'][self.group]]
+ return filter(None, [self.system.get_module(child)
+ for child
+ in self.definition['data']['group_content'][self.group]])
# TODO (cpennington): Use Groups should be a first class object, rather than being
diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py
index c613283683..40eec1f70f 100644
--- a/common/lib/xmodule/xmodule/course_module.py
+++ b/common/lib/xmodule/xmodule/course_module.py
@@ -1,12 +1,12 @@
from fs.errors import ResourceNotFoundError
import time
-import dateutil.parser
import logging
from xmodule.util.decorators import lazyproperty
from xmodule.graders import load_grading_policy
from xmodule.modulestore import Location
from xmodule.seq_module import SequenceDescriptor, SequenceModule
+from xmodule.timeparse import parse_time, stringify_time
log = logging.getLogger(__name__)
@@ -18,38 +18,15 @@ class CourseDescriptor(SequenceDescriptor):
super(CourseDescriptor, self).__init__(system, definition, **kwargs)
msg = None
- try:
- self.start = time.strptime(self.metadata["start"], "%Y-%m-%dT%H:%M")
- except KeyError:
- msg = "Course loaded without a start date. id = %s" % self.id
- except ValueError as e:
- msg = "Course loaded with a bad start date. %s '%s'" % (self.id, e)
-
- # Don't call the tracker from the exception handler.
- if msg is not None:
- self.start = time.gmtime(0) # The epoch
+ if self.start is None:
+ msg = "Course loaded without a valid start date. id = %s" % self.id
+ # hack it -- start in 1970
+ self.metadata['start'] = stringify_time(time.gmtime(0))
log.critical(msg)
system.error_tracker(msg)
- def try_parse_time(key):
- """
- Parse an optional metadata key: if present, must be valid.
- Return None if not present.
- """
- if key in self.metadata:
- try:
- return time.strptime(self.metadata[key], "%Y-%m-%dT%H:%M")
- except ValueError as e:
- msg = "Course %s loaded with a bad metadata key %s '%s'" % (
- self.id, self.metadata[key], e)
- log.warning(msg)
- return None
-
- self.enrollment_start = try_parse_time("enrollment_start")
- self.enrollment_end = try_parse_time("enrollment_end")
-
-
-
+ self.enrollment_start = self._try_parse_time("enrollment_start")
+ self.enrollment_end = self._try_parse_time("enrollment_end")
def has_started(self):
return time.gmtime() > self.start
@@ -154,6 +131,7 @@ class CourseDescriptor(SequenceDescriptor):
@property
def id(self):
+ """Return the course_id for this course"""
return self.location_to_id(self.location)
@property
diff --git a/common/lib/xmodule/xmodule/error_module.py b/common/lib/xmodule/xmodule/error_module.py
index 20301ee460..bdd7179a0a 100644
--- a/common/lib/xmodule/xmodule/error_module.py
+++ b/common/lib/xmodule/xmodule/error_module.py
@@ -24,16 +24,8 @@ class ErrorModule(XModule):
return self.system.render_template('module-error.html', {
'data' : self.definition['data']['contents'],
'error' : self.definition['data']['error_msg'],
- 'is_staff' : self.system.is_staff,
})
- def displayable_items(self):
- """Hide errors in the profile and table of contents for non-staff
- users.
- """
- if self.system.is_staff:
- return [self]
- return []
class ErrorDescriptor(EditingDescriptor):
"""
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
index 6b39805d1a..c00b680eba 100644
--- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
@@ -32,22 +32,37 @@ class @Problem
queueing: =>
@queued_items = @$(".xqueue")
- if @queued_items.length > 0
+ @num_queued_items = @queued_items.length
+ if @num_queued_items > 0
if window.queuePollerID # Only one poller 'thread' per Problem
window.clearTimeout(window.queuePollerID)
- window.queuePollerID = window.setTimeout(@poll, 100)
+ queuelen = @get_queuelen()
+ window.queuePollerID = window.setTimeout(@poll, queuelen*10)
+ # Retrieves the minimum queue length of all queued items
+ get_queuelen: =>
+ minlen = Infinity
+ @queued_items.each (index, qitem) ->
+ len = parseInt($.text(qitem))
+ if len < minlen
+ minlen = len
+ return minlen
+
poll: =>
$.postWithPrefix "#{@url}/problem_get", (response) =>
- @queued_items = $(response.html).find(".xqueue")
- if @queued_items.length == 0
+ # If queueing status changed, then render
+ @new_queued_items = $(response.html).find(".xqueue")
+ if @new_queued_items.length isnt @num_queued_items
@el.html(response.html)
@executeProblemScripts () =>
@setupInputTypes()
@bind()
+
+ @num_queued_items = @new_queued_items.length
+ if @num_queued_items == 0
delete window.queuePollerID
else
- # TODO: Dynamically adjust timeout interval based on @queued_items.value
+ # TODO: Some logic to dynamically adjust polling rate based on queuelen
window.queuePollerID = window.setTimeout(@poll, 1000)
render: (content) ->
@@ -141,9 +156,16 @@ class @Problem
fd = new FormData()
+ # Sanity check of file size
+ file_too_large = false
+ max_filesize = 4*1000*1000 # 4 MB
+
@inputs.each (index, element) ->
if element.type is 'file'
if element.files[0] instanceof File
+ if element.files[0].size > max_filesize
+ file_too_large = true
+ alert 'Submission aborted! Your file "' + element.files[0].name + '" is too large (max size: ' + max_filesize/(1000*1000) + ' MB)'
fd.append(element.id, element.files[0])
else
fd.append(element.id, '')
@@ -163,7 +185,8 @@ class @Problem
else
alert(response.success)
- $.ajaxWithPrefix("#{@url}/problem_check", settings)
+ if not file_too_large
+ $.ajaxWithPrefix("#{@url}/problem_check", settings)
check: =>
Logger.log 'problem_check', @answers
diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py
index 7b2bd6bc2b..f08b0f8d6e 100644
--- a/common/lib/xmodule/xmodule/tests/__init__.py
+++ b/common/lib/xmodule/xmodule/tests/__init__.py
@@ -35,7 +35,6 @@ i4xs = ModuleSystem(
filestore=fs.osfs.OSFS(os.path.dirname(os.path.realpath(__file__))+"/test_files"),
debug=True,
xqueue={'interface':None, 'callback_url':'/', 'default_queuename': 'testqueue'},
- is_staff=False,
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules")
)
@@ -336,7 +335,7 @@ class CodeResponseTest(unittest.TestCase):
self.assertFalse(test_lcp.correct_map.is_queued(answer_ids[j])) # Should be dequeued, message delivered
else:
self.assertTrue(test_lcp.correct_map.is_queued(answer_ids[j])) # Should be queued, message undelivered
-
+
def test_convert_files_to_filenames(self):
problem_file = os.path.dirname(__file__) + "/test_files/coderesponse.xml"
fp = open(problem_file)
@@ -347,7 +346,7 @@ class CodeResponseTest(unittest.TestCase):
self.assertEquals(answers_converted['1_2_1'], 'String-based answer')
self.assertEquals(answers_converted['1_3_1'], ['answer1', 'answer2', 'answer3'])
self.assertEquals(answers_converted['1_4_1'], fp.name)
-
+
class ChoiceResponseTest(unittest.TestCase):
diff --git a/common/lib/xmodule/xmodule/timeparse.py b/common/lib/xmodule/xmodule/timeparse.py
new file mode 100644
index 0000000000..117105d085
--- /dev/null
+++ b/common/lib/xmodule/xmodule/timeparse.py
@@ -0,0 +1,19 @@
+"""
+Helper functions for handling time in the format we like.
+"""
+import time
+
+TIME_FORMAT = "%Y-%m-%dT%H:%M"
+
+def parse_time(time_str):
+ """
+ Takes a time string in TIME_FORMAT, returns
+ it as a time_struct. Raises ValueError if the string is not in the right format.
+ """
+ return time.strptime(time_str, TIME_FORMAT)
+
+def stringify_time(time_struct):
+ """
+ Convert a time struct to a string
+ """
+ return time.strftime(TIME_FORMAT, time_struct)
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 071e453901..06449dc37f 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -8,8 +8,9 @@ from lxml import etree
from lxml.etree import XMLSyntaxError
from pprint import pprint
-from xmodule.modulestore import Location
from xmodule.errortracker import exc_info_to_str
+from xmodule.modulestore import Location
+from xmodule.timeparse import parse_time
log = logging.getLogger('mitx.' + __name__)
@@ -218,9 +219,11 @@ class XModule(HTMLSnippet):
Return module instances for all the children of this module.
'''
if self._loaded_children is None:
- self._loaded_children = [
- self.system.get_module(child)
- for child in self.definition.get('children', [])]
+ # get_module returns None if the current user doesn't have access
+ # to the location.
+ self._loaded_children = filter(None,
+ [self.system.get_module(child)
+ for child in self.definition.get('children', [])])
return self._loaded_children
@@ -396,6 +399,15 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
return self.metadata.get('display_name',
self.url_name.replace('_', ' '))
+ @property
+ def start(self):
+ """
+ If self.metadata contains start, return it. Else return None.
+ """
+ if 'start' not in self.metadata:
+ return None
+ return self._try_parse_time('start')
+
@property
def own_metadata(self):
"""
@@ -596,6 +608,24 @@ class XModuleDescriptor(Plugin, HTMLSnippet):
metadata=self.metadata
))
+ # ================================ Internal helpers =======================
+
+ def _try_parse_time(self, key):
+ """
+ Parse an optional metadata key containing a time: if present, complain
+ if it doesn't parse.
+ Return None if not present or invalid.
+ """
+ if key in self.metadata:
+ try:
+ return parse_time(self.metadata[key])
+ except ValueError as e:
+ msg = "Descriptor {} loaded with a bad metadata key '{}': '{}'".format(
+ self.location.url(), self.metadata[key], e)
+ log.warning(msg)
+ return None
+
+
class DescriptorSystem(object):
def __init__(self, load_item, resources_fs, error_tracker, **kwargs):
@@ -675,7 +705,6 @@ class ModuleSystem(object):
filestore=None,
debug=False,
xqueue=None,
- is_staff=False,
node_path=""):
'''
Create a closure around the system environment.
@@ -688,7 +717,8 @@ class ModuleSystem(object):
files. Update or remove.
get_module - function that takes (location) and returns a corresponding
- module instance object.
+ module instance object. If the current user does not have
+ access to that location, returns None.
render_template - a function that takes (template_file, context), and
returns rendered html.
@@ -705,9 +735,6 @@ class ModuleSystem(object):
replace_urls - TEMPORARY - A function like static_replace.replace_urls
that capa_module can use to fix up the static urls in
ajax results.
-
- is_staff - Is the user making the request a staff user?
- TODO (vshnayder): this will need to change once we have real user roles.
'''
self.ajax_url = ajax_url
self.xqueue = xqueue
@@ -718,7 +745,6 @@ class ModuleSystem(object):
self.DEBUG = self.debug = debug
self.seed = user.id if user is not None else 0
self.replace_urls = replace_urls
- self.is_staff = is_staff
self.node_path = node_path
def get(self, attr):
diff --git a/doc/development.md b/doc/development.md
index 44965cb0de..590a935405 100644
--- a/doc/development.md
+++ b/doc/development.md
@@ -65,3 +65,4 @@ To run a single nose test:
nosetests common/lib/xmodule/xmodule/tests/test_stringify.py:test_stringify
+Very handy: if you uncomment the `--pdb` argument in `NOSE_ARGS` in `lms/envs/test.py`, it will drop you into pdb on error. This lets you go up and down the stack and see what the values of the variables are. Check out http://docs.python.org/library/pdb.html
diff --git a/lms/askbot/skins/mitx/media/images/email-sharing.png b/lms/askbot/skins/mitx/media/images/email-sharing.png
new file mode 100644
index 0000000000..57fcee00e9
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/email-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/facebook-sharing.png b/lms/askbot/skins/mitx/media/images/facebook-sharing.png
new file mode 100644
index 0000000000..a82612c342
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/facebook-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/google-plus-sharing.png b/lms/askbot/skins/mitx/media/images/google-plus-sharing.png
new file mode 100644
index 0000000000..04f21d7860
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/google-plus-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/email-sharing.png b/lms/askbot/skins/mitx/media/images/lrg/email-sharing.png
new file mode 100644
index 0000000000..2e5e972c2b
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/email-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/facebook-sharing.png b/lms/askbot/skins/mitx/media/images/lrg/facebook-sharing.png
new file mode 100644
index 0000000000..782e830680
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/facebook-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/facebook.png b/lms/askbot/skins/mitx/media/images/lrg/facebook.png
new file mode 100644
index 0000000000..f024b7c8ae
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/facebook.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/google-plus-sharing.png b/lms/askbot/skins/mitx/media/images/lrg/google-plus-sharing.png
new file mode 100644
index 0000000000..ddf2abef83
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/google-plus-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/linkedin.png b/lms/askbot/skins/mitx/media/images/lrg/linkedin.png
new file mode 100644
index 0000000000..34261b05e5
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/linkedin.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/twitter-sharing.png b/lms/askbot/skins/mitx/media/images/lrg/twitter-sharing.png
new file mode 100644
index 0000000000..55b29fafc0
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/twitter-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/twitter.png b/lms/askbot/skins/mitx/media/images/lrg/twitter.png
new file mode 100644
index 0000000000..3d1856f834
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/twitter.png differ
diff --git a/lms/askbot/skins/mitx/media/images/lrg/youtube-sharing.png b/lms/askbot/skins/mitx/media/images/lrg/youtube-sharing.png
new file mode 100644
index 0000000000..111aa685a8
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/lrg/youtube-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/social/email-sharing.png b/lms/askbot/skins/mitx/media/images/social/email-sharing.png
new file mode 100644
index 0000000000..57fcee00e9
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/social/email-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/social/facebook-sharing.png b/lms/askbot/skins/mitx/media/images/social/facebook-sharing.png
new file mode 100644
index 0000000000..a82612c342
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/social/facebook-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/social/google-plus-sharing.png b/lms/askbot/skins/mitx/media/images/social/google-plus-sharing.png
new file mode 100644
index 0000000000..04f21d7860
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/social/google-plus-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/social/twitter-sharing.png b/lms/askbot/skins/mitx/media/images/social/twitter-sharing.png
new file mode 100644
index 0000000000..7d171d0fef
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/social/twitter-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/social/youtube-sharing.png b/lms/askbot/skins/mitx/media/images/social/youtube-sharing.png
new file mode 100644
index 0000000000..a26b18121b
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/social/youtube-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/twitter-sharing.png b/lms/askbot/skins/mitx/media/images/twitter-sharing.png
new file mode 100644
index 0000000000..7d171d0fef
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/twitter-sharing.png differ
diff --git a/lms/askbot/skins/mitx/media/images/youtube-sharing.png b/lms/askbot/skins/mitx/media/images/youtube-sharing.png
new file mode 100644
index 0000000000..a26b18121b
Binary files /dev/null and b/lms/askbot/skins/mitx/media/images/youtube-sharing.png differ
diff --git a/lms/askbot/skins/mitx/templates/base.html b/lms/askbot/skins/mitx/templates/base.html
index 18ca213cb7..a344009c60 100644
--- a/lms/askbot/skins/mitx/templates/base.html
+++ b/lms/askbot/skins/mitx/templates/base.html
@@ -3,7 +3,7 @@
{% spaceless %}
- {% block title %}{% endblock %} - MITX 6.002
+ {% block title %}{% endblock %}
{% include "meta/html_head_meta.html" %}
{% include "meta/html_head_stylesheets.html" %}
diff --git a/lms/askbot/skins/mitx/templates/meta/bottom_scripts.html b/lms/askbot/skins/mitx/templates/meta/bottom_scripts.html
index d9d5eb97dd..4e189f598c 100644
--- a/lms/askbot/skins/mitx/templates/meta/bottom_scripts.html
+++ b/lms/askbot/skins/mitx/templates/meta/bottom_scripts.html
@@ -33,8 +33,14 @@
+{#
+
+#}
diff --git a/lms/askbot/skins/mitx/templates/navigation.jinja.html b/lms/askbot/skins/mitx/templates/navigation.jinja.html
index 59c7148184..686ae3a724 100644
--- a/lms/askbot/skins/mitx/templates/navigation.jinja.html
+++ b/lms/askbot/skins/mitx/templates/navigation.jinja.html
@@ -1,25 +1,25 @@