Commit 0c43ff6a by Braden MacDonald

Merge pull request #7 from open-craft/import-export-fix2

Remove custom deserialization code
parents ba65ce0a 2cf54dc5
......@@ -10,6 +10,7 @@ install:
- "pip install -r $VIRTUAL_ENV/src/xblock-sdk/test-requirements.txt"
- "pip install -r requirements.txt"
- "pip uninstall -y xblock-problem-builder && python setup.py sdist && pip install dist/xblock-problem-builder-2.0.tar.gz"
- "pip install -r test_requirements.txt"
script:
- pep8 problem_builder --max-line-length=120
- pylint problem_builder --disable=all --enable=function-redefined,undefined-variable,unused-variable
......
......@@ -90,34 +90,6 @@ class QuestionnaireAbstractBlock(StudioEditableXBlockMixin, StudioContainerXBloc
""" translate text """
return self.runtime.service(self, "i18n").ugettext(text)
@classmethod
def parse_xml(cls, node, runtime, keys, id_generator):
"""
Custom XML parser that can handle list type fields properly,
as well as the old way of defining 'question' and 'message' field values via tags.
"""
block = runtime.construct_xblock_from_class(cls, keys)
# Load XBlock properties from the XML attributes:
for name, value in node.items():
if name not in block.fields:
logging.warn("XBlock %s does not contain field %s", type(block), name)
continue
field = block.fields[name]
if isinstance(field, List) and not value.startswith('['):
# This list attribute is just a string of comma separated strings:
setattr(block, name, [unicode(val).strip() for val in value.split(',')])
elif isinstance(field, String):
setattr(block, name, value)
else:
setattr(block, name, field.from_json(value))
for xml_child in node:
if xml_child.tag is not etree.Comment:
block.runtime.add_node_as_child(block, xml_child, id_generator)
return block
@property
def html_id(self):
"""
......
......@@ -14,32 +14,32 @@
<pb-answer name="goal" question="What is your goal?" />
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes">Great!</pb-tip>
<pb-tip values="maybenot">Ah, damn.</pb-tip>
<pb-tip values="understand"><div id="test-custom-html">Really?</div></pb-tip>
<pb-tip values='["yes"]'>Great!</pb-tip>
<pb-tip values='["maybenot"]'>Ah, damn.</pb-tip>
<pb-tip values='["understand"]'><div id="test-custom-html">Really?</div></pb-tip>
</pb-mcq>
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How much do you rate this MCQ?" correct_choices="4,5">
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How much do you rate this MCQ?" correct_choices='["4","5"]'>
<pb-choice value="notwant">I don't want to rate it</pb-choice>
<pb-tip values="4,5">I love good grades.</pb-tip>
<pb-tip values="1,2,3">Will do better next time...</pb-tip>
<pb-tip values="notwant">Your loss!</pb-tip>
<pb-tip values='["4","5"]'>I love good grades.</pb-tip>
<pb-tip values='["1","2", "3"]'>Will do better next time...</pb-tip>
<pb-tip values='["notwant"]'>Your loss!</pb-tip>
</pb-rating>
<pb-mrq name="mrq_1_1" question="What do you like in this MRQ?" required_choices="gracefulness,elegance,beauty">
<pb-mrq name="mrq_1_1" question="What do you like in this MRQ?" required_choices='["gracefulness","elegance","beauty"]'>
<pb-choice value="elegance">Its elegance</pb-choice>
<pb-choice value="beauty">Its beauty</pb-choice>
<pb-choice value="gracefulness">Its gracefulness</pb-choice>
<pb-choice value="bugs">Its bugs</pb-choice>
<pb-tip values="gracefulness">This MRQ is indeed very graceful</pb-tip>
<pb-tip values="elegance,beauty">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values="bugs">Nah, there isn't any!</pb-tip>
<pb-tip values='["gracefulness"]'>This MRQ is indeed very graceful</pb-tip>
<pb-tip values='["elegance","beauty"]'>This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values='["bugs"]'>Nah, there isn't any!</pb-tip>
</pb-mrq>
</problem-builder>
......@@ -4,13 +4,13 @@
<p>Please answer the questions below.</p>
</html_demo>
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value='["yes"]'>Yes</pb-choice>
<pb-choice value='["maybenot"]'>Maybe not</pb-choice>
<pb-choice value='["understand"]'>I don't understand</pb-choice>
<pb-tip values="yes">Great!</pb-tip>
<pb-tip values="maybenot">Ah, damn.</pb-tip>
<pb-tip values="understand"><div id="test-custom-html">Really?</div></pb-tip>
<pb-tip values='["yes"]'>Great!</pb-tip>
<pb-tip values='["maybenot"]'>Ah, damn.</pb-tip>
<pb-tip values='["understand"]'><div id="test-custom-html">Really?</div></pb-tip>
</pb-mcq>
</problem-builder>
<vertical_demo>
<problem-builder url_name="mcq_1" enforce_dependency="false">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes">Great!</pb-tip>
<pb-tip values="maybenot">Ah, damn.</pb-tip>
<pb-tip values="understand"><div id="test-custom-html">Really?</div></pb-tip>
<pb-tip values='["yes"]'>Great!</pb-tip>
<pb-tip values='["maybenot"]'>Ah, damn.</pb-tip>
<pb-tip values='["understand"]'><div id="test-custom-html">Really?</div></pb-tip>
</pb-mcq>
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How do you rate this MCQ?" correct_choices="4,5">
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How do you rate this MCQ?" correct_choices='["4","5"]'>
<pb-choice value="notwant">I don't want to rate it</pb-choice>
<pb-tip values="4,5">I love good grades.</pb-tip>
<pb-tip values="1,2,3">Will do better next time...</pb-tip>
<pb-tip values="notwant">Your loss!</pb-tip>
<pb-tip values='["4","5"]'>I love good grades.</pb-tip>
<pb-tip values='["1","2","3"]'>Will do better next time...</pb-tip>
<pb-tip values='["notwant"]'>Your loss!</pb-tip>
</pb-rating>
<pb-message type="completed">
......
<vertical_demo>
<problem-builder url_name="mcq_with_comments" display_name="MRQ With Resizable popups" weight="1" enforce_dependency="false">
<pb-mrq name="mrq_1_1_7" question="What do you like in this MRQ?" required_choices="elegance,gracefulness,beauty">
<pb-mrq name="mrq_1_1_7" question="What do you like in this MRQ?" required_choices='["elegance","gracefulness","beauty"]'>
<pb-choice value="elegance">Its elegance</pb-choice>
<pb-choice value="beauty">Its beauty</pb-choice>
<pb-choice value="gracefulness">Its gracefulness</pb-choice>
<pb-choice value="bugs">Its bugs</pb-choice>
<pb-tip values="gracefulness" width ="200" height = "200">This MRQ is indeed very graceful</pb-tip>
<pb-tip values="elegance" width ="600" height = "800">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values="beauty" width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values="bugs" width = "100" height = "200">Nah, there isn\'t any!</pb-tip>
<pb-tip values='["gracefulness"]' width ="200" height = "200">This MRQ is indeed very graceful</pb-tip>
<pb-tip values='["elegance"]' width ="600" height = "800">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values='["beauty"]' width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values='["bugs"]' width = "100" height = "200">Nah, there isn\'t any!</pb-tip>
<!--<pb-message type="on-submit">This is deliberately commented out to test parsing of XML comments</pb-message> -->
</pb-mrq>
......
<vertical_demo>
<problem-builder url_name="mcq_1" enforce_dependency="false">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes" height="10">Great!</pb-tip> <!--should be no less than 40 -->
<pb-tip values="maybenot" height="60">Ah, damn.</pb-tip>
<pb-tip values="understand" height="600">Really?</pb-tip> <!-- should override max-height -->
<pb-tip values='["yes"]' height="10">Great!</pb-tip> <!--should be no less than 40 -->
<pb-tip values='["maybenot"]' height="60">Ah, damn.</pb-tip>
<pb-tip values='["understand"]' height="600">Really?</pb-tip> <!-- should override max-height -->
</pb-mcq>
</problem-builder>
</vertical_demo>
<vertical_demo>
<problem-builder url_name="mcq_with_comments" display_name="MCQ With Resizable popups" weight="1" enforce_dependency="false">
<pb-mcq name="mrq_1_1_7" question="What do you like in this MCQ?" correct_choices="gracefulness,elegance,beauty">
<pb-mcq name="mrq_1_1_7" question="What do you like in this MCQ?" correct_choices='["gracefulness","elegance","beauty"]'>
<pb-choice value="elegance"><strong>Its elegance</strong></pb-choice>
<pb-choice value="beauty"><em>Its beauty</em></pb-choice>
<pb-choice value="gracefulness"><strong>Its gracefulness</strong></pb-choice>
<pb-choice value="bugs"><span style="font-color:red">Its bugs</span></pb-choice>
<pb-tip values="gracefulness" width ="200" height = "200">This MCQ is indeed very graceful</pb-tip>
<pb-tip values="elegance" width ="600" height = "800">This is something everyone has to like about this MCQ</pb-tip>
<pb-tip values="beauty" width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values="bugs" width = "100" height = "200">Nah, there isn\'t any!</pb-tip>
<pb-tip values='["gracefulness"]' width ="200" height = "200">This MCQ is indeed very graceful</pb-tip>
<pb-tip values='["elegance"]' width ="600" height = "800">This is something everyone has to like about this MCQ</pb-tip>
<pb-tip values='["beauty"]' width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values='["bugs"]' width = "100" height = "200">Nah, there isn\'t any!</pb-tip>
</pb-mcq>
<pb-message type="completed">
......
<vertical_demo>
<problem-builder url_name="mcq_with_comments" display_name="MRQ With Resizable popups" weight="1" enforce_dependency="false">
<pb-mrq name="mrq_1_1_7" question="What do you like in this MRQ?" required_choices="elegance,beauty,gracefulness">
<pb-mrq name="mrq_1_1_7" question="What do you like in this MRQ?" required_choices='["elegance","beauty","gracefulness"]'>
<pb-choice value="elegance"><strong>Its elegance</strong></pb-choice>
<pb-choice value="beauty"><em>Its beauty</em></pb-choice>
<pb-choice value="gracefulness"><strong>Its gracefulness</strong></pb-choice>
<pb-choice value="bugs"><span style="font-color:red">Its bugs</span></pb-choice>
<pb-tip values="gracefulness" width ="200" height = "200">This MRQ is indeed very graceful</pb-tip>
<pb-tip values="elegance" width ="600" height = "800">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values="beauty" width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values="bugs" width = "100" height = "200">Nah, there aren\'t any!</pb-tip>
<pb-tip values='["gracefulness"]' width ="200" height = "200">This MRQ is indeed very graceful</pb-tip>
<pb-tip values='["elegance"]' width ="600" height = "800">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values='["beauty"]' width ="400" height = "600">This is something everyone has to like about beauty</pb-tip>
<pb-tip values='["bugs"]' width = "100" height = "200">Nah, there aren\'t any!</pb-tip>
</pb-mrq>
<pb-message type="completed">
......
......@@ -4,13 +4,13 @@
<p>Please answer the questions below.</p>
</html_demo>
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes">Great!</pb-tip>
<pb-tip values="maybenot">Ah, damn.</pb-tip>
<pb-tip values="understand"><div id="test-custom-html">Really?</div></pb-tip>
<pb-tip values='["yes"]'>Great!</pb-tip>
<pb-tip values='["maybenot"]'>Ah, damn.</pb-tip>
<pb-tip values='["understand"]'><div id="test-custom-html">Really?</div></pb-tip>
</pb-mcq>
</problem-builder>
......@@ -132,7 +132,7 @@ class TipBlock(StudioEditableXBlockMixin, XBlock):
"""
block = runtime.construct_xblock_from_class(cls, keys)
block.values = [unicode(val).strip() for val in node.get('values', '').split(',')]
block.values = cls.values.from_string(node.get('values', '[]'))
block.width = node.get('width', '')
block.height = node.get('height', '')
......
......@@ -57,8 +57,7 @@ class TestUpgrade(unittest.TestCase):
@XBlock.register_temp_plugin(MentoringBlock, "mentoring")
def test_xml_upgrade(self, file_name):
"""
Convert a v1 mentoring block to v2 and then compare the resulting block to a
pre-converted one.
Convert a v1 mentoring block to v2 and then compare the resulting block to a pre-converted one.
"""
with open("{}/{}_old.xml".format(xml_path, file_name)) as xmlfile:
temp_node = etree.parse(xmlfile).getroot()
......
......@@ -6,30 +6,30 @@
<p>Please answer the questions below.</p>
</html>
<pb-answer name="goal" question="What is your goal?"/>
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
<pb-mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices='["yes"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes">Great!</pb-tip>
<pb-tip values="maybenot">Ah, damn.</pb-tip>
<pb-tip values="understand">
<pb-tip values='["yes"]'>Great!</pb-tip>
<pb-tip values='["maybenot"]'>Ah, damn.</pb-tip>
<pb-tip values='["understand"]'>
<div id="test-custom-html">Really?</div>
</pb-tip>
</pb-mcq>
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How much do you rate this MCQ?" correct_choices="4,5">
<pb-rating name="mcq_1_2" low="Not good at all" high="Extremely good" question="How much do you rate this MCQ?" correct_choices='["4","5"]'>
<pb-choice value="notwant">I don't want to rate it</pb-choice>
<pb-tip values="4,5">I love good grades.</pb-tip>
<pb-tip values="1,2,3">Will do better next time...</pb-tip>
<pb-tip values="notwant">Your loss!</pb-tip>
<pb-tip values='["4","5"]'>I love good grades.</pb-tip>
<pb-tip values='["1","2","3"]'>Will do better next time...</pb-tip>
<pb-tip values='["notwant"]'>Your loss!</pb-tip>
</pb-rating>
<pb-mrq name="mrq_1_1" question="What do you like in this MRQ?" message="Thank you for answering!" required_choices="gracefulness,elegance,beauty">
<pb-mrq name="mrq_1_1" question="What do you like in this MRQ?" message="Thank you for answering!" required_choices='["gracefulness","elegance","beauty"]'>
<pb-choice value="elegance">Its elegance</pb-choice>
<pb-choice value="beauty">Its beauty</pb-choice>
<pb-choice value="gracefulness">Its gracefulness</pb-choice>
<pb-choice value="bugs">Its bugs</pb-choice>
<pb-tip values="gracefulness">This MRQ is indeed very graceful</pb-tip>
<pb-tip values="elegance,beauty">This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values="bugs">Nah, there isn't any!</pb-tip>
<pb-tip values='["gracefulness"]'>This MRQ is indeed very graceful</pb-tip>
<pb-tip values='["elegance","beauty"]'>This is something everyone has to like about this MRQ</pb-tip>
<pb-tip values='["bugs"]'>Nah, there isn't any!</pb-tip>
</pb-mrq>
<pb-message type="completed">
<p>Congratulations!</p>
......
......@@ -4,31 +4,31 @@
<p>Now, let's make sure your frog meets the criteria for a strong column 1. Here is your frog:</p>
</html>
<pb-answer-recap name="improvement-frog"/>
<pb-mcq name="frog-happy" question="Is this frog happy for you?" correct_choices="yes,maybenot,understand">
<pb-mcq name="frog-happy" question="Is this frog happy for you?" correct_choices='["yes","maybenot","understand"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip width="350" height="100" values="yes">Great. Your frog should be happy for you.</pb-tip>
<pb-tip values="maybenot">In the end, all the feedback you have gotten from others should not lead you to choose a frog that does not also feel happy and important to you.</pb-tip>
<pb-tip values="understand">
<pb-tip width="350" height="100" values='["yes"]'>Great. Your frog should be happy for you.</pb-tip>
<pb-tip values='["maybenot"]'>In the end, all the feedback you have gotten from others should not lead you to choose a frog that does not also feel happy and important to you.</pb-tip>
<pb-tip values='["understand"]'>
<p>If a frog is <span class="italic">happy for you</span>, that means it is a frog that you genuinely feel in your own heart to be something that you want to improve. What is in your heart?</p>
</pb-tip>
</pb-mcq>
<pb-mcq name="frog-implicate" question="Does this frog implicate you?" correct_choices="yes,maybenot,understand">
<pb-mcq name="frog-implicate" question="Does this frog implicate you?" correct_choices='["yes","maybenot","understand"]'>
<pb-choice value="yes">Yes</pb-choice>
<pb-choice value="maybenot">Maybe not</pb-choice>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="yes">Great. Your frog should implicate you.</pb-tip>
<pb-tip values="maybenot">
<pb-tip values='["yes"]'>Great. Your frog should implicate you.</pb-tip>
<pb-tip values='["maybenot"]'>
<p>Since the Trial of Uruk-Shan focuses on your own growth and change, it is important to be clear about the ways <span class="bold">you</span> are hoping to change and improve.</p>
</pb-tip>
<pb-tip values="understand">Your frog implicates you if it is clear that you must get better at something. Your frog should focus on something you can control.</pb-tip>
<pb-tip values='["understand"]'>Your frog implicates you if it is clear that you must get better at something. Your frog should focus on something you can control.</pb-tip>
</pb-mcq>
<pb-rating name="frog-important" low="Not at all important to me" high="Very important to me" question="How important is it to you?" correct_choices="4,5,1,2,3,understand">
<pb-rating name="frog-important" low="Not at all important to me" high="Very important to me" question="How important is it to you?" correct_choices='["4","5","1","2","3","understand"]'>
<pb-choice value="understand">I don't understand</pb-choice>
<pb-tip values="4,5">Great!</pb-tip>
<pb-tip values="1,2,3">The Trial of Uruk-Shan helps you uncover some of the core beliefs and assumptions you have held that are preventing you from making change.</pb-tip>
<pb-tip values="understand">A frog is important if it is one that could make a big difference in helping you reach your frogs in your work life or your personal life (or both).</pb-tip>
<pb-tip values='["4","5"]'>Great!</pb-tip>
<pb-tip values='["1","2","3"]'>The Trial of Uruk-Shan helps you uncover some of the core beliefs and assumptions you have held that are preventing you from making change.</pb-tip>
<pb-tip values='["understand"]'>A frog is important if it is one that could make a big difference in helping you reach your frogs in your work life or your personal life (or both).</pb-tip>
</pb-rating>
<pb-message type="completed">
Great! You have indicated that you have chosen a frog that is happy for you, implicates you, has room for improvement, and is important to you. You are now ready to move onto the next step.
......
......@@ -21,6 +21,7 @@
Each class in this file represents a change made to the XML schema between v1 and v2.
"""
from lxml import etree
import json
import warnings
......@@ -292,6 +293,22 @@ class SharedHeaderToHTML(Change):
self.node.tag = "html"
class CommaSeparatedListToJson(Change):
APPLY_TO_ATTRIBUTES = ("values", "correct_choices", "required_choices", "ignored_choices")
def _convert_value(self, raw_value):
return json.dumps([unicode(val).strip() for val in raw_value.split(',')])
@staticmethod
def applies_to(node):
return node.tag in ("pb-tip", "pb-mrq", "pb-mcq", "pb-rating")
def apply(self):
for attribute in self.APPLY_TO_ATTRIBUTES:
if attribute in self.node.attrib:
self.node.attrib[attribute] = self._convert_value(self.node.attrib[attribute])
# An *ordered* list of all XML schema changes:
xml_changes = (
RenameMentoringTag,
......@@ -307,6 +324,7 @@ xml_changes = (
QuestionSubmitMessageToField,
TipChanges,
SharedHeaderToHTML,
CommaSeparatedListToJson,
)
......
-e git+https://github.com/edx/XBlock.git@496d3cb9aca1d9e0a18b0f5e73c7bede824e465f#egg=XBlock
\ No newline at end of file
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