Commit 19a3c14a by Calen Pennington

Split out code to replace /static urls in get_html into a separate module so…

Split out code to replace /static urls in get_html into a separate module so that it can be used in CMS previews
parent 4c82f35e
......@@ -14,6 +14,7 @@ from static_replace import replace_urls
from mitxmako.shortcuts import render_to_response, render_to_string
from xmodule.modulestore.django import modulestore
from xmodule_modifiers import replace_static_urls
# ==== Public views ==================================================
......@@ -167,8 +168,21 @@ def get_sample_module(location):
"""
descriptor = modulestore().get_item(location)
instance_state, shared_state = descriptor.get_sample_state()[0]
return load_sample_module(descriptor, instance_state, shared_state)
def load_sample_module(descriptor, instance_state, shared_state):
"""
Return a sample XModule instantiated from the supplied descriptor, instance_state, and shared_state
descriptor: An XModuleDescriptor
instance_state: An instance state string
shared_state: A shared state string
"""
system = sample_module_system(descriptor)
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
module.get_html = replace_static_urls(module.get_html, module.metadata['data_dir'])
return module
......@@ -180,9 +194,8 @@ def get_module_previews(descriptor):
descriptor: An XModuleDescriptor
"""
preview_html = []
system = sample_module_system(descriptor)
for instance_state, shared_state in descriptor.get_sample_state():
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
module = load_sample_module(descriptor, instance_state, shared_state)
preview_html.append(module.get_html())
return preview_html
......
......@@ -155,6 +155,13 @@ STATICFILES_DIRS = [
# This is how you would use the textbook images locally
# ("book", ENV_ROOT / "book_images")
]
if os.path.isdir(GITHUB_REPO_ROOT):
STATICFILES_DIRS += [
# TODO (cpennington): When courses aren't loaded from github, remove this
(course_dir, GITHUB_REPO_ROOT / course_dir)
for course_dir in os.listdir(GITHUB_REPO_ROOT)
if os.path.isdir(GITHUB_REPO_ROOT / course_dir)
]
# Locale/Internationalization
TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
......
import json
from django.conf import settings
from functools import wraps
from static_replace import replace_urls
from mitxmako.shortcuts import render_to_string
def replace_static_urls(original, prefix):
"""
Updates the supplied module with a new get_html function that wraps
the old get_html function and substitutes urls of the form /static/...
with urls that are /static/<prefix>/...
"""
@wraps(original)
def get_html():
return replace_urls(original(), staticfiles_prefix=prefix)
return get_html
def grade_histogram(module_id):
''' Print out a histogram of grades on a given problem.
Part of staff member debug info.
'''
from django.db import connection
cursor = connection.cursor()
q = """SELECT courseware_studentmodule.grade,
COUNT(courseware_studentmodule.student_id)
FROM courseware_studentmodule
WHERE courseware_studentmodule.module_id=%s
GROUP BY courseware_studentmodule.grade"""
# Passing module_id this way prevents sql-injection.
cursor.execute(q, [module_id])
grades = list(cursor.fetchall())
grades.sort(key=lambda x: x[0]) # Add ORDER BY to sql query?
if len(grades) == 1 and grades[0][0] is None:
return []
return grades
def add_histogram(original, module):
"""
Updates the supplied module with a new get_html function that wraps
the output of the old get_html function with additional information
for admin users only, including a histogram of student answers and the
definition of the xmodule
"""
@wraps(original)
def get_html():
module_id = module.id
histogram = grade_histogram(module_id)
render_histogram = len(histogram) > 0
# TODO: fixme - no filename in module.xml in general (this code block for edx4edx)
# the following if block is for summer 2012 edX course development; it will change when the CMS comes online
if settings.MITX_FEATURES.get('DISPLAY_EDIT_LINK') and settings.DEBUG and module_xml.get('filename') is not None:
coursename = multicourse_settings.get_coursename_from_request(request)
github_url = multicourse_settings.get_course_github_url(coursename)
fn = module_xml.get('filename')
if module_xml.tag=='problem': fn = 'problems/' + fn # grrr
edit_link = (github_url + '/tree/master/' + fn) if github_url is not None else None
if module_xml.tag=='problem': edit_link += '.xml' # grrr
else:
edit_link = False
# Cast module.definition and module.metadata to dicts so that json can dump them
# even though they are lazily loaded
staff_context = {'definition': json.dumps(dict(module.definition), indent=4),
'metadata': json.dumps(dict(module.metadata), indent=4),
'element_id': module.location.html_id(),
'edit_link': edit_link,
'histogram': json.dumps(histogram),
'render_histogram': render_histogram,
'module_content': original()}
return render_to_string("staff_problem_info.html", staff_context)
return get_html
......@@ -5,7 +5,6 @@ from django.conf import settings
from django.http import Http404
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from functools import wraps
from django.contrib.auth.models import User
from xmodule.modulestore.django import modulestore
......@@ -14,6 +13,7 @@ from models import StudentModule, StudentModuleCache
from static_replace import replace_urls
from xmodule.exceptions import NotFoundError
from xmodule.x_module import ModuleSystem
from xmodule_modifiers import replace_static_urls, add_histogram
log = logging.getLogger("mitx.courseware")
......@@ -30,28 +30,6 @@ def make_track_function(request):
return f
def grade_histogram(module_id):
''' Print out a histogram of grades on a given problem.
Part of staff member debug info.
'''
from django.db import connection
cursor = connection.cursor()
q = """SELECT courseware_studentmodule.grade,
COUNT(courseware_studentmodule.student_id)
FROM courseware_studentmodule
WHERE courseware_studentmodule.module_id=%s
GROUP BY courseware_studentmodule.grade"""
# Passing module_id this way prevents sql-injection.
cursor.execute(q, [module_id])
grades = list(cursor.fetchall())
grades.sort(key=lambda x: x[0]) # Add ORDER BY to sql query?
if len(grades) == 1 and grades[0][0] is None:
return []
return grades
def toc_for_course(user, request, course, active_chapter, active_section):
'''
Create a table of contents from the module store
......@@ -180,11 +158,10 @@ def get_module(user, request, location, student_module_cache, position=None):
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
replace_prefix = module.metadata['data_dir']
module = replace_static_urls(module, replace_prefix)
module.get_html = replace_static_urls(module.get_html, module.metadata['data_dir'])
if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF') and user.is_staff:
module = add_histogram(module)
module.get_html = add_histogram(module.get_html)
# If StudentModule for this instance wasn't already in the database,
# and this isn't a guest user, create it.
......@@ -212,64 +189,6 @@ def get_module(user, request, location, student_module_cache, position=None):
return (module, instance_module, shared_module, descriptor.category)
def replace_static_urls(module, prefix):
"""
Updates the supplied module with a new get_html function that wraps
the old get_html function and substitutes urls of the form /static/...
with urls that are /static/<prefix>/...
"""
original_get_html = module.get_html
@wraps(original_get_html)
def get_html():
return replace_urls(original_get_html(), staticfiles_prefix=prefix)
module.get_html = get_html
return module
def add_histogram(module):
"""
Updates the supplied module with a new get_html function that wraps
the output of the old get_html function with additional information
for admin users only, including a histogram of student answers and the
definition of the xmodule
"""
original_get_html = module.get_html
@wraps(original_get_html)
def get_html():
module_id = module.id
histogram = grade_histogram(module_id)
render_histogram = len(histogram) > 0
# TODO: fixme - no filename in module.xml in general (this code block for edx4edx)
# the following if block is for summer 2012 edX course development; it will change when the CMS comes online
if settings.MITX_FEATURES.get('DISPLAY_EDIT_LINK') and settings.DEBUG and module_xml.get('filename') is not None:
coursename = multicourse_settings.get_coursename_from_request(request)
github_url = multicourse_settings.get_course_github_url(coursename)
fn = module_xml.get('filename')
if module_xml.tag == 'problem': fn = 'problems/' + fn # grrr
edit_link = (github_url + '/tree/master/' + fn) if github_url is not None else None
if module_xml.tag == 'problem': edit_link += '.xml' # grrr
else:
edit_link = False
# Cast module.definition and module.metadata to dicts so that json can dump them
# even though they are lazily loaded
staff_context = {'definition': json.dumps(dict(module.definition), indent=4),
'metadata': json.dumps(dict(module.metadata), indent=4),
'element_id': module.location.html_id(),
'edit_link': edit_link,
'histogram': json.dumps(histogram),
'render_histogram': render_histogram,
'module_content': original_get_html()}
return render_to_string("staff_problem_info.html", staff_context)
module.get_html = get_html
return module
# TODO: TEMPORARY BYPASS OF AUTH!
@csrf_exempt
def xqueue_callback(request, userid, id, dispatch):
......
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