def parse_from_xml(root): """ Update the OpenAssessment XBlock's content from an XML definition. We need to be strict about the XML we accept, to avoid setting the XBlock to an invalid state (which will then be persisted). Args: root (lxml.etree.Element): The XML definition of the XBlock's content. Returns: A dictionary of all of the XBlock's content. Raises: UpdateFromXmlError: The XML definition is invalid """ # Check that the root has the correct tag if root.tag != 'openassessment': raise UpdateFromXmlError( 'Every open assessment problem must contain an "openassessment" element.' ) # Retrieve the start date for the submission # Set it to None by default; we will update it to the latest start date later on submission_start = None if 'submission_start' in root.attrib: submission_start = parse_date(str(root.attrib['submission_start']), name="submission start date") # Retrieve the due date for the submission # Set it to None by default; we will update it to the earliest deadline later on submission_due = None if 'submission_due' in root.attrib: submission_due = parse_date(str(root.attrib['submission_due']), name="submission due date") text_response = None if 'text_response' in root.attrib: text_response = str(root.attrib['text_response']) text_response_editor = 'text' if 'text_response_editor' in root.attrib: text_response_editor = str(root.attrib['text_response_editor']) file_upload_response = None if 'file_upload_response' in root.attrib: file_upload_response = str(root.attrib['file_upload_response']) allow_file_upload = None if 'allow_file_upload' in root.attrib: allow_file_upload = _parse_boolean( str(root.attrib['allow_file_upload'])) file_upload_type = None if 'file_upload_type' in root.attrib: file_upload_type = str(root.attrib['file_upload_type']) white_listed_file_types = None if 'white_listed_file_types' in root.attrib: white_listed_file_types = str(root.attrib['white_listed_file_types']) allow_multiple_files = True if 'allow_multiple_files' in root.attrib: allow_multiple_files = _parse_boolean( str(root.attrib['allow_multiple_files'])) allow_latex = False if 'allow_latex' in root.attrib: allow_latex = _parse_boolean(str(root.attrib['allow_latex'])) group_access = {} if 'group_access' in root.attrib: group_access = GroupAccessDict().from_json( json.loads(root.attrib['group_access'])) show_rubric_during_response = False if 'show_rubric_during_response' in root.attrib: show_rubric_during_response = _parse_boolean( str(root.attrib['show_rubric_during_response'])) # Retrieve the title title_el = root.find('title') if title_el is None: raise UpdateFromXmlError( 'Every assessment must contain a "title" element.') title = _safe_get_text(title_el) # Retrieve the rubric rubric_el = root.find('rubric') if rubric_el is None: raise UpdateFromXmlError( 'Every assessment must contain a "rubric" element.') rubric = parse_rubric_xml(rubric_el) # Retrieve the prompts prompts = _parse_prompts_xml(root) prompts_type = 'text' if 'prompts_type' in root.attrib: prompts_type = str(root.attrib['prompts_type']) # Retrieve the leaderboard if it exists, otherwise set it to 0 leaderboard_show = 0 if 'leaderboard_show' in root.attrib: try: leaderboard_show = int(root.attrib['leaderboard_show']) except (TypeError, ValueError) as ex: raise UpdateFromXmlError( 'The leaderboard must have an integer value.') from ex # Retrieve teams info teams_enabled = False selected_teamset_id = None if 'teams_enabled' in root.attrib: teams_enabled = _parse_boolean(str(root.attrib['teams_enabled'])) if 'selected_teamset_id' in root.attrib: selected_teamset_id = str(root.attrib['selected_teamset_id']) # Retrieve the assessments assessments_el = root.find('assessments') if assessments_el is None: raise UpdateFromXmlError( 'Every assessment must contain an "assessments" element.') assessments = parse_assessments_xml(assessments_el) return { 'title': title, 'prompts': prompts, 'prompts_type': prompts_type, 'rubric_criteria': rubric['criteria'], 'rubric_assessments': assessments, 'rubric_feedback_prompt': rubric['feedbackprompt'], 'rubric_feedback_default_text': rubric['feedback_default_text'], 'submission_start': submission_start, 'submission_due': submission_due, 'text_response': text_response, 'text_response_editor': text_response_editor, 'file_upload_response': file_upload_response, 'allow_file_upload': allow_file_upload, 'file_upload_type': file_upload_type, 'white_listed_file_types': white_listed_file_types, 'allow_multiple_files': allow_multiple_files, 'allow_latex': allow_latex, 'group_access': group_access, 'leaderboard_show': leaderboard_show, 'teams_enabled': teams_enabled, 'selected_teamset_id': selected_teamset_id, 'show_rubric_during_response': show_rubric_during_response, }
def serialize_content_to_xml(oa_block, root): """ Serialize the OpenAssessment XBlock's content to XML. Args: oa_block (OpenAssessmentBlock): The open assessment block to serialize. root (etree.Element): The XML root node to update. Returns: etree.Element """ root.tag = 'openassessment' # Set the submission start date if oa_block.submission_start is not None: root.set('submission_start', str(oa_block.submission_start)) # Set submission due date if oa_block.submission_due is not None: root.set('submission_due', str(oa_block.submission_due)) # Set leaderboard show if oa_block.leaderboard_show: root.set('leaderboard_show', str(oa_block.leaderboard_show)) # Set text response if oa_block.text_response: root.set('text_response', str(oa_block.text_response)) # Set text response editor if oa_block.text_response_editor: root.set('text_response_editor', str(oa_block.text_response_editor)) # Set file upload response if oa_block.file_upload_response: root.set('file_upload_response', str(oa_block.file_upload_response)) # Set File upload settings if oa_block.file_upload_type: root.set('file_upload_type', str(oa_block.file_upload_type)) # Set File type white listing if oa_block.white_listed_file_types: root.set('white_listed_file_types', str(oa_block.white_listed_file_types_string)) if oa_block.allow_multiple_files is not None: root.set('allow_multiple_files', str(oa_block.allow_multiple_files)) if oa_block.allow_latex is not None: root.set('allow_latex', str(oa_block.allow_latex)) # Set group access setting if not empty if oa_block.group_access: root.set('group_access', json.dumps(GroupAccessDict().to_json(oa_block.group_access))) # Open assessment displayed title title = etree.SubElement(root, 'title') title.text = str(oa_block.title) # Assessment list 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) root.set('prompts_type', str(oa_block.prompts_type)) # Rubric rubric_root = etree.SubElement(root, 'rubric') serialize_rubric(rubric_root, oa_block) # Team info if oa_block.teams_enabled is not None: root.set('teams_enabled', str(oa_block.teams_enabled)) if oa_block.selected_teamset_id is not None: root.set('selected_teamset_id', str(oa_block.selected_teamset_id)) if oa_block.show_rubric_during_response is not None: root.set('show_rubric_during_response', str(oa_block.show_rubric_during_response))