Commit 0b04fbd1 by Jonathan Piacenti

Addressed review notes.

parent 725ff4cb
...@@ -28,7 +28,6 @@ from xblock.exceptions import JsonHandlerError ...@@ -28,7 +28,6 @@ from xblock.exceptions import JsonHandlerError
from xblock.fields import Scope, String, Dict from xblock.fields import Scope, String, Dict
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader from xblockutils.resources import ResourceLoader
from problem_builder.sub_api import SubmittingXBlockMixin
loader = ResourceLoader(__name__) loader = ResourceLoader(__name__)
...@@ -40,7 +39,7 @@ def _(text): ...@@ -40,7 +39,7 @@ def _(text):
@XBlock.needs("i18n") @XBlock.needs("i18n")
@XBlock.wants('user') @XBlock.wants('user')
class DataExportBlock(SubmittingXBlockMixin, XBlock): class DataExportBlock(XBlock):
""" """
DataExportBlock: An XBlock for instructors to export student answers from a course. DataExportBlock: An XBlock for instructors to export student answers from a course.
...@@ -162,12 +161,11 @@ class DataExportBlock(SubmittingXBlockMixin, XBlock): ...@@ -162,12 +161,11 @@ class DataExportBlock(SubmittingXBlockMixin, XBlock):
username = data.get('username', None) username = data.get('username', None)
root_block_id = data.get('root_block_id', None) root_block_id = data.get('root_block_id', None)
if not root_block_id: if not root_block_id:
root_block_id = unicode(self.scope_ids.usage_id) root_block_id = self.scope_ids.usage_id
# Block ID not in workbench runtime.
root_block_id = unicode(getattr(root_block_id, 'block_id', root_block_id))
get_root = True get_root = True
else: else:
from xmodule.modulestore.django import modulestore
block = modulestore().get_items(self.runtime.course_id, qualifiers={'name': root_block_id}, depth=0)[0]
root_block_id = unicode(block.location)
get_root = False get_root = False
user_service = self.runtime.service(self, 'user') user_service = self.runtime.service(self, 'user')
if not self.user_is_staff(): if not self.user_is_staff():
...@@ -182,7 +180,12 @@ class DataExportBlock(SubmittingXBlockMixin, XBlock): ...@@ -182,7 +180,12 @@ class DataExportBlock(SubmittingXBlockMixin, XBlock):
self.raise_error(404, _("Could not find the specified username.")) self.raise_error(404, _("Could not find the specified username."))
async_result = export_data_task.delay( async_result = export_data_task.delay(
root_block_id, block_types, user_id, get_root=get_root, # course_id not available in workbench.
unicode(getattr(self.runtime, 'course_id', 'course_id')),
root_block_id,
block_types,
user_id,
get_root=get_root,
) )
if async_result.ready(): if async_result.ready():
# In development mode, the task may have executed synchronously. # In development mode, the task may have executed synchronously.
......
.data-export-options {
margin-top: 2em;
}
.data-export-actions button { .data-export-actions button {
display: none; display: none;
} }
.data-export-status { .data-export-status {
height: 8em; height: 8em;
} }
.data-export-field {
margin-top: .5em;
margin-bottom: .5em;
}
.data-export-field label span {
font-weight: bold;
}
.data-export-helptext {
font-size: 75%;
}
.data-export-field-container {
margin-bottom: 1em;
}
\ No newline at end of file
...@@ -11,7 +11,7 @@ function DataExportBlock(runtime, element) { ...@@ -11,7 +11,7 @@ function DataExportBlock(runtime, element) {
var $downloadButton = $element.find('.data-export-download'); var $downloadButton = $element.find('.data-export-download');
var $deleteButton = $element.find('.data-export-delete'); var $deleteButton = $element.find('.data-export-delete');
var $blockTypes = $element.find("select[name='block_types']"); var $blockTypes = $element.find("select[name='block_types']");
var $rootBlockIds = $element.find("input[name='root_block_id']"); var $rootBlockId = $element.find("input[name='root_block_id']");
var $username = $element.find("input[name='username']"); var $username = $element.find("input[name='username']");
var status; var status;
...@@ -102,11 +102,11 @@ function DataExportBlock(runtime, element) { ...@@ -102,11 +102,11 @@ function DataExportBlock(runtime, element) {
$button.on('click', function() { $button.on('click', function() {
var data; var data;
if (form_submit) { if (form_submit) {
data = {}; data = {
data['block_types'] = $blockTypes.val(); block_types: $blockTypes.val(),
data['block_types'] = $blockTypes.val(); root_block_id: $rootBlockId.val(),
data['root_block_id'] = $rootBlockIds.val(); username: $username.val()
data['username'] = $username.val(); };
data = JSON.stringify(data); data = JSON.stringify(data);
} else { } else {
data = '{}'; data = '{}';
......
...@@ -7,7 +7,7 @@ from celery.task import task ...@@ -7,7 +7,7 @@ from celery.task import task
from celery.utils.log import get_task_logger from celery.utils.log import get_task_logger
from instructor_task.models import ReportStore from instructor_task.models import ReportStore
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey, CourseKey
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from .mcq import MCQBlock, RatingBlock from .mcq import MCQBlock, RatingBlock
...@@ -18,7 +18,7 @@ logger = get_task_logger(__name__) ...@@ -18,7 +18,7 @@ logger = get_task_logger(__name__)
@task() @task()
def export_data(source_block_id_str, block_types, user_id, get_root=True): def export_data(course_id, source_block_id_str, block_types, user_id, get_root=True):
""" """
Exports student answers to all MCQ questions to a CSV file. Exports student answers to all MCQ questions to a CSV file.
""" """
...@@ -26,9 +26,10 @@ def export_data(source_block_id_str, block_types, user_id, get_root=True): ...@@ -26,9 +26,10 @@ def export_data(source_block_id_str, block_types, user_id, get_root=True):
logger.debug("Beginning data export") logger.debug("Beginning data export")
try: try:
block_key = UsageKey.from_string(source_block_id_str) course_key = CourseKey.from_string(course_id)
src_block = modulestore().get_item(block_key) src_block = modulestore().get_items(course_key, qualifiers={'name': source_block_id_str}, depth=0)[0]
course_key = src_block.scope_ids.usage_id.course_key.replace(branch=None, version_guid=None) if src_block is None:
raise InvalidKeyError
except InvalidKeyError: except InvalidKeyError:
raise ValueError("Could not find the specified Block ID.") raise ValueError("Could not find the specified Block ID.")
course_key_str = unicode(course_key) course_key_str = unicode(course_key)
...@@ -44,7 +45,7 @@ def export_data(source_block_id_str, block_types, user_id, get_root=True): ...@@ -44,7 +45,7 @@ def export_data(source_block_id_str, block_types, user_id, get_root=True):
if not block_types: if not block_types:
block_types = tuple(type_map.values()) block_types = tuple(type_map.values())
else: else:
block_types = tuple([type_map[class_name] for class_name in block_types]) block_types = tuple(type_map[class_name] for class_name in block_types)
# Build an ordered list of blocks to include in the export - each block is a column in the CSV file # Build an ordered list of blocks to include in the export - each block is a column in the CSV file
blocks_to_include = [] blocks_to_include = []
......
...@@ -11,10 +11,11 @@ ...@@ -11,10 +11,11 @@
<button class="data-export-delete">{% trans "Delete result" %}</button> <button class="data-export-delete">{% trans "Delete result" %}</button>
</div> </div>
<div class="export-options"> <div class="data-export-options">
<div> <div class="data-export-field-container">
<div class="data-export-field">
<label> <label>
{% trans "Select which blocks to filter by (selecting none will grab all types):" %} <span>{% trans "Problem types:" %}</span>
<select multiple name="block_types"> <select multiple name="block_types">
{% for label, value in block_choices.items %} {% for label, value in block_choices.items %}
<option value="{{value}}">{{label}}</option> <option value="{{value}}">{{label}}</option>
...@@ -22,18 +23,32 @@ ...@@ -22,18 +23,32 @@
</select> </select>
</label> </label>
</div> </div>
<div> <div class="data-export-helptext">
{% trans "Select which types of problem to include (selecting none will grab all types)" %}
</div>
</div>
<div class="data-export-field-container">
<div class="data-export-field">
<label> <label>
{% trans "Input the ID of a chapter, section, or unit if you wish to only get results under it. Otherwise, it will grab all results for the course." %} <span>{% trans "Root block ID:" %}</span>
<input type="text" name="root_block_id" /> <input type="text" name="root_block_id" />
</label> </label>
</div> </div>
<div> <div class="data-export-helptext">
{% trans "Input the ID of a chapter, section, or unit if you wish to only get results under it. Otherwise, it will grab all results for the course." %}
</div>
</div>
<div class="data-export-field-container">
<div class="data-export-field">
<label> <label>
{% trans "Input the username of a student if you wish to query for a specific one. Otherwise, it will grab all results for all students." %} <span>{% trans "Username:" %}</span>
<input type="text" name="username" /> <input type="text" name="username" />
</label> </label>
</div> </div>
<div class="data-export-helptext">
{% trans "Input the username of a student if you wish to query for a specific one. Otherwise, it will grab all results for all students." %}
</div>
</div>
</div> </div>
<div class="data-export-actions"> <div class="data-export-actions">
<button class="data-export-start">{% trans "Start a new export" %}</button> <button class="data-export-start">{% trans "Start a new export" %}</button>
......
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