Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b74d5d1
Rename "Data Export" block to "Student Answers Dashboard" (user-facing
itsjeyd Jul 3, 2015
28cebfd
Rename files that implement data export to match new name of XBlock.
itsjeyd Jul 3, 2015
caf0714
Update Student Answers Dashboard key for advanced modules.
itsjeyd Jul 6, 2015
a199b82
Display data to be exported in Student Answers Dashboard XBlock.
itsjeyd Jul 6, 2015
777a9a4
Make contents of CSV file match results displayed on page.
itsjeyd Jul 6, 2015
b9ebeee
Empty result table before adding new results.
itsjeyd Jul 6, 2015
3e4edf4
Hide results table if no data is available.
itsjeyd Jul 6, 2015
e0f62ff
Allow instructors to filter answers by content.
itsjeyd Jul 7, 2015
f463897
Rework UI of Student Answers Dashboard.
itsjeyd Jul 7, 2015
96496aa
Update and extend integration tests for problem-builder.
itsjeyd Jul 8, 2015
d1f2ef6
Paginate export results on the client.
itsjeyd Jul 13, 2015
56dc273
Make existing problem-builder tests pass.
itsjeyd Jul 14, 2015
6ee520a
Extend existing problem-builder tests.
itsjeyd Jul 14, 2015
c7fd48a
Add integration tests for pagination.
itsjeyd Jul 14, 2015
f1e8f6a
Include full MIT license for third-party libraries backbone.paginator,
itsjeyd Jul 14, 2015
b8050f2
Fix pep8 violations.
itsjeyd Jul 14, 2015
9fe9f34
Fix pylint violations.
itsjeyd Jul 14, 2015
01e30ce
Address review comments.
itsjeyd Jul 15, 2015
f57db13
Fix "ImportError: 'module' object has no attribute 'DataExportBlock'".
itsjeyd Jul 15, 2015
dae27b3
Cache answer choices for MCQs.
itsjeyd Jul 16, 2015
90e0b0e
Rename "Student Answers Dashboard" to "Instructor Tool".
itsjeyd Jul 16, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions LICENSE.MIT
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
------------------------------------------------------------------------------
This license applies to the following third-party libraries included
in this repository:

- backbone.paginator
- Backbone.js
- Underscore.js

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itsjeyd Is it necessary to include these? Backbone and Underscore should both be available in Studio and the LMS:

RequireJS.require(['backbone', 'underscore'], function(backbone, _) {
    console.log(backbone.VERSION, _.VERSION);
});
> 1.0.0, 1.4.4

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bradenmacdonald It's not necessary to include Backbone and Underscore when running problem-builder inside LMS/Studio, I just checked. However, tests fail horribly without them. Is there a way to conditionally include them, i.e., load them iff problem-builder is running as a standalone XBlock?

------------------------------------------------------------------------------

The MIT License (MIT)

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
2 changes: 1 addition & 1 deletion problem_builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .answer import AnswerBlock, AnswerRecapBlock
from .choice import ChoiceBlock
from .dashboard import DashboardBlock
from .data_export import DataExportBlock
from .instructor_tool import InstructorToolBlock
from .mcq import MCQBlock, RatingBlock
from .mrq import MRQBlock
from .message import MentoringMessageBlock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# "AGPLv3". If not, see <http://www.gnu.org/licenses/>.
#
"""
Data Export: An XBlock for instructors to export student answers from a course.
Instructor Tool: An XBlock for instructors to export student answers from a course.

All processing is done offline.
"""
Expand All @@ -39,16 +39,16 @@ def _(text):

@XBlock.needs("i18n")
@XBlock.wants('user')
class DataExportBlock(XBlock):
class InstructorToolBlock(XBlock):
"""
DataExportBlock: An XBlock for instructors to export student answers from a course.
InstructorToolBlock: An XBlock for instructors to export student answers from a course.

All processing is done offline.
"""
display_name = String(
display_name=_("Title (Display name)"),
help=_("Title to display"),
default=_("Data Export"),
default=_("Instructor Tool"),
scope=Scope.settings
)
active_export_task_id = String(
Expand All @@ -67,13 +67,13 @@ class DataExportBlock(XBlock):

@property
def display_name_with_default(self):
return "Data Export"
return "Instructor Tool"

def author_view(self, context=None):
""" Studio View """
# Warn the user that this block will only work from the LMS. (Since the CMS uses
# different celery queues; our task listener is waiting for tasks on the LMS queue)
return Fragment(u'<p>Data Export Block</p><p>This block only works from the LMS.</p>')
return Fragment(u'<p>Instructor Tool Block</p><p>This block only works from the LMS.</p>')

def check_pending_export(self):
"""
Expand Down Expand Up @@ -105,12 +105,17 @@ def student_view(self, context=None):
_('Rating Question'): 'RatingBlock',
_('Long Answer'): 'AnswerBlock',
}
html = loader.render_template('templates/html/data_export.html', {'block_choices': block_choices})
html = loader.render_template(
'templates/html/instructor_tool.html',
{'block_choices': block_choices}
)
fragment = Fragment(html)
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/data_export.css'))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/data_export.js'))
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/instructor_tool.css'))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/instructor_tool.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/underscore-min.js'))
fragment.initialize_js('DataExportBlock')
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/backbone-min.js'))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/backbone.paginator.min.js'))
fragment.initialize_js('InstructorToolBlock')
return fragment

@property
Expand Down Expand Up @@ -160,34 +165,45 @@ def start_export(self, data, suffix=''):
block_types = data.get('block_types', None)
username = data.get('username', None)
root_block_id = data.get('root_block_id', None)
if not root_block_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
match_string = data.get('match_string', None)

# Process user-submitted data
if block_types == 'all':
block_types = []
else:
get_root = False
block_types = [block_types]

user_service = self.runtime.service(self, 'user')
if not self.user_is_staff():
return {'error': 'permission denied'}
from .tasks import export_data as export_data_task # Import here since this is edX LMS specific
self._delete_export()
# Make sure we nail down our state before sending off an asynchronous task.
self.save()
if not username:
user_id = None
else:
user_id = user_service.get_anonymous_user_id(username, unicode(self.runtime.course_id))
if user_id is None:
self.raise_error(404, _("Could not find the specified username."))

if not root_block_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
else:
get_root = False

# Launch task
from .tasks import export_data as export_data_task # Import here since this is edX LMS specific
self._delete_export()
# Make sure we nail down our state before sending off an asynchronous task.
self.save()
async_result = export_data_task.delay(
# 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,
match_string,
get_root=get_root
)
if async_result.ready():
# In development mode, the task may have executed synchronously.
Expand Down
22 changes: 0 additions & 22 deletions problem_builder/public/css/data_export.css

This file was deleted.

68 changes: 68 additions & 0 deletions problem_builder/public/css/instructor_tool.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.data-export-options, .data-export-results, .data-export-status {
margin-top: 2em;
}
.data-export-options, .data-export-results table {
border: 2px solid #999;
}
.data-export-options, .data-export-results thead {
background-color: #ddd;
}
.data-export-options {
display: table;
padding: 1em;
}
.data-export-header, .data-export-row {
display: table-row;
}
.data-export-header h3, .data-export-results thead {
font-weight: bold;
}
.data-export-header h3 {
margin-top: 0px;
margin-bottom: 10px;
}
.data-export-field-container, .data-export-options .data-export-actions {
display: table-cell;
padding-left: 1em;
}
.data-export-field {
margin-top: .5em;
margin-bottom: .5em;
}
.data-export-field label span {
padding-right: .5em;
vertical-align: middle;
}
.data-export-field input, .data-export-field select {
max-width: 60%;
float: right;
}
.data-export-results, .data-export-download, .data-export-cancel, .data-export-delete {
display: none;
}
.data-export-results table {
width: 100%;
margin-top: 1em;
}
.data-export-results thead {
border-bottom: 2px solid #999;
}
.data-export-results td {
border-left: 1px solid #999;
padding: 5px;
}
.data-export-results tr:nth-child(odd) {
background-color: #eee;
}
.data-export-info p {
font-size: 75%;
}
.data-export-status {
margin-bottom: 1em;
}
.data-export-status i {
font-size: 3em;
}
.data-export-actions {
text-align: right;
}
136 changes: 0 additions & 136 deletions problem_builder/public/js/data_export.js

This file was deleted.

Loading