Unverified Commit 90fa622d by Eric Fischer Committed by GitHub

Merge pull request #1073 from edx/efischer/group_access_export

Efischer/group access export
parents 6f9bf909 fe46522c
...@@ -2,7 +2,18 @@ ...@@ -2,7 +2,18 @@
Fields and methods used by the LMS and Studio. Fields and methods used by the LMS and Studio.
""" """
from xblock.fields import DateTime, Float, Scope, String from xblock.fields import DateTime, Dict, Float, Scope, String
class GroupAccessDict(Dict):
"""Special Dict class for serializing the group_access field"""
def from_json(self, access_dict):
if access_dict is not None:
return {int(k): access_dict[k] for k in access_dict}
def to_json(self, access_dict):
if access_dict is not None:
return {unicode(k): access_dict[k] for k in access_dict}
class LmsCompatibilityMixin(object): class LmsCompatibilityMixin(object):
...@@ -35,6 +46,18 @@ class LmsCompatibilityMixin(object): ...@@ -35,6 +46,18 @@ class LmsCompatibilityMixin(object):
scope=Scope.settings scope=Scope.settings
) )
group_access = GroupAccessDict(
help=(
"A dictionary that maps which groups can be shown this block. The keys "
"are group configuration ids and the values are a list of group IDs. "
"If there is no key for a group configuration or if the set of group IDs "
"is empty then the block is considered visible to all. Note that this "
"field is ignored if the block is visible_to_staff_only."
),
default={},
scope=Scope.settings,
)
icon_class = "problem" icon_class = "problem"
def has_dynamic_children(self): def has_dynamic_children(self):
......
...@@ -704,6 +704,7 @@ class OpenAssessmentBlock(MessageMixin, ...@@ -704,6 +704,7 @@ class OpenAssessmentBlock(MessageMixin,
block.white_listed_file_types_string = config['white_listed_file_types'] block.white_listed_file_types_string = config['white_listed_file_types']
block.allow_latex = config['allow_latex'] block.allow_latex = config['allow_latex']
block.leaderboard_show = config['leaderboard_show'] block.leaderboard_show = config['leaderboard_show']
block.group_access = config['group_access']
return block return block
......
<openassessment text_response="required" file_upload_response=""> <openassessment text_response="required" file_upload_response="" group_access="{&quot;381451918&quot;: [1179773159]}">
<title>Open Assessment Test</title> <title>Open Assessment Test</title>
<prompts> <prompts>
<prompt> <prompt>
......
...@@ -79,6 +79,87 @@ ...@@ -79,6 +79,87 @@
] ]
}, },
"group_access": {
"group_access" : "{\"381451918\": [1179773159]}",
"title": "Foo",
"text_response": "required",
"file_upload_response": null,
"prompt": "Test prompt",
"rubric_feedback_prompt": "Test Feedback Prompt",
"rubric_feedback_default_text": "Test default text...",
"start": null,
"due": null,
"submission_start": null,
"submission_due": null,
"file_upload_type": null,
"criteria": [
{
"order_num": 0,
"name": "Test criterion",
"label": "Test criterion label",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"label": "No label",
"name": "No",
"explanation": "No explanation"
},
{
"order_num": 1,
"points": 2,
"label": "Yes label",
"name": "Yes",
"explanation": "Yes explanation"
}
]
}
],
"assessments": [
{
"name": "peer-assessment",
"start": "2014-02-27T09:46:28",
"due": "2014-03-01T00:00:00",
"must_grade": 5,
"must_be_graded_by": 3
},
{
"name": "self-assessment",
"start": "2014-04-01T00:00:00",
"due": "2014-06-01T00:00:00"
},
{
"name": "staff-assessment",
"required": false
}
],
"expected_xml": [
"<openassessment text_response=\"required\" group_access=\"{&quot;381451918&quot;: [1179773159]}\">",
"<title>Foo</title>",
"<assessments>",
"<assessment name=\"peer-assessment\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\" must_grade=\"5\" must_be_graded_by=\"3\" />",
"<assessment name=\"self-assessment\" start=\"2014-04-01T00:00:00\" due=\"2014-06-01T00:00:00\" />",
"<assessment name=\"staff-assessment\" required=\"False\" />",
"</assessments>",
"<prompts>",
"<prompt><description>Test prompt</description></prompt>",
"</prompts>",
"<rubric>",
"<criterion>",
"<name>Test criterion</name>",
"<label>Test criterion label</label>",
"<prompt>Test criterion prompt</prompt>",
"<option points=\"0\"><name>No</name><label>No label</label><explanation>No explanation</explanation></option>",
"<option points=\"2\"><name>Yes</name><label>Yes label</label><explanation>Yes explanation</explanation></option>",
"</criterion>",
"<feedbackprompt>Test Feedback Prompt</feedbackprompt>",
"<feedback_default_text>Test default text...</feedback_default_text>",
"</rubric>",
"</openassessment>"
]
},
"promptless": { "promptless": {
"title": "Foo", "title": "Foo",
"text_response": "required", "text_response": "required",
......
...@@ -6,6 +6,7 @@ import copy ...@@ -6,6 +6,7 @@ import copy
import dateutil.parser import dateutil.parser
import ddt import ddt
import json
import lxml.etree as etree import lxml.etree as etree
import mock import mock
import pytz import pytz
...@@ -131,6 +132,7 @@ class TestSerializeContent(TestCase): ...@@ -131,6 +132,7 @@ class TestSerializeContent(TestCase):
self.oa_block.white_listed_file_types = data.get('white_listed_file_types') self.oa_block.white_listed_file_types = data.get('white_listed_file_types')
self.oa_block.allow_latex = data.get('allow_latex') self.oa_block.allow_latex = data.get('allow_latex')
self.oa_block.leaderboard_show = data.get('leaderboard_show', 0) self.oa_block.leaderboard_show = data.get('leaderboard_show', 0)
self.oa_block.group_access = json.loads(data.get('group_access', "{}"))
@ddt.file_data('data/serialize.json') @ddt.file_data('data/serialize.json')
def test_serialize(self, data): def test_serialize(self, data):
......
...@@ -3,6 +3,7 @@ Serialize and deserialize OpenAssessment XBlock content to/from XML. ...@@ -3,6 +3,7 @@ Serialize and deserialize OpenAssessment XBlock content to/from XML.
""" """
from uuid import uuid4 as uuid from uuid import uuid4 as uuid
import logging import logging
import json
import dateutil.parser import dateutil.parser
import defusedxml.ElementTree as safe_etree import defusedxml.ElementTree as safe_etree
...@@ -10,7 +11,7 @@ import lxml.etree as etree ...@@ -10,7 +11,7 @@ import lxml.etree as etree
import pytz import pytz
from openassessment.xblock.data_conversion import update_assessments_format from openassessment.xblock.data_conversion import update_assessments_format
from openassessment.xblock.lms_mixin import GroupAccessDict
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -721,6 +722,10 @@ def serialize_content_to_xml(oa_block, root): ...@@ -721,6 +722,10 @@ def serialize_content_to_xml(oa_block, root):
if oa_block.allow_latex is not None: if oa_block.allow_latex is not None:
root.set('allow_latex', unicode(oa_block.allow_latex)) root.set('allow_latex', unicode(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 # Open assessment displayed title
title = etree.SubElement(root, 'title') title = etree.SubElement(root, 'title')
title.text = unicode(oa_block.title) title.text = unicode(oa_block.title)
...@@ -867,6 +872,10 @@ def parse_from_xml(root): ...@@ -867,6 +872,10 @@ def parse_from_xml(root):
if 'allow_latex' in root.attrib: if 'allow_latex' in root.attrib:
allow_latex = _parse_boolean(unicode(root.attrib['allow_latex'])) allow_latex = _parse_boolean(unicode(root.attrib['allow_latex']))
group_access = {}
if 'group_access' in root.attrib:
group_access = GroupAccessDict().from_json(json.loads(root.attrib['group_access']))
# Retrieve the title # Retrieve the title
title_el = root.find('title') title_el = root.find('title')
if title_el is None: if title_el is None:
...@@ -914,6 +923,7 @@ def parse_from_xml(root): ...@@ -914,6 +923,7 @@ def parse_from_xml(root):
'file_upload_type': file_upload_type, 'file_upload_type': file_upload_type,
'white_listed_file_types': white_listed_file_types, 'white_listed_file_types': white_listed_file_types,
'allow_latex': allow_latex, 'allow_latex': allow_latex,
'group_access': group_access,
'leaderboard_show': leaderboard_show 'leaderboard_show': leaderboard_show
} }
......
...@@ -34,7 +34,7 @@ def load_requirements(*requirements_paths): ...@@ -34,7 +34,7 @@ def load_requirements(*requirements_paths):
setup( setup(
name='ora2', name='ora2',
version='2.1.9', version='2.1.10',
author='edX', author='edX',
url='http://github.com/edx/edx-ora2', url='http://github.com/edx/edx-ora2',
description='edx-ora2', description='edx-ora2',
......
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