Commit 7cb95aad by Calen Pennington

WIP: Add grade publishing functionality

parent e1ca413b
...@@ -103,7 +103,7 @@ class CapaModule(XModule): ...@@ -103,7 +103,7 @@ class CapaModule(XModule):
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings) graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings)
show_answer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed") show_answer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed")
force_save_button = Boolean(help="Whether to force the save button to appear on the page", scope=Scope.settings, default=False) force_save_button = Boolean(help="Whether to force the save button to appear on the page", scope=Scope.settings, default=False)
rerandomize = String(help="When to rerandomize the problem", default="always") rerandomize = String(help="When to rerandomize the problem", default="always", scope=Scope.settings)
data = String(help="XML data for the problem", scope=Scope.content) data = String(help="XML data for the problem", scope=Scope.content)
correct_map = Object(help="Dictionary with the correctness of current student answers", scope=Scope.student_state, default={}) correct_map = Object(help="Dictionary with the correctness of current student answers", scope=Scope.student_state, default={})
student_answers = Object(help="Dictionary with the current student responses", scope=Scope.student_state) student_answers = Object(help="Dictionary with the current student responses", scope=Scope.student_state)
...@@ -442,6 +442,7 @@ class CapaModule(XModule): ...@@ -442,6 +442,7 @@ class CapaModule(XModule):
score_msg = get['xqueue_body'] score_msg = get['xqueue_body']
self.lcp.update_score(score_msg, queuekey) self.lcp.update_score(score_msg, queuekey)
self.set_state_from_lcp() self.set_state_from_lcp()
self.publish_grade()
return dict() # No AJAX return is needed return dict() # No AJAX return is needed
...@@ -519,6 +520,19 @@ class CapaModule(XModule): ...@@ -519,6 +520,19 @@ class CapaModule(XModule):
return answers return answers
def publish_grade(self):
"""
Publishes the student's current grade to the system as an event
"""
score = self.lcp.get_score()
print score
self.system.publish({
'event_name': 'grade',
'value': score['score'],
'max_value': score['total'],
})
def check_problem(self, get): def check_problem(self, get):
''' Checks whether answers to a problem are correct, and ''' Checks whether answers to a problem are correct, and
returns a map of correct/incorrect answers: returns a map of correct/incorrect answers:
...@@ -570,6 +584,9 @@ class CapaModule(XModule): ...@@ -570,6 +584,9 @@ class CapaModule(XModule):
self.attempts = self.attempts + 1 self.attempts = self.attempts + 1
self.lcp.done = True self.lcp.done = True
self.set_state_from_lcp()
self.publish_grade()
# success = correct if ALL questions in this problem are correct # success = correct if ALL questions in this problem are correct
success = 'correct' success = 'correct'
for answer_id in correct_map: for answer_id in correct_map:
......
...@@ -672,6 +672,7 @@ class ModuleSystem(object): ...@@ -672,6 +672,7 @@ class ModuleSystem(object):
filestore=None, filestore=None,
debug=False, debug=False,
xqueue=None, xqueue=None,
publish=None,
node_path="", node_path="",
anonymous_student_id=''): anonymous_student_id=''):
''' '''
...@@ -723,6 +724,12 @@ class ModuleSystem(object): ...@@ -723,6 +724,12 @@ class ModuleSystem(object):
self.user_is_staff = user is not None and user.is_staff self.user_is_staff = user is not None and user.is_staff
self.xmodule_model_data = xmodule_model_data self.xmodule_model_data = xmodule_model_data
if publish is None:
publish = lambda e: None
self.publish = publish
def get(self, attr): def get(self, attr):
''' provide uniform access to attributes (like etree).''' ''' provide uniform access to attributes (like etree).'''
return self.__dict__.get(attr) return self.__dict__.get(attr)
......
...@@ -277,6 +277,26 @@ def _get_module(user, request, location, student_module_cache, course_id, positi ...@@ -277,6 +277,26 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
LmsUsage(location, location) LmsUsage(location, location)
) )
def publish(event):
if event.get('event_name') != 'grade':
return
student_module = student_module_cache.lookup(
course_id, descriptor.location.category, descriptor.location.url()
)
if student_module is None:
student_module = StudentModule(
course_id=course_id,
student=user,
module_type=descriptor.location.category,
module_state_key=descriptor.location.url(),
state=json.dumps({})
)
student_module_cache.append(student_module)
student_module.grade = event.get('value')
student_module.max_grade = event.get('max_value')
student_module.save()
# TODO (cpennington): When modules are shared between courses, the static # TODO (cpennington): When modules are shared between courses, the static
# prefix is going to have to be specific to the module, not the directory # prefix is going to have to be specific to the module, not the directory
# that the xml was loaded from # that the xml was loaded from
...@@ -294,7 +314,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi ...@@ -294,7 +314,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
replace_urls=replace_urls, replace_urls=replace_urls,
node_path=settings.NODE_PATH, node_path=settings.NODE_PATH,
anonymous_student_id=anonymous_student_id, anonymous_student_id=anonymous_student_id,
xmodule_model_data=xmodule_model_data xmodule_model_data=xmodule_model_data,
publish=publish,
) )
# pass position specified in URL to module through ModuleSystem # pass position specified in URL to module through ModuleSystem
system.set('position', position) system.set('position', position)
......
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