From 7cb95aad47b3eeac72c9aaa725a0387cd464de70 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 19 Dec 2012 10:11:39 -0500 Subject: [PATCH] WIP: Add grade publishing functionality --- common/lib/xmodule/xmodule/capa_module.py | 19 +++++++++++++++++- common/lib/xmodule/xmodule/x_module.py | 7 +++++++ lms/djangoapps/courseware/module_render.py | 23 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 4728c713af..8c2297af1b 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -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) 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) - 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) 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) @@ -442,6 +442,7 @@ class CapaModule(XModule): score_msg = get['xqueue_body'] self.lcp.update_score(score_msg, queuekey) self.set_state_from_lcp() + self.publish_grade() return dict() # No AJAX return is needed @@ -519,6 +520,19 @@ class CapaModule(XModule): 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): ''' Checks whether answers to a problem are correct, and returns a map of correct/incorrect answers: @@ -570,6 +584,9 @@ class CapaModule(XModule): self.attempts = self.attempts + 1 self.lcp.done = True + self.set_state_from_lcp() + self.publish_grade() + # success = correct if ALL questions in this problem are correct success = 'correct' for answer_id in correct_map: diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 6c499aa611..a05a191e5f 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -672,6 +672,7 @@ class ModuleSystem(object): filestore=None, debug=False, xqueue=None, + publish=None, node_path="", anonymous_student_id=''): ''' @@ -723,6 +724,12 @@ class ModuleSystem(object): self.user_is_staff = user is not None and user.is_staff self.xmodule_model_data = xmodule_model_data + if publish is None: + publish = lambda e: None + + self.publish = publish + + def get(self, attr): ''' provide uniform access to attributes (like etree).''' return self.__dict__.get(attr) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 085432cbd9..839ee80591 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -277,6 +277,26 @@ def _get_module(user, request, location, student_module_cache, course_id, positi 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 # prefix is going to have to be specific to the module, not the directory # that the xml was loaded from @@ -294,7 +314,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi replace_urls=replace_urls, node_path=settings.NODE_PATH, 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 system.set('position', position)