Commit 0c69ec2f by Victor Shnayder

Add support for per-course site status.

Now looks for a status_message.json file, looks for 'global' and ${course.id} keys. Return any global message and any course-specific message, joined by <br>.

fab files need to be updated to use this new format (new filename, possibly also help manage per-course messages, or at least test for valid json)
parent c72d1a38
...@@ -3,27 +3,41 @@ A tiny app that checks for a status message. ...@@ -3,27 +3,41 @@ A tiny app that checks for a status message.
""" """
from django.conf import settings from django.conf import settings
import json
import logging import logging
import os import os
import sys import sys
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def get_site_status_msg(): def get_site_status_msg(course):
""" """
Look for a file settings.STATUS_MESSAGE_PATH. If found, return the Look for a file settings.STATUS_MESSAGE_PATH. If found, read it,
contents. Otherwise, return None. parse as json, and do the following:
* if there is a key 'global', include that in the result list.
* if course is not None, and there is a key for course.id, add that to the result list.
* return "<br/>".join(result)
Otherwise, return None.
If something goes wrong, returns None. ("is there a status msg?" logic is If something goes wrong, returns None. ("is there a status msg?" logic is
not allowed to break the entire site). not allowed to break the entire site).
""" """
try: try:
content = None
if os.path.isfile(settings.STATUS_MESSAGE_PATH): if os.path.isfile(settings.STATUS_MESSAGE_PATH):
with open(settings.STATUS_MESSAGE_PATH) as f: with open(settings.STATUS_MESSAGE_PATH) as f:
content = f.read() content = f.read()
else:
return None
status_dict = json.loads(content)
msg = status_dict.get('global', None)
if course and course.id in status_dict:
msg = msg + "<br>" if msg else ''
msg += status_dict[course.id]
return content return msg
except: except:
log.exception("Error while getting a status message.") log.exception("Error while getting a status message.")
return None return None
from django.conf import settings
from django.test import TestCase
from tempfile import NamedTemporaryFile
import os
from override_settings import override_settings
from status import get_site_status_msg
import xmodule.modulestore.django
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import Location
from xmodule.modulestore.xml_importer import import_from_xml
class TestStatus(TestCase):
"""Test that the get_site_status_msg function does the right thing"""
no_file = None
invalid_json = """{
"global" : "Hello, Globe",
}"""
global_only = """{
"global" : "Hello, Globe"
}"""
toy_only = """{
"edX/toy/2012_Fall" : "A toy story"
}"""
global_and_toy = """{
"global" : "Hello, Globe",
"edX/toy/2012_Fall" : "A toy story"
}"""
# json to use, expected results for course=None (e.g. homepage),
# for toy course, for full course. Note that get_site_status_msg
# is supposed to return global message even if course=None. The
# template just happens to not display it outside the courseware
# at the moment...
checks = [
(no_file, None, None, None),
(invalid_json, None, None, None),
(global_only, "Hello, Globe", "Hello, Globe", "Hello, Globe"),
(toy_only, None, "A toy story", None),
(global_and_toy, "Hello, Globe", "Hello, Globe<br>A toy story", "Hello, Globe"),
]
def setUp(self):
xmodule.modulestore.django._MODULESTORES = {}
courses = modulestore().get_courses()
def find_course(course_id):
"""Assumes the course is present"""
return [c for c in courses if c.id==course_id][0]
self.full = find_course("edX/full/6.002_Spring_2012")
self.toy = find_course("edX/toy/2012_Fall")
def create_status_file(self, contents):
"""
Write contents to settings.STATUS_MESSAGE_PATH.
"""
with open(settings.STATUS_MESSAGE_PATH, 'w') as f:
f.write(contents)
def remove_status_file(self):
"""Delete the status file if it exists"""
if os.path.exists(settings.STATUS_MESSAGE_PATH):
os.remove(settings.STATUS_MESSAGE_PATH)
def tearDown(self):
self.remove_status_file()
def test_get_site_status_msg(self):
"""run the tests"""
for (json_str, exp_none, exp_toy, exp_full) in self.checks:
self.remove_status_file()
if json_str:
self.create_status_file(json_str)
print "checking results for {0}".format(json_str)
print "course=None:"
self.assertEqual(get_site_status_msg(None), exp_none)
print "course=toy:"
self.assertEqual(get_site_status_msg(self.toy), exp_toy)
print "course=full:"
self.assertEqual(get_site_status_msg(self.full), exp_full)
...@@ -129,7 +129,7 @@ NODE_PATH = ':'.join(node_paths) ...@@ -129,7 +129,7 @@ NODE_PATH = ':'.join(node_paths)
# Where to look for a status message # Where to look for a status message
STATUS_MESSAGE_PATH = ENV_ROOT / "status_message.html" STATUS_MESSAGE_PATH = ENV_ROOT / "status_message.json"
############################ OpenID Provider ################################## ############################ OpenID Provider ##################################
OPENID_PROVIDER_TRUSTED_ROOTS = ['cs50.net', '*.cs50.net'] OPENID_PROVIDER_TRUSTED_ROOTS = ['cs50.net', '*.cs50.net']
......
...@@ -40,6 +40,8 @@ TEST_ROOT = path("test_root") ...@@ -40,6 +40,8 @@ TEST_ROOT = path("test_root")
# Want static files in the same dir for running on jenkins. # Want static files in the same dir for running on jenkins.
STATIC_ROOT = TEST_ROOT / "staticfiles" STATIC_ROOT = TEST_ROOT / "staticfiles"
STATUS_MESSAGE_PATH = TEST_ROOT / "status_message.json"
COURSES_ROOT = TEST_ROOT / "data" COURSES_ROOT = TEST_ROOT / "data"
DATA_DIR = COURSES_ROOT DATA_DIR = COURSES_ROOT
...@@ -77,6 +79,19 @@ STATICFILES_DIRS += [ ...@@ -77,6 +79,19 @@ STATICFILES_DIRS += [
if os.path.isdir(COMMON_TEST_DATA_ROOT / course_dir) if os.path.isdir(COMMON_TEST_DATA_ROOT / course_dir)
] ]
# point tests at the test courses by default
MODULESTORE = {
'default': {
'ENGINE': 'xmodule.modulestore.xml.XMLModuleStore',
'OPTIONS': {
'data_dir': COMMON_TEST_DATA_ROOT,
'default_class': 'xmodule.hidden_module.HiddenDescriptor',
}
}
}
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
......
...@@ -14,7 +14,12 @@ from status.status import get_site_status_msg ...@@ -14,7 +14,12 @@ from status.status import get_site_status_msg
<%block cached="False"> <%block cached="False">
<% <%
site_status_msg = get_site_status_msg() try:
c = course
except:
# can't figure out a better way to get at a possibly-defined course var
c = None
site_status_msg = get_site_status_msg(c)
%> %>
% if site_status_msg: % if site_status_msg:
<div class="site-status"> <div class="site-status">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment