Commit e6e75978 by Usman Khalid

Parse and serialize multiple prompts

TNL-708
parent d6511edd
......@@ -418,7 +418,7 @@ class OpenAssessmentBlock(
xblock_validator = validator(block, block._, strict_post_release=False)
xblock_validator(
create_rubric_dict(config['prompt'], config['rubric_criteria']),
create_rubric_dict(config['prompts'], config['rubric_criteria']),
config['rubric_assessments'],
submission_start=config['submission_start'],
submission_due=config['submission_due'],
......@@ -432,7 +432,7 @@ class OpenAssessmentBlock(
block.submission_start = config['submission_start']
block.submission_due = config['submission_due']
block.title = config['title']
block.prompt = config['prompt']
block.prompts = config['prompts']
block.allow_file_upload = config['allow_file_upload']
block.allow_latex = config['allow_latex']
block.leaderboard_show = config['leaderboard_show']
......
......@@ -55,6 +55,26 @@ def _safe_get_text(element):
return unicode(element.text) if element.text is not None else u""
def _serialize_prompts(prompts_root, prompts_list):
"""
Serialize prompts as XML, adding children to the XML with root
node `prompts_root`.
Args:
prompts_root (lxml.etree.Element): The root node of the tree.
prompts_list (list): List of prompt dictionaries.
Returns:
None
"""
for prompt in prompts_list:
prompt_el = etree.SubElement(prompts_root, 'prompt')
# Prompt description
prompt_description = etree.SubElement(prompt_el, 'description')
prompt_description.text = unicode(prompt.get('description', u''))
def _serialize_options(options_root, options_list):
"""
Serialize rubric criterion options as XML, adding children to the XML
......@@ -139,7 +159,7 @@ def _serialize_criteria(criteria_root, criteria_list):
_serialize_options(criterion_el, options_list)
def serialize_rubric(rubric_root, oa_block, include_prompt=True):
def serialize_rubric(rubric_root, oa_block):
"""
Serialize a rubric dictionary as XML, adding children to the XML
with root node `rubric_root`.
......@@ -153,17 +173,9 @@ def serialize_rubric(rubric_root, oa_block, include_prompt=True):
rubric_dict (dict): A dictionary representation of the rubric, of the form
described in the serialized Rubric model (peer grading serializers).
Kwargs:
include_prompt (bool): Whether or not to include the prompt in the
serialized format for a rubric. Defaults to True.
Returns:
None
"""
# Rubric prompt (default to empty text); None indicates no input element
if include_prompt and oa_block.prompt is not None:
prompt = etree.SubElement(rubric_root, 'prompt')
prompt.text = unicode(oa_block.prompt)
# Criteria
criteria_list = oa_block.rubric_criteria
......@@ -227,6 +239,51 @@ def _parse_boolean(boolean_str):
return boolean_str in ['True', 'true']
def _parse_prompts_xml(root):
"""
Parse <prompts> element in the OpenAssessment XBlock's content XML.
Args:
root (lxml.etree.Element): The root node of the tree.
Returns:
list of prompts dictionaries.
Raises:
UpdateFromXmlError: The XML definition is invalid or the XBlock could not be updated.
"""
prompts_list = []
prompts_el = root.find('prompts')
if prompts_el is not None:
for prompt in prompts_el.findall('prompt'):
prompt_dict = dict()
# Prompt description
prompt_description = prompt.find('description')
if prompt_description is not None:
prompt_dict['description'] = _safe_get_text(prompt_description)
else:
raise UpdateFromXmlError('Every "prompt" element must contain a "description" element.')
prompts_list.append(prompt_dict)
else:
# For backwards compatibility. Initially a single prompt element was added in
# the rubric element.
rubric_el = root.find('rubric')
prompt_el = rubric_el.find('prompt')
prompt_description = ''
if prompt_el is not None:
prompt_description = _safe_get_text(prompt_el)
prompts_list.append(
{
'description': prompt_description,
}
)
return prompts_list
def _parse_options_xml(options_root):
"""
Parse <options> element in the OpenAssessment XBlock's content XML.
......@@ -368,13 +425,6 @@ def parse_rubric_xml(rubric_root):
"""
rubric_dict = dict()
# Rubric prompt
prompt_el = rubric_root.find('prompt')
if prompt_el is not None:
rubric_dict['prompt'] = _safe_get_text(prompt_el)
else:
rubric_dict['prompt'] = None
feedback_prompt_el = rubric_root.find('feedbackprompt')
if feedback_prompt_el is not None:
rubric_dict['feedbackprompt'] = _safe_get_text(feedback_prompt_el)
......@@ -635,6 +685,10 @@ def serialize_content_to_xml(oa_block, root):
assessments_root = etree.SubElement(root, 'assessments')
serialize_assessments(assessments_root, oa_block)
# Prompts
prompts_root = etree.SubElement(root, 'prompts')
_serialize_prompts(prompts_root, oa_block.prompts)
# Rubric
rubric_root = etree.SubElement(root, 'rubric')
serialize_rubric(rubric_root, oa_block)
......@@ -673,7 +727,7 @@ def serialize_rubric_to_xml_str(oa_block):
"""
rubric_root = etree.Element('rubric')
serialize_rubric(rubric_root, oa_block, include_prompt=False)
serialize_rubric(rubric_root, oa_block)
return etree.tostring(rubric_root, pretty_print=True, encoding='unicode')
......@@ -767,6 +821,9 @@ def parse_from_xml(root):
else:
rubric = parse_rubric_xml(rubric_el)
# Retrieve the prompts
prompts = _parse_prompts_xml(root)
# Retrieve the leaderboard if it exists, otherwise set it to 0
leaderboard_show = 0
if 'leaderboard_show' in root.attrib:
......@@ -784,7 +841,7 @@ def parse_from_xml(root):
return {
'title': title,
'prompt': rubric['prompt'],
'prompts': prompts,
'rubric_criteria': rubric['criteria'],
'rubric_assessments': assessments,
'rubric_feedback_prompt': rubric['feedbackprompt'],
......
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