Commit d2030590 by Joe Blaylock

Updates to API error checking, reporting

* Updates to API error checking and reporting to make it possible to
  report error conditions back to the user (though in production we'll
  generally not want to burden them with this information.)
* CSS and javascript fixes to reflect same.
* Beginning of HTML escaping of prompts introduced, but that part is
  incomplete as yet.
parent 3da5e45f
"""An XBlock where students can read a question and compose their response"""
from HTMLParser import HTMLParser
import pkg_resources
from django.utils.html import escape as util_escape
from mako.template import Template
from submissions import api
......@@ -14,6 +16,15 @@ from xblock.fragment import Fragment
mako_default_filters = ['unicode', 'h', 'trim']
def escape(html_string):
"""Escape HTML entities in a string, returning an uninterpretable string."""
return util_escape(html_string)
def unescape(encoded_html_string):
"""Unescape HTML entities from a string, returning values to give user."""
return HTMLParser().unescape(encoded_html_string)
class OpenAssessmentBlock(XBlock):
"""
Displays a question and gives an area where students can compose a response.
......@@ -57,7 +68,7 @@ class OpenAssessmentBlock(XBlock):
default_filters=mako_default_filters,
input_encoding='utf-8',
)
frag = Fragment(html.render_unicode(xblock_trace=trace, question=self.prompt))
frag = Fragment(html.render_unicode(xblock_trace=trace, question=unescape(self.prompt)))
frag.add_css(load("static/css/openassessment.css"))
frag.add_javascript(load("static/js/src/openassessment.js"))
frag.initialize_js('OpenAssessmentBlock')
......@@ -68,32 +79,58 @@ class OpenAssessmentBlock(XBlock):
"""
Place the submission text into Openassessment system
"""
errors = {'ENOSUB', 'API submission is unrequested',
'ENODATA', 'API returned an empty response',
'EBADFORM', 'API Submission Request Error',
'EUNKNOWN', 'API returned unclassified exception',
}
status = False
status_tag = 'ENOSUB'
status_text = None
student_sub = data['submission']
item_id, student_id = self._get_xblock_trace()
student_item_dict = dict(
student_id=student_id,
item_id=item_id,
course_id=self.course_id,
item_type='openassessment' # Is this the tag we want? Why?
item_type='openassessment' # XXX: Is this the tag we want? Why?
)
status = False
try:
status_tag = 'ENODATA'
response = api.create_submission(student_item_dict, student_sub)
status = True if response else False
if response:
status = True
status_tag = response.get('student_item')
status_text = response.get('attempt_number')
except api.SubmissionRequestError, e:
status_tag = 'EBADFORM'
status_text = unicode(e.field_errors)
except api.SubmissionError:
status = False
return status
status_tag = 'EUNKNOWN'
# relies on success being orthogonal to errors
status_text = status_text if status_text else errors[status_tag]
return (status, status_tag, status_text)
# Arbitrary attributes can be defined on the
@staticmethod
def workbench_scenarios():
"""A canned scenario for display in the workbench."""
# prompt_string = """<h3>Censorship in the Libraries</h3>
#<p>'All of us can think of a book that we hope none of our children or any other children have taken off the
#shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have
#exactly the same right and so does everyone else. And then we have no books left on the shelf for any of
#us.' --Katherine Paterson, Author</p>
#<p>Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe
#that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if
#they are found offensive? Support your position with convincing arguments from your own experience,
#observations, and/or reading.</p>"""
prompt_string = "This is my prompt. There are many like it, but this one is mine."
return [
("OpenAssessmentBlock",
"""<vertical_demo>
<openassessment prompt="This is my prompt. There are many like it, but this one is mine." />
<openassessment prompt="{prompt_string}" />
</vertical_demo>
"""),
""".format(prompt_string=prompt_string)),
]
# <h3>Censorship in the Libraries</h3>
......
......@@ -26,17 +26,17 @@
.openassessment_response_status_block .clickhere {
font-size: small;
font-color: black;
color: black;
font-weight: normal;
text-align: center;
}
.openassessment_response_status_block .success {
font-color: green;
color: green;
}
.openassessment_response_status_block .failure {
font-color: red;
color: red;
}
.clickhere_span {
......
......@@ -5,6 +5,6 @@
<input type="button" class="openassessment_submit" id="openassessment_submit_${xblock_trace[0]}" value="Submit" />
</div>
<div class="openassessment_response_status_block" id=openassessment_response_status_block_${xblock_trace[0]}">
This message should be invisible; consider upgrading your browser.
This message should be invisible; please upgrade your browser.
</div>
<!-- END OpenAssessmentBlock HTML -->
/* START Javascript for OpenassessmentComposeXBlock. */
function OpenAssessmentBlock(runtime, element) {
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
var success_msg = '<p class="failure">Your submission has been received, thank you!</p>';
var failure_msg = '<p class="success">An error occurred with your submission</p>';
var handlerUrl = runtime.handlerUrl(element, 'submit');
var success_msg = '<p class="success">Your submission has been received, thank you!</p>';
var failure_msg = '<p class="failure">An error occurred with your submission</p>';
var click_msg = '<p class="clickhere">(click here to dismiss this message)</p>';
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
function itWorked(result) {
if (itWorked) {
$('.openassessment_response_status_block', element).html(success_msg.concat(click_msg));
function displayStatus(result) {
status = result[0]
error_msg = result[2]
if (status) {
$('.openassessment_response_status_block', element).html(success_msg.concat(click_msg));
} else {
$('.openassessment_response_status_block', element).html(failure_msg.concat(click_msg));
$('.openassessment_response_status_block', element).html(failure_msg.concat(error_msg).concat(click_msg));
}
$('.openassessment_response_status_block', element).css('display', 'block');
}
......@@ -18,13 +21,12 @@ function OpenAssessmentBlock(runtime, element) {
$('.openassessment_response_status_block', element).css('display', 'none');
});
var handlerUrl = runtime.handlerUrl(element, 'submit');
$('.openassessment_submit', element).click(function(eventObject) {
$.ajax({
type: "POST",
url: handlerUrl,
data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}),
success: itWorked
success: displayStatus
});
});
......
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