Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
ed3f0817
Commit
ed3f0817
authored
May 21, 2012
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into asset-pipeline
parents
fe4f7bb2
4fe22be5
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
325 additions
and
52 deletions
+325
-52
djangoapps/courseware/capa/capa_problem.py
+14
-5
djangoapps/courseware/capa/inputtypes.py
+121
-2
djangoapps/courseware/capa/responsetypes.py
+13
-13
djangoapps/courseware/capa/util.py
+1
-0
djangoapps/courseware/module_render.py
+6
-4
djangoapps/courseware/views.py
+13
-16
djangoapps/multicourse/multicourse_settings.py
+5
-0
djangoapps/multicourse/views.py
+24
-1
lib/util/views.py
+0
-6
templates/mathjax_include.html
+89
-0
templates/mitxhome.html
+4
-4
templates/optioninput.html
+25
-0
templates/problem.html
+9
-0
urls.py
+1
-1
No files found.
djangoapps/courseware/capa/capa_problem.py
View file @
ed3f0817
...
@@ -25,6 +25,7 @@ from mako.template import Template
...
@@ -25,6 +25,7 @@ from mako.template import Template
from
util
import
contextualize_text
from
util
import
contextualize_text
import
inputtypes
import
inputtypes
from
responsetypes
import
NumericalResponse
,
FormulaResponse
,
CustomResponse
,
SchematicResponse
,
MultipleChoiceResponse
,
StudentInputError
,
TrueFalseResponse
,
ExternalResponse
,
ImageResponse
,
OptionResponse
from
responsetypes
import
NumericalResponse
,
FormulaResponse
,
CustomResponse
,
SchematicResponse
,
MultipleChoiceResponse
,
StudentInputError
,
TrueFalseResponse
,
ExternalResponse
,
ImageResponse
,
OptionResponse
import
calc
import
calc
...
@@ -166,7 +167,7 @@ class LoncapaProblem(object):
...
@@ -166,7 +167,7 @@ class LoncapaProblem(object):
problems_simple
=
self
.
extract_problems
(
self
.
tree
)
problems_simple
=
self
.
extract_problems
(
self
.
tree
)
for
response
in
problems_simple
:
for
response
in
problems_simple
:
grader
=
response_types
[
response
.
tag
](
response
,
self
.
context
,
self
.
system
)
grader
=
response_types
[
response
.
tag
](
response
,
self
.
context
,
self
.
system
)
results
=
grader
.
g
rad
e
(
answers
)
# call the responsetype instance to do the actual grading
results
=
grader
.
g
et_scor
e
(
answers
)
# call the responsetype instance to do the actual grading
self
.
correct_map
.
update
(
results
)
self
.
correct_map
.
update
(
results
)
return
self
.
correct_map
return
self
.
correct_map
...
@@ -239,7 +240,7 @@ class LoncapaProblem(object):
...
@@ -239,7 +240,7 @@ class LoncapaProblem(object):
# used to be
# used to be
# if problemtree.tag in html_special_response:
# if problemtree.tag in html_special_response:
if
hasattr
(
inputtypes
,
problemtree
.
tag
):
if
problemtree
.
tag
in
inputtypes
.
get_input_xml_tags
(
):
# status is currently the answer for the problem ID for the input element,
# status is currently the answer for the problem ID for the input element,
# but it will turn into a dict containing both the answer and any associated message
# but it will turn into a dict containing both the answer and any associated message
# for the problem ID for the input element.
# for the problem ID for the input element.
...
@@ -266,9 +267,17 @@ class LoncapaProblem(object):
...
@@ -266,9 +267,17 @@ class LoncapaProblem(object):
# print "[courseware.capa.capa_problem.extract_html] msg = ",msg
# print "[courseware.capa.capa_problem.extract_html] msg = ",msg
# do the rendering
# do the rendering
#render_function = html_special_response[problemtree.tag]
# This should be broken out into a helper function
render_function
=
getattr
(
inputtypes
,
problemtree
.
tag
)
# that handles all input objects
return
render_function
(
problemtree
,
value
,
status
,
msg
)
# render the special response (textline, schematic,...)
render_object
=
inputtypes
.
SimpleInput
(
system
=
self
.
system
,
xml
=
problemtree
,
state
=
{
'value'
:
value
,
'status'
:
status
,
'id'
:
problemtree
.
get
(
'id'
),
'feedback'
:{
'message'
:
msg
}
},
use
=
'capa_input'
)
return
render_object
.
get_html
()
#function(problemtree, value, status, msg) # render the special response (textline, schematic,...)
tree
=
Element
(
problemtree
.
tag
)
tree
=
Element
(
problemtree
.
tag
)
for
item
in
problemtree
:
for
item
in
problemtree
:
...
...
djangoapps/courseware/capa/inputtypes.py
View file @
ed3f0817
...
@@ -32,8 +32,121 @@ from lxml import etree
...
@@ -32,8 +32,121 @@ from lxml import etree
from
mitxmako.shortcuts
import
render_to_string
from
mitxmako.shortcuts
import
render_to_string
def
get_input_xml_tags
():
''' Eventually, this will be for all registered input types '''
return
SimpleInput
.
get_xml_tags
()
class
SimpleInput
():
# XModule
''' Type for simple inputs -- plain HTML with a form element
State is a dictionary with optional keys:
* Value
* ID
* Status (answered, unanswered, unsubmitted)
* Feedback (dictionary containing keys for hints, errors, or other
feedback from previous attempt)
'''
xml_tags
=
{}
## Maps tags to functions
@classmethod
def
get_xml_tags
(
c
):
return
c
.
xml_tags
.
keys
()
@classmethod
def
get_uses
(
c
):
return
[
'capa_input'
,
'capa_transform'
]
def
get_html
(
self
):
return
self
.
xml_tags
[
self
.
tag
](
self
.
xml
,
self
.
value
,
self
.
status
,
self
.
msg
)
def
__init__
(
self
,
system
,
xml
,
item_id
=
None
,
track_url
=
None
,
state
=
None
,
use
=
'capa_input'
):
self
.
xml
=
xml
self
.
tag
=
xml
.
tag
if
not
state
:
state
=
{}
## ID should only come from one place.
## If it comes from multiple, we use state first, XML second, and parameter
## third. Since we don't make this guarantee, we can swap this around in
## the future if there's a more logical order.
if
item_id
:
self
.
id
=
item_id
if
xml
.
get
(
'id'
):
self
.
id
=
xml
.
get
(
'id'
)
if
'id'
in
state
:
self
.
id
=
state
[
'id'
]
self
.
system
=
system
self
.
value
=
''
if
'value'
in
state
:
self
.
value
=
state
[
'value'
]
self
.
msg
=
''
if
'feedback'
in
state
and
'message'
in
state
[
'feedback'
]:
self
.
msg
=
state
[
'feedback'
][
'message'
]
self
.
status
=
'unanswered'
if
'status'
in
state
:
self
.
status
=
state
[
'status'
]
## TODO
# class SimpleTransform():
# ''' Type for simple XML to HTML transforms. Examples:
# * Math tags, which go from LON-CAPA-style m-tags to MathJAX
# '''
# xml_tags = {} ## Maps tags to functions
# @classmethod
# def get_xml_tags(c):
# return c.xml_tags.keys()
# @classmethod
# def get_uses(c):
# return ['capa_transform']
# def get_html(self):
# return self.xml_tags[self.tag](self.xml, self.value, self.status, self.msg)
# def __init__(self, system, xml, item_id = None, track_url=None, state=None, use = 'capa_input'):
# self.xml = xml
# self.tag = xml.tag
# if not state:
# state = {}
# if item_id:
# self.id = item_id
# if xml.get('id'):
# self.id = xml.get('id')
# if 'id' in state:
# self.id = state['id']
# self.system = system
# self.value = ''
# if 'value' in state:
# self.value = state['value']
# self.msg = ''
# if 'feedback' in state and 'message' in state['feedback']:
# self.msg = state['feedback']['message']
# self.status = 'unanswered'
# if 'status' in state:
# self.status = state['status']
def
register_render_function
(
fn
,
names
=
None
,
cls
=
SimpleInput
):
if
names
==
None
:
SimpleInput
.
xml_tags
[
fn
.
__name__
]
=
fn
else
:
raise
NotImplementedError
def
wrapped
():
return
fn
return
wrapped
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
def
optioninput
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Select option input type.
Select option input type.
...
@@ -67,7 +180,7 @@ def optioninput(element, value, status, msg=''):
...
@@ -67,7 +180,7 @@ def optioninput(element, value, status, msg=''):
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
def
choicegroup
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Radio button inputs: multiple choice or true/false
Radio button inputs: multiple choice or true/false
...
@@ -90,6 +203,7 @@ def choicegroup(element, value, status, msg=''):
...
@@ -90,6 +203,7 @@ def choicegroup(element, value, status, msg=''):
html
=
render_to_string
(
"choicegroup.html"
,
context
)
html
=
render_to_string
(
"choicegroup.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
@register_render_function
def
textline
(
element
,
value
,
state
,
msg
=
""
):
def
textline
(
element
,
value
,
state
,
msg
=
""
):
eid
=
element
.
get
(
'id'
)
eid
=
element
.
get
(
'id'
)
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
count
=
int
(
eid
.
split
(
'_'
)[
-
2
])
-
1
# HACK
...
@@ -100,6 +214,7 @@ def textline(element, value, state, msg=""):
...
@@ -100,6 +214,7 @@ def textline(element, value, state, msg=""):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
js_textline
(
element
,
value
,
status
,
msg
=
''
):
def
js_textline
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Plan: We will inspect element to figure out type
Plan: We will inspect element to figure out type
...
@@ -125,6 +240,7 @@ def js_textline(element, value, status, msg=''):
...
@@ -125,6 +240,7 @@ def js_textline(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
## TODO: Make a wrapper for <codeinput>
## TODO: Make a wrapper for <codeinput>
@register_render_function
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
def
textbox
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
The textbox is used for code input. The message is the return HTML string from
The textbox is used for code input. The message is the return HTML string from
...
@@ -140,6 +256,7 @@ def textbox(element, value, status, msg=''):
...
@@ -140,6 +256,7 @@ def textbox(element, value, status, msg=''):
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
def
schematic
(
element
,
value
,
status
,
msg
=
''
):
eid
=
element
.
get
(
'id'
)
eid
=
element
.
get
(
'id'
)
height
=
element
.
get
(
'height'
)
height
=
element
.
get
(
'height'
)
...
@@ -164,6 +281,7 @@ def schematic(element, value, status, msg=''):
...
@@ -164,6 +281,7 @@ def schematic(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
### TODO: Move out of inputtypes
### TODO: Move out of inputtypes
@register_render_function
def
math
(
element
,
value
,
status
,
msg
=
''
):
def
math
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
This is not really an input type. It is a convention from Lon-CAPA, used for
This is not really an input type. It is a convention from Lon-CAPA, used for
...
@@ -198,6 +316,7 @@ def math(element, value, status, msg=''):
...
@@ -198,6 +316,7 @@ def math(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
solution
(
element
,
value
,
status
,
msg
=
''
):
def
solution
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
This is not really an input type. It is just a <span>...</span> which is given an ID,
This is not really an input type. It is just a <span>...</span> which is given an ID,
...
@@ -218,6 +337,7 @@ def solution(element, value, status, msg=''):
...
@@ -218,6 +337,7 @@ def solution(element, value, status, msg=''):
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
@register_render_function
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
def
imageinput
(
element
,
value
,
status
,
msg
=
''
):
'''
'''
Clickable image as an input field. Element should specify the image source, height, and width, eg
Clickable image as an input field. Element should specify the image source, height, and width, eg
...
@@ -253,4 +373,3 @@ def imageinput(element, value, status, msg=''):
...
@@ -253,4 +373,3 @@ def imageinput(element, value, status, msg=''):
print
'[courseware.capa.inputtypes.imageinput] context='
,
context
print
'[courseware.capa.inputtypes.imageinput] context='
,
context
html
=
render_to_string
(
"imageinput.html"
,
context
)
html
=
render_to_string
(
"imageinput.html"
,
context
)
return
etree
.
XML
(
html
)
return
etree
.
XML
(
html
)
djangoapps/courseware/capa/responsetypes.py
View file @
ed3f0817
...
@@ -47,10 +47,10 @@ def compare_with_tolerance(v1, v2, tol):
...
@@ -47,10 +47,10 @@ def compare_with_tolerance(v1, v2, tol):
return
abs
(
v1
-
v2
)
<=
tolerance
return
abs
(
v1
-
v2
)
<=
tolerance
class
GenericResponse
(
object
):
class
GenericResponse
(
object
):
__metaclass__
=
abc
.
ABCMeta
__metaclass__
=
abc
.
ABCMeta
# abc = Abstract Base Class
@abc.abstractmethod
@abc.abstractmethod
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
pass
pass
@abc.abstractmethod
@abc.abstractmethod
...
@@ -61,7 +61,7 @@ class GenericResponse(object):
...
@@ -61,7 +61,7 @@ class GenericResponse(object):
def
preprocess_response
(
self
):
def
preprocess_response
(
self
):
pass
pass
#Every response type needs methods "g
rad
e" and "get_answers"
#Every response type needs methods "g
et_scor
e" and "get_answers"
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
...
@@ -95,7 +95,7 @@ class MultipleChoiceResponse(GenericResponse):
...
@@ -95,7 +95,7 @@ class MultipleChoiceResponse(GenericResponse):
raise
Exception
(
"should have exactly one choice group per multiplechoicceresponse"
)
raise
Exception
(
"should have exactly one choice group per multiplechoicceresponse"
)
self
.
answer_id
=
self
.
answer_id
[
0
]
self
.
answer_id
=
self
.
answer_id
[
0
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
if
self
.
answer_id
in
student_answers
and
student_answers
[
self
.
answer_id
]
in
self
.
correct_choices
:
if
self
.
answer_id
in
student_answers
and
student_answers
[
self
.
answer_id
]
in
self
.
correct_choices
:
return
{
self
.
answer_id
:
'correct'
}
return
{
self
.
answer_id
:
'correct'
}
else
:
else
:
...
@@ -132,7 +132,7 @@ class TrueFalseResponse(MultipleChoiceResponse):
...
@@ -132,7 +132,7 @@ class TrueFalseResponse(MultipleChoiceResponse):
else
:
else
:
choice
.
set
(
"name"
,
"choice_"
+
choice
.
get
(
"name"
))
choice
.
set
(
"name"
,
"choice_"
+
choice
.
get
(
"name"
))
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct
=
set
(
self
.
correct_choices
)
correct
=
set
(
self
.
correct_choices
)
answers
=
set
(
student_answers
.
get
(
self
.
answer_id
,
[]))
answers
=
set
(
student_answers
.
get
(
self
.
answer_id
,
[]))
...
@@ -162,7 +162,7 @@ class OptionResponse(GenericResponse):
...
@@ -162,7 +162,7 @@ class OptionResponse(GenericResponse):
print
'[courseware.capa.responsetypes.OR.init] answer_fields=
%
s'
%
(
self
.
answer_fields
)
print
'[courseware.capa.responsetypes.OR.init] answer_fields=
%
s'
%
(
self
.
answer_fields
)
self
.
context
=
context
self
.
context
=
context
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
cmap
=
{}
cmap
=
{}
amap
=
self
.
get_answers
()
amap
=
self
.
get_answers
()
for
aid
in
amap
:
for
aid
in
amap
:
...
@@ -194,7 +194,7 @@ class NumericalResponse(GenericResponse):
...
@@ -194,7 +194,7 @@ class NumericalResponse(GenericResponse):
except
Exception
,
err
:
except
Exception
,
err
:
self
.
answer_id
=
None
self
.
answer_id
=
None
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
''' Display HTML for a numeric response '''
''' Display HTML for a numeric response '''
student_answer
=
student_answers
[
self
.
answer_id
]
student_answer
=
student_answers
[
self
.
answer_id
]
try
:
try
:
...
@@ -300,7 +300,7 @@ def sympy_check2():
...
@@ -300,7 +300,7 @@ def sympy_check2():
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
'''
'''
student_answers is a dict with everything from request.POST, but with the first part
student_answers is a dict with everything from request.POST, but with the first part
of each key removed (the string before the first "_").
of each key removed (the string before the first "_").
...
@@ -363,7 +363,7 @@ def sympy_check2():
...
@@ -363,7 +363,7 @@ def sympy_check2():
print
"oops in customresponse (cfn) error
%
s"
%
err
print
"oops in customresponse (cfn) error
%
s"
%
err
# print "context = ",self.context
# print "context = ",self.context
print
traceback
.
format_exc
()
print
traceback
.
format_exc
()
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
rad
e] ret = "
,
ret
if
settings
.
DEBUG
:
print
"[courseware.capa.responsetypes.customresponse.g
et_scor
e] ret = "
,
ret
if
type
(
ret
)
==
dict
:
if
type
(
ret
)
==
dict
:
correct
[
0
]
=
'correct'
if
ret
[
'ok'
]
else
'incorrect'
correct
[
0
]
=
'correct'
if
ret
[
'ok'
]
else
'incorrect'
msg
=
ret
[
'msg'
]
msg
=
ret
[
'msg'
]
...
@@ -428,7 +428,7 @@ class ExternalResponse(GenericResponse):
...
@@ -428,7 +428,7 @@ class ExternalResponse(GenericResponse):
self
.
tests
=
xml
.
get
(
'answer'
)
self
.
tests
=
xml
.
get
(
'answer'
)
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
submission
=
[
student_answers
[
k
]
for
k
in
sorted
(
self
.
answer_ids
)]
submission
=
[
student_answers
[
k
]
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
self
.
context
.
update
({
'submission'
:
submission
})
...
@@ -504,7 +504,7 @@ class FormulaResponse(GenericResponse):
...
@@ -504,7 +504,7 @@ class FormulaResponse(GenericResponse):
self
.
case_sensitive
=
False
self
.
case_sensitive
=
False
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
variables
=
self
.
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
variables
=
self
.
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
numsamples
=
int
(
self
.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
numsamples
=
int
(
self
.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
...
@@ -566,7 +566,7 @@ class SchematicResponse(GenericResponse):
...
@@ -566,7 +566,7 @@ class SchematicResponse(GenericResponse):
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
from
capa_problem
import
global_context
from
capa_problem
import
global_context
submission
=
[
json
.
loads
(
student_answers
[
k
])
for
k
in
sorted
(
self
.
answer_ids
)]
submission
=
[
json
.
loads
(
student_answers
[
k
])
for
k
in
sorted
(
self
.
answer_ids
)]
self
.
context
.
update
({
'submission'
:
submission
})
self
.
context
.
update
({
'submission'
:
submission
})
...
@@ -605,7 +605,7 @@ class ImageResponse(GenericResponse):
...
@@ -605,7 +605,7 @@ class ImageResponse(GenericResponse):
self
.
ielements
=
xml
.
findall
(
'imageinput'
)
self
.
ielements
=
xml
.
findall
(
'imageinput'
)
self
.
answer_ids
=
[
ie
.
get
(
'id'
)
for
ie
in
self
.
ielements
]
self
.
answer_ids
=
[
ie
.
get
(
'id'
)
for
ie
in
self
.
ielements
]
def
g
rad
e
(
self
,
student_answers
):
def
g
et_scor
e
(
self
,
student_answers
):
correct_map
=
{}
correct_map
=
{}
expectedset
=
self
.
get_answers
()
expectedset
=
self
.
get_answers
()
...
...
djangoapps/courseware/capa/util.py
View file @
ed3f0817
def
contextualize_text
(
text
,
context
):
# private
def
contextualize_text
(
text
,
context
):
# private
''' Takes a string with variables. E.g. $a+$b.
''' Takes a string with variables. E.g. $a+$b.
Does a substitution of those variables from the context '''
Does a substitution of those variables from the context '''
if
not
text
:
return
text
for
key
in
sorted
(
context
,
lambda
x
,
y
:
cmp
(
len
(
y
),
len
(
x
))):
for
key
in
sorted
(
context
,
lambda
x
,
y
:
cmp
(
len
(
y
),
len
(
x
))):
text
=
text
.
replace
(
'$'
+
key
,
str
(
context
[
key
]))
text
=
text
.
replace
(
'$'
+
key
,
str
(
context
[
key
]))
return
text
return
text
djangoapps/courseware/module_render.py
View file @
ed3f0817
...
@@ -13,8 +13,8 @@ from fs.osfs import OSFS
...
@@ -13,8 +13,8 @@ from fs.osfs import OSFS
from
django.conf
import
settings
from
django.conf
import
settings
from
mitxmako.shortcuts
import
render_to_string
from
mitxmako.shortcuts
import
render_to_string
from
models
import
StudentModule
from
models
import
StudentModule
from
multicourse
import
multicourse_settings
import
courseware.modules
import
courseware.modules
...
@@ -31,6 +31,8 @@ class I4xSystem(object):
...
@@ -31,6 +31,8 @@ class I4xSystem(object):
self
.
track_function
=
track_function
self
.
track_function
=
track_function
if
not
filestore
:
if
not
filestore
:
self
.
filestore
=
OSFS
(
settings
.
DATA_DIR
)
self
.
filestore
=
OSFS
(
settings
.
DATA_DIR
)
else
:
self
.
filestore
=
filestore
self
.
render_function
=
render_function
self
.
render_function
=
render_function
self
.
exception404
=
Http404
self
.
exception404
=
Http404
def
__repr__
(
self
):
def
__repr__
(
self
):
...
@@ -95,15 +97,15 @@ def render_x_module(user, request, xml_module, module_object_preload):
...
@@ -95,15 +97,15 @@ def render_x_module(user, request, xml_module, module_object_preload):
state
=
smod
.
state
state
=
smod
.
state
# get coursename if stored
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
else
:
coursename
=
Non
e
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
# Create a new instance
# Create a new instance
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module_type
+
'/'
+
module_id
+
'/'
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module_type
+
'/'
+
module_id
+
'/'
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
lambda
x
:
render_module
(
user
,
request
,
x
,
module_object_preload
),
render_function
=
lambda
x
:
render_module
(
user
,
request
,
x
,
module_object_preload
),
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
None
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
)
)
instance
=
module_class
(
system
,
instance
=
module_class
(
system
,
etree
.
tostring
(
xml_module
),
etree
.
tostring
(
xml_module
),
...
...
djangoapps/courseware/views.py
View file @
ed3f0817
...
@@ -2,6 +2,8 @@ import logging
...
@@ -2,6 +2,8 @@ import logging
import
urllib
import
urllib
import
json
import
json
from
fs.osfs
import
OSFS
from
django.conf
import
settings
from
django.conf
import
settings
from
django.core.context_processors
import
csrf
from
django.core.context_processors
import
csrf
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
...
@@ -38,9 +40,7 @@ def gradebook(request):
...
@@ -38,9 +40,7 @@ def gradebook(request):
if
'course_admin'
not
in
content_parser
.
user_groups
(
request
.
user
):
if
'course_admin'
not
in
content_parser
.
user_groups
(
request
.
user
):
raise
Http404
raise
Http404
# TODO: This should be abstracted out. We repeat this logic many times.
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
student_objects
=
User
.
objects
.
all
()[:
100
]
student_objects
=
User
.
objects
.
all
()[:
100
]
student_info
=
[{
'username'
:
s
.
username
,
student_info
=
[{
'username'
:
s
.
username
,
...
@@ -68,8 +68,7 @@ def profile(request, student_id = None):
...
@@ -68,8 +68,7 @@ def profile(request, student_id = None):
user_info
=
UserProfile
.
objects
.
get
(
user
=
student
)
# request.user.profile_cache #
user_info
=
UserProfile
.
objects
.
get
(
user
=
student
)
# request.user.profile_cache #
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
else
:
coursename
=
None
context
=
{
'name'
:
user_info
.
name
,
context
=
{
'name'
:
user_info
.
name
,
'username'
:
student
.
username
,
'username'
:
student
.
username
,
...
@@ -110,8 +109,7 @@ def render_section(request, section):
...
@@ -110,8 +109,7 @@ def render_section(request, section):
if
not
settings
.
COURSEWARE_ENABLED
:
if
not
settings
.
COURSEWARE_ENABLED
:
return
redirect
(
'/'
)
return
redirect
(
'/'
)
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
else
:
coursename
=
None
try
:
try
:
dom
=
content_parser
.
section_file
(
user
,
section
,
coursename
)
dom
=
content_parser
.
section_file
(
user
,
section
,
coursename
)
...
@@ -251,8 +249,8 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
...
@@ -251,8 +249,8 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module
+
'/'
+
id
+
'/'
ajax_url
=
settings
.
MITX_ROOT_URL
+
'/modx/'
+
module
+
'/'
+
id
+
'/'
# get coursename if stored
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
else
:
coursename
=
Non
e
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
# Grab the XML corresponding to the request from course.xml
# Grab the XML corresponding to the request from course.xml
try
:
try
:
...
@@ -269,7 +267,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
...
@@ -269,7 +267,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
render_function
=
None
,
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
None
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
)
)
try
:
try
:
...
@@ -307,12 +305,12 @@ def quickedit(request, id=None):
...
@@ -307,12 +305,12 @@ def quickedit(request, id=None):
print
"In deployed use, this will only edit on one server"
print
"In deployed use, this will only edit on one server"
print
"We need a setting to disable for production where there is"
print
"We need a setting to disable for production where there is"
print
"a load balanacer"
print
"a load balanacer"
if
not
request
.
user
.
is_staff
()
:
if
not
request
.
user
.
is_staff
:
return
redirect
(
'/'
)
return
redirect
(
'/'
)
# get coursename if stored
# get coursename if stored
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
coursename
=
multicourse_settings
.
get_coursename_from_request
(
request
)
else
:
coursename
=
Non
e
xp
=
multicourse_settings
.
get_course_xmlpath
(
coursename
)
# path to XML for the cours
e
def
get_lcp
(
coursename
,
id
):
def
get_lcp
(
coursename
,
id
):
# Grab the XML corresponding to the request from course.xml
# Grab the XML corresponding to the request from course.xml
...
@@ -325,9 +323,8 @@ def quickedit(request, id=None):
...
@@ -325,9 +323,8 @@ def quickedit(request, id=None):
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
system
=
I4xSystem
(
track_function
=
make_track_function
(
request
),
render_function
=
None
,
render_function
=
None
,
ajax_url
=
ajax_url
,
ajax_url
=
ajax_url
,
filestore
=
None
,
filestore
=
OSFS
(
settings
.
DATA_DIR
+
xp
),
coursename
=
coursename
,
#role = 'staff' if request.user.is_staff else 'student', # TODO: generalize this
role
=
'staff'
if
request
.
user
.
is_staff
else
'student'
,
# TODO: generalize this
)
)
instance
=
courseware
.
modules
.
get_module_class
(
module
)(
system
,
instance
=
courseware
.
modules
.
get_module_class
(
module
)(
system
,
xml
,
xml
,
...
...
djangoapps/multicourse/multicourse_settings.py
View file @
ed3f0817
...
@@ -42,6 +42,11 @@ else: # default to 6.002_Spring_2012
...
@@ -42,6 +42,11 @@ else: # default to 6.002_Spring_2012
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# wrapper functions around course settings
# wrapper functions around course settings
def
get_coursename_from_request
(
request
):
if
'coursename'
in
request
.
session
:
coursename
=
request
.
session
[
'coursename'
]
else
:
coursename
=
None
return
coursename
def
get_course_settings
(
coursename
):
def
get_course_settings
(
coursename
):
if
not
coursename
:
if
not
coursename
:
if
hasattr
(
settings
,
'COURSE_DEFAULT'
):
if
hasattr
(
settings
,
'COURSE_DEFAULT'
):
...
...
djangoapps/multicourse/views.py
View file @
ed3f0817
# multicourse/views.py
import
datetime
import
json
import
sys
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.core.context_processors
import
csrf
from
django.core.mail
import
send_mail
from
django.http
import
Http404
from
django.http
import
HttpResponse
from
django.shortcuts
import
redirect
from
mitxmako.shortcuts
import
render_to_response
,
render_to_string
import
courseware.capa.calc
import
track.views
from
multicourse
import
multicourse_settings
def
mitxhome
(
request
):
''' Home page (link from main header). List of courses. '''
if
settings
.
ENABLE_MULTICOURSE
:
context
=
{
'courseinfo'
:
multicourse_settings
.
COURSE_SETTINGS
}
return
render_to_response
(
"mitxhome.html"
,
context
)
return
info
(
request
)
lib/util/views.py
View file @
ed3f0817
...
@@ -61,12 +61,6 @@ def info(request):
...
@@ -61,12 +61,6 @@ def info(request):
''' Info page (link from main header) '''
''' Info page (link from main header) '''
return
render_to_response
(
"info.html"
,
{})
return
render_to_response
(
"info.html"
,
{})
def
mitxhome
(
request
):
''' Home page (link from main header). List of courses. '''
if
settings
.
ENABLE_MULTICOURSE
:
return
render_to_response
(
"mitxhome.html"
,
{})
return
info
(
request
)
# From http://djangosnippets.org/snippets/1042/
# From http://djangosnippets.org/snippets/1042/
def
parse_accept_header
(
accept
):
def
parse_accept_header
(
accept
):
"""Parse the Accept header *accept*, returning a list with pairs of
"""Parse the Accept header *accept*, returning a list with pairs of
...
...
templates/mathjax_include.html
0 → 100644
View file @
ed3f0817
##
## File: templates/mathjax_include.html
##
## Advanced mathjax using 2.0-latest CDN for Dynamic Math
##
## This enables ASCIIMathJAX, and is used by js_textbox
<script
type=
"text/x-mathjax-config"
>
// (function () {
var
QUEUE
=
MathJax
.
Hub
.
queue
;
// shorthand for the queue
var
math
=
null
;
var
jaxset
=
{};
// associative array of the element jaxs for the math output.
var
mmlset
=
{};
// associative array of mathml from each jax
// constructs mathML of the specified jax element
function
toMathML
(
jax
,
callback
)
{
var
mml
;
try
{
mml
=
jax
.
root
.
toMathML
(
""
);
}
catch
(
err
)
{
if
(
!
err
.
restart
)
{
throw
err
}
// an actual error
return
MathJax
.
Callback
.
After
([
toMathML
,
jax
,
callback
],
err
.
restart
);
}
MathJax
.
Callback
(
callback
)(
mml
);
}
// function to queue in MathJax to get put the MathML expression in in the right document element
function
UpdateMathML
(
jax
,
id
)
{
toMathML
(
jax
,
function
(
mml
)
{
// document.getElementById(id+'_fromjs').value=math.originalText+ "\n\n=>\n\n"+ mml;
delem
=
document
.
getElementById
(
"input_"
+
id
+
"_fromjs"
);
if
(
delem
)
{
delem
.
value
=
mml
;
};
mmlset
[
id
]
=
mml
;
})
}
MathJax
.
Hub
.
Config
({
tex2jax
:
{
inlineMath
:
[
[
"
\\
("
,
"
\\
)"
],
[
'[mathjaxinline]'
,
'[/mathjaxinline]'
]
],
displayMath
:
[
[
"
\\
["
,
"
\\
]"
],
[
'[mathjax]'
,
'[/mathjax]'
]
]
}
});
//
// The onchange event handler that typesets the
// math entered by the user
//
window
.
UpdateMath
=
function
(
Am
,
id
)
{
QUEUE
.
Push
([
"Text"
,
jaxset
[
id
],
Am
]);
QUEUE
.
Push
(
UpdateMathML
(
jaxset
[
id
],
id
));
}
// })();
function
DoUpdateMath
(
inputId
)
{
var
str
=
document
.
getElementById
(
"input_"
+
inputId
).
value
;
// make sure the input field is in the jaxset
if
(
$
.
inArray
(
inputId
,
jaxset
)
==
-
1
){
//alert('missing '+inputId);
if
(
document
.
getElementById
(
"display_"
+
inputId
)){
MathJax
.
Hub
.
queue
.
Push
(
function
()
{
math
=
MathJax
.
Hub
.
getAllJax
(
"display_"
+
inputId
)[
0
];
if
(
math
){
jaxset
[
inputId
]
=
math
;
}
});
};
}
UpdateMath
(
str
,
inputId
)
}
</script>
<
%
block
name=
"headextra"
/>
<!-- This must appear after all mathjax-config blocks, so it is after the imports from the other templates -->
<!-- TODO: move to settings -->
<script
type=
"text/javascript"
src=
"http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full"
>
</script>
templates/mitxhome.html
View file @
ed3f0817
...
@@ -28,10 +28,10 @@ $(document).ready(function(){
...
@@ -28,10 +28,10 @@ $(document).ready(function(){
<hr
width=
"100%"
>
<hr
width=
"100%"
>
<h3>
Courses available:
</h3>
<h3>
Courses available:
</h3>
<ul>
<ul>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
6
.
002_Spring_2012
/>
6.002 (Spring 2012)
</a></li>
% for coursename, info in courseinfo.items():
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
8
.
02_Spring_2013
/>
8.02 (Spring 2013
)
</a></li>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/${
coursename
}
/>
${info['title']} (${coursename}
)
</a></li>
<li><a
href=
${
MITX_ROOT_URL
}/
courseware
/
8
.
01_Spring_2013
/>
8.01 (Spring 201x)
</a></li>
% endfor
</ul>
</ul>
</section>
</section>
</div>
</div>
</section>
</section>
templates/optioninput.html
0 → 100644
View file @
ed3f0817
<form
class=
"option-input"
>
<select
name=
"input_${id}"
id=
"input_${id}"
>
<option
value=
"option_${id}_dummy_default"
>
</option>
% for option_id, option_description in options.items():
<option
value=
"${option_id}"
%
if
(
option_id=
=value):
selected=
"true"
%
endif
>
${option_description}
</option>
% endfor
</select>
<span
id=
"answer_${id}"
></span>
% if state == 'unsubmitted':
<span
class=
"unanswered"
style=
"display:inline-block;"
id=
"status_${id}"
></span>
% elif state == 'correct':
<span
class=
"correct"
id=
"status_${id}"
></span>
% elif state == 'incorrect':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% elif state == 'incomplete':
<span
class=
"incorrect"
id=
"status_${id}"
></span>
% endif
</form>
templates/problem.html
View file @
ed3f0817
...
@@ -3,6 +3,15 @@
...
@@ -3,6 +3,15 @@
% if problem['weight']:
% if problem['weight']:
: ${ problem['weight'] } points
: ${ problem['weight'] } points
% endif
% endif
% if settings.QUICKEDIT:
<span
class=
"staff"
>
<br/>
<br/>
<br/>
<br/>
<font
size=
-2
><a
href=
${MITX_ROOT_URL}/quickedit/${id}
>
Quick
Edit Problem
</a></font></span>
% endif
</h2>
</h2>
<section
class=
"problem"
>
<section
class=
"problem"
>
...
...
urls.py
View file @
ed3f0817
...
@@ -70,7 +70,7 @@ if settings.COURSEWARE_ENABLED:
...
@@ -70,7 +70,7 @@ if settings.COURSEWARE_ENABLED:
)
)
if
settings
.
ENABLE_MULTICOURSE
:
if
settings
.
ENABLE_MULTICOURSE
:
urlpatterns
+=
(
url
(
r'^mitxhome$'
,
'
util
.views.mitxhome'
),)
urlpatterns
+=
(
url
(
r'^mitxhome$'
,
'
multicourse
.views.mitxhome'
),)
if
settings
.
QUICKEDIT
:
if
settings
.
QUICKEDIT
:
urlpatterns
+=
(
url
(
r'^quickedit/(?P<id>[^/]*)$'
,
'courseware.views.quickedit'
),)
urlpatterns
+=
(
url
(
r'^quickedit/(?P<id>[^/]*)$'
,
'courseware.views.quickedit'
),)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment