Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-ora2
Commits
229b719b
Commit
229b719b
authored
Feb 24, 2014
by
Stephen Sanchez
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #42 from edx/sanchez/base_template_cleanup
Some additional doc around all the functions in the front end.
parents
b491ad87
3cd1bdb0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
194 additions
and
63 deletions
+194
-63
apps/openassessment/xblock/openassessmentblock.py
+54
-5
apps/openassessment/xblock/peer_assessment_mixin.py
+32
-0
apps/openassessment/xblock/self_assessment_mixin.py
+11
-0
apps/openassessment/xblock/static/js/src/oa_assessment.js
+0
-48
apps/openassessment/xblock/submission_mixin.py
+65
-10
apps/openassessment/xblock/ui_models.py
+32
-0
No files found.
apps/openassessment/xblock/openassessmentblock.py
View file @
229b719b
...
...
@@ -181,7 +181,7 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
)
def
get_xblock_trace
(
self
):
"""Uniquely identify this
xb
lock by context.
"""Uniquely identify this
XB
lock by context.
Every XBlock has a scope_ids, which is a NamedTuple describing
important contextual information. Per @nedbat, the usage_id attribute
...
...
@@ -189,13 +189,19 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
identifies this student. With the two of them, we can trace all the
interactions emanating from this interaction.
Useful for logging, debugging, and uniqueification."""
Useful for logging, debugging, and uniqueification.
"""
return
self
.
scope_ids
.
usage_id
,
self
.
scope_ids
.
user_id
def
get_student_item_dict
(
self
):
"""Create a student_item_dict from our surrounding context.
See also: submissions.api for details.
Returns:
(dict): The student item associated with this XBlock instance. This
includes the student id, item id, and course id.
"""
item_id
,
student_id
=
self
.
get_xblock_trace
()
student_item_dict
=
dict
(
...
...
@@ -208,10 +214,20 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
def
student_view
(
self
,
context
=
None
):
"""The main view of OpenAssessmentBlock, displayed when viewing courses.
The main view which displays the general layout for Open Ended
Assessment Questions. The contents of the XBlock are determined
dynamically based on the assessment workflow configured by the author.
Args:
context: Not used for this view.
Returns:
(Fragment): The HTML Fragment for this XBlock, which determines the
general frame of the Open Ended Assessment Question.
"""
trace
=
self
.
get_xblock_trace
()
student_item_dict
=
self
.
get_student_item_dict
()
grade_state
=
self
.
get_grade_state
()
# All data we intend to pass to the front end.
...
...
@@ -235,7 +251,12 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
@staticmethod
def
workbench_scenarios
():
"""A canned scenario for display in the workbench."""
"""A canned scenario for display in the workbench.
These scenarios are only intended to be used for Workbench XBlock
Development.
"""
return
[
(
"OpenAssessmentBlock Poverty Rubric"
,
...
...
@@ -249,11 +270,28 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
@staticmethod
def
studio_view
(
context
=
None
):
"""Determines how the XBlock is rendered for editing in Studio.
Displays the section where Editing can occur within Studio to modify
this XBlock instance.
Args:
context: Not actively used for this view.
Returns:
(Fragment): An HTML fragment for editing the configuration of this
XBlock.
"""
return
Fragment
(
u"<div>Edit the XBlock.</div>"
)
@classmethod
def
parse_xml
(
cls
,
node
,
runtime
,
keys
,
id_generator
):
"""Instantiate xblock object from runtime XML definition."""
"""Instantiate XBlock object from runtime XML definition.
Inherited by XBlock core.
"""
def
unknown_handler
(
block
,
child
):
"""Recursively embed xblocks for nodes we don't recognize"""
block
.
runtime
.
add_node_as_child
(
block
,
child
,
id_generator
)
...
...
@@ -280,6 +318,17 @@ class OpenAssessmentBlock(XBlock, SubmissionMixin, PeerAssessmentMixin, SelfAsse
Given the name of an assessment module, find it in the list of
configured modules, and ask for its rendered HTML.
Args:
path (str): The path to the template used to render this HTML
section.
context_dict (dict): A dictionary of context variables used to
populate this HTML section.
Returns:
(Response): A Response Object with the generated HTML fragment. This
is intended for AJAX calls to load dynamically into a larger
document.
"""
if
not
context_dict
:
context_dict
=
{}
...
...
apps/openassessment/xblock/peer_assessment_mixin.py
View file @
229b719b
...
...
@@ -4,10 +4,35 @@ from openassessment.peer.api import PeerAssessmentWorkflowError
class
PeerAssessmentMixin
(
object
):
"""The Peer Assessment Mixin for all Peer Functionality.
Abstracts all functionality and handlers associated with Peer Assessment.
All Peer Assessment API calls should be contained without this Mixin as
well.
PeerAssessmentMixin is a Mixin for the OpenAssessmentBlock. Functions in
the PeerAssessmentMixin call into the OpenAssessmentBlock functions and
will not work outside of OpenAssessmentBlock
"""
@XBlock.json_handler
def
assess
(
self
,
data
,
suffix
=
''
):
"""Place an assessment into OpenAssessment system
Assess a Peer Submission. Performs basic workflow validation to ensure
that an assessment can be performed as this time.
Args:
data (dict): A dictionary containing information required to create
a new peer assessment. Expecting attributes "points_earned",
"total_value", and "submission_uuid". If these attributes are
not available, a new assessment cannot be stored.
Returns:
(tuple): A tuple containing the dictionary representation of the
newly created assessment, and a "Success" string.
"""
assessment
=
self
.
get_assessment_module
(
'peer-assessment'
)
if
assessment
:
...
...
@@ -31,6 +56,13 @@ class PeerAssessmentMixin(object):
@XBlock.handler
def
render_peer_assessment
(
self
,
data
,
suffix
=
''
):
"""Renders the Peer Assessment HTML section of the XBlock
Generates the peer assessment HTML for the first section of an Open
Assessment XBlock. See OpenAssessmentBlock.render_assessment() for
more information on rendering XBlock sections.
"""
assessment
=
self
.
get_assessment_module
(
'peer-assessment'
)
if
assessment
:
peer_sub
=
self
.
get_peer_submission
(
self
.
get_student_item_dict
(),
assessment
)
...
...
apps/openassessment/xblock/self_assessment_mixin.py
View file @
229b719b
...
...
@@ -2,6 +2,17 @@ from xblock.core import XBlock
class
SelfAssessmentMixin
(
object
):
"""The Self Assessment Mixin for all Self Assessment Functionality.
Abstracts all functionality and handlers associated with Self Assessment.
All Self Assessment API calls should be contained without this Mixin as
well.
SelfAssessmentMixin is a Mixin for the OpenAssessmentBlock. Functions in
the SelfAssessmentMixin call into the OpenAssessmentBlock functions and
will not work outside of OpenAssessmentBlock.
"""
@XBlock.handler
def
render_self_assessment
(
self
,
data
,
suffix
=
''
):
...
...
apps/openassessment/xblock/static/js/src/oa_assessment.js
deleted
100644 → 0
View file @
b491ad87
/* START Javascript for OpenassessmentComposeXBlock. */
function
OpenAssessmentBlock
(
runtime
,
element
)
{
var
handlerUrl
=
runtime
.
handlerUrl
(
element
,
'assess'
);
var
success_msg
=
'<p class="success">Thanks for your feedback!</p>'
;
var
failure_msg
=
'<p class="failure">An error occurred with your feedback</p>'
;
var
click_msg
=
'<p class="clickhere">(click here to dismiss this message)</p>'
;
/* Sample Debug Console: http://localhost:8000/submissions/Joe_Bloggs/TestCourse/u_3 */
function
prepare_assessment_post
(
element
)
{
var
selector
=
$
(
"input[type=radio]:checked"
,
element
);
var
values
=
[];
for
(
i
=
0
;
i
<
selector
.
length
;
i
++
)
{
values
[
i
]
=
selector
[
i
].
value
;
}
return
{
"submission_uuid"
:
$
(
"div#peer_submission_uuid"
)[
0
].
innerText
,
"points_earned"
:
values
};
}
function
displayStatus
(
result
)
{
var
status
=
result
[
0
];
var
error_msg
=
result
[
1
];
if
(
status
)
{
$
(
'.openassessment_response_status_block'
,
element
).
html
(
success_msg
.
concat
(
click_msg
));
}
else
{
$
(
'.openassessment_response_status_block'
,
element
).
html
(
failure_msg
.
concat
(
error_msg
).
concat
(
click_msg
));
}
$
(
'.openassessment_response_status_block'
,
element
).
css
(
'display'
,
'block'
);
}
$
(
'.openassessment_response_status_block'
,
element
).
click
(
function
(
eventObject
)
{
$
(
'.openassessment_response_status_block'
,
element
).
css
(
'display'
,
'none'
);
});
$
(
'.openassessment_submit'
,
element
).
click
(
function
(
eventObject
)
{
$
.
ajax
({
type
:
"POST"
,
url
:
handlerUrl
,
/* data: JSON.stringify({"submission": $('.openassessment_submission', element).val()}), */
data
:
JSON
.
stringify
(
prepare_assessment_post
(
element
)),
success
:
displayStatus
});
});
$
(
function
(
$
)
{
/* Here's where you'd do things on page load. */
$
(
element
).
css
(
'background-color'
,
'LightBlue'
)
});
}
/* END Javascript for OpenassessmentComposeXBlock. */
apps/openassessment/xblock/submission_mixin.py
View file @
229b719b
...
...
@@ -3,10 +3,20 @@ from submissions import api
class
SubmissionMixin
(
object
):
"""Submission Mixin introducing all Submission-related functionality.
Submission Mixin contains all logic and handlers associated with rendering
the submission section of the front end, as well as making all API calls to
the middle tier for constructing new submissions, or fetching submissions.
SubmissionMixin is a Mixin for the OpenAssessmentBlock. Functions in the
SubmissionMixin call into the OpenAssessmentBlock functions and will not
work outside the scope of OpenAssessmentBlock.
"""
submit_errors
=
{
# Reported to user sometimes, and useful in tests
'ENOSUB'
:
'API submission is unrequested'
,
'ENODATA'
:
'API returned an empty response'
,
'EBADFORM'
:
'API Submission Request Error'
,
'EUNKNOWN'
:
'API returned unclassified exception'
,
...
...
@@ -15,20 +25,31 @@ class SubmissionMixin(object):
@XBlock.json_handler
def
submit
(
self
,
data
,
suffix
=
''
):
"""
Place the submission text into Openassessment system
"""Place the submission text into Openassessment system
Allows submission of new responses. Performs basic workflow validation
on any new submission to ensure it is acceptable to receive a new
response at this time.
Args:
data (dict): Data should contain one attribute: submission. This is
the response from the student which should be stored in the
Open Assessment system.
suffix (str): Not used in this handler.
Returns:
(tuple): Returns the status (boolean) of this request, the
associated status tag (str), and status text (unicode).
"""
status
=
False
status_tag
=
'ENOSUB'
status_text
=
None
student_sub
=
data
[
'submission'
]
student_item_dict
=
self
.
get_student_item_dict
()
prev_sub
=
self
.
_get_user_submission
(
student_item_dict
)
if
prev_sub
:
# It is an error to submit multiple times for the same item
status_tag
=
'ENOMULTI'
else
:
status_tag
=
'ENOMULTI'
# It is an error to submit multiple times for the same item
if
not
prev_sub
:
status_tag
=
'ENODATA'
try
:
response
=
api
.
create_submission
(
student_item_dict
,
student_sub
)
...
...
@@ -48,7 +69,19 @@ class SubmissionMixin(object):
@staticmethod
def
_get_submission_score
(
student_item_dict
,
submission
=
False
):
"""Return the most recent score, if any, for student item"""
"""Return the most recent score, if any, for student item
Gets the score, if available.
Args:
student_item_dict (dict): The student item we want to check for a
score.
Returns:
(dict): Dictionary representing the score for this particular
question.
"""
scores
=
False
if
submission
:
scores
=
api
.
get_score
(
student_item_dict
)
...
...
@@ -56,7 +89,22 @@ class SubmissionMixin(object):
@staticmethod
def
_get_user_submission
(
student_item_dict
):
"""Return the most recent submission, if any, by user in student_item_dict"""
"""Return the most recent submission by user in student_item_dict
Given a student item, return the most recent submission. If no
submission is available, return None. All submissions are preserved, but
only the most recent will be returned in this function, since the active
workflow will only be concerned with the most recent submission.
Args:
student_item_dict (dict): The student item we want to get the
latest submission for.
Returns:
(dict): A dictionary representation of a submission to render to
the front end.
"""
submissions
=
[]
try
:
submissions
=
api
.
get_submissions
(
student_item_dict
)
...
...
@@ -67,4 +115,11 @@ class SubmissionMixin(object):
@XBlock.handler
def
render_submission
(
self
,
data
,
suffix
=
''
):
"""Renders the Submission HTML section of the XBlock
Generates the submission HTML for the first section of an Open
Assessment XBlock. See OpenAssessmentBlock.render_assessment() for
more information on rendering XBlock sections.
"""
return
self
.
render_assessment
(
'static/html/oa_response.html'
)
apps/openassessment/xblock/ui_models.py
View file @
229b719b
"""UI Models constructed by the Open Assessment XBlock to generate HTML.
These Models should be fully constructed before reaching any templates used by
the XBlock, such that the templates should only have to render based on the
information provided. If any logic exists in the templates, it is likely that
should be refactored into the XBlock, and the results stored in these models.
"""
class
SubmissionUIModel
(
object
):
"""All data to be displayed to the front end regarding submissions.
All the data required to generate the Submission HTML.
"""
def
__init__
(
self
):
self
.
assessment_type
=
"submission"
...
...
@@ -16,6 +31,11 @@ class SubmissionUIModel(object):
class
AssessmentUIModel
(
object
):
"""Generic Assessment UI Model.
Common attributes for displaying Assessment sections of the front end.
"""
def
__init__
(
self
):
...
...
@@ -42,6 +62,12 @@ class AssessmentUIModel(object):
class
PeerAssessmentUIModel
(
AssessmentUIModel
):
"""All data required to display the Peer Assessment front end.
Attributes and data specific to rendering the Peer Assessment section of
the front end.
"""
def
__init__
(
self
):
super
(
PeerAssessmentUIModel
,
self
)
.
__init__
()
...
...
@@ -51,6 +77,12 @@ class PeerAssessmentUIModel(AssessmentUIModel):
class
SelfAssessmentUIModel
(
AssessmentUIModel
):
"""All data required to display the Self Assessment front end.
Attributes and data specific to rendering the Self Assessment section of
the front end.
"""
def
__init__
(
self
):
super
(
SelfAssessmentUIModel
,
self
)
.
__init__
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment