From d663d23257299d2f0a3d397b6665ee1fee5de60d Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 10:33:36 -0500 Subject: [PATCH 01/27] Work on adding in a new ajax post type --- common/lib/capa/capa/inputtypes.py | 2 +- common/lib/capa/capa/responsetypes.py | 1 + common/lib/capa/capa/templates/openendedinput.html | 7 +++++++ common/lib/xmodule/xmodule/capa_module.py | 14 ++++++++++++++ .../lib/xmodule/xmodule/js/src/capa/display.coffee | 6 ++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 73056bc09e..e3eb47acc5 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -748,7 +748,7 @@ class OpenEndedInput(InputTypeBase): # pulled out for testing submitted_msg = ("Feedback not yet available. Reload to check again. " "Once the problem is graded, this message will be " - "replaced with the grader's feedback") + "replaced with the grader's feedback.") @classmethod def get_attributes(cls): diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 8517e71d04..989e29c7a2 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1836,6 +1836,7 @@ class OpenEndedResponse(LoncapaResponse): """ DEFAULT_QUEUE = 'open-ended' + DEFAULT_MESSAGE_QUEUE = 'open-ended-message' response_tag = 'openendedresponse' allowed_inputfields = ['openendedinput'] max_inputfields = 1 diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 65fc7fb9bb..3d51b7c3b2 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -28,5 +28,12 @@ % endif
${msg|n} + % if status in ['correct','incorrect']: +
+ Score Evaluation: + + +
+ % endif
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 4c10a1703a..8ce0b17190 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -380,6 +380,7 @@ class CapaModule(XModule): 'problem_save': self.save_problem, 'problem_show': self.get_answer, 'score_update': self.update_score, + 'message_post' : self.message_post, } if dispatch not in handlers: @@ -394,6 +395,19 @@ class CapaModule(XModule): }) return json.dumps(d, cls=ComplexEncoder) + def feedback_post(self, get): + """ + Posts a message from a form to an appropriate location + """ + event_info = dict() + event_info['state'] = self.lcp.get_state() + event_info['problem_id'] = self.location.url() + + answers = self.make_dict_of_responses(get) + log.debug(answers) + + + def closed(self): ''' Is the student still allowed to submit answers? ''' if self.attempts == self.max_attempts: diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 1c0ace9e59..2c676e1e52 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -25,6 +25,7 @@ class @Problem @$('section.action input.reset').click @reset @$('section.action input.show').click @show @$('section.action input.save').click @save + @$('section.evaluation input.submit-message').click @message_post # Collapsibles Collapsible.setCollapsibles(@el) @@ -197,6 +198,11 @@ class @Problem else @gentle_alert response.success + message_post: => + Logger.log 'message_post', @answers + $.postWithPrefix "#{@url}/message_post", @answers, (response) => + @gentle_alert response.success + reset: => Logger.log 'problem_reset', @answers $.postWithPrefix "#{@url}/problem_reset", id: @id, (response) => From 634b586085a3e7a0fe14f2fb6bdb3bc027992d6e Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 10:44:17 -0500 Subject: [PATCH 02/27] Integrate new ajax action --- common/lib/capa/capa/templates/openendedinput.html | 4 ++-- common/lib/xmodule/xmodule/capa_module.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 3d51b7c3b2..6b2b293f42 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -29,9 +29,9 @@
${msg|n} % if status in ['correct','incorrect']: -
+
Score Evaluation: - +
% endif diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 8ce0b17190..3f60fc77f6 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -395,7 +395,7 @@ class CapaModule(XModule): }) return json.dumps(d, cls=ComplexEncoder) - def feedback_post(self, get): + def message_post(self, get): """ Posts a message from a form to an appropriate location """ @@ -405,8 +405,7 @@ class CapaModule(XModule): answers = self.make_dict_of_responses(get) log.debug(answers) - - + log.debug(event_info) def closed(self): ''' Is the student still allowed to submit answers? ''' From b782f712b9ab481391ae6dc5e39d064c162d2291 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 11:42:24 -0500 Subject: [PATCH 03/27] Add in more js to handle student feedback --- .../lib/capa/capa/templates/openendedinput.html | 2 +- common/lib/xmodule/xmodule/capa_module.py | 6 ++++-- .../xmodule/xmodule/js/src/capa/display.coffee | 16 ++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 6b2b293f42..f384cc3167 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -31,7 +31,7 @@ % if status in ['correct','incorrect']:
Score Evaluation: - +
% endif diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 3f60fc77f6..08f57ba14c 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -402,11 +402,13 @@ class CapaModule(XModule): event_info = dict() event_info['state'] = self.lcp.get_state() event_info['problem_id'] = self.location.url() + event_info['student_id'] = self.system.anonymous_system_id + event_info['survey_responses']= get - answers = self.make_dict_of_responses(get) - log.debug(answers) log.debug(event_info) + return {'success' : True} + def closed(self): ''' Is the student still allowed to submit answers? ''' if self.attempts == self.max_attempts: diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 2c676e1e52..e75d3a5a1d 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -200,8 +200,20 @@ class @Problem message_post: => Logger.log 'message_post', @answers - $.postWithPrefix "#{@url}/message_post", @answers, (response) => - @gentle_alert response.success + + fd = new FormData() + feedback = @$('section.evaluation textarea.feedback-on-feedback')[0] + fd.append(feedback.class, feedback.value) + + settings = + type: "POST" + data: fd + processData: false + contentType: false + success: (response) => + @gentle_alert response.success + + $.ajaxWithPrefix("#{@url}/message_post", settings) reset: => Logger.log 'problem_reset', @answers From ce3b84d0e59fc4361814bbc1b0ffcf74f110fd6e Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 11:55:03 -0500 Subject: [PATCH 04/27] Message passing in lms --- common/lib/capa/capa/capa_problem.py | 8 ++++++++ common/lib/capa/capa/responsetypes.py | 8 +++++++- common/lib/xmodule/xmodule/capa_module.py | 4 ++-- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 2eaa0e4286..585e087b36 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -186,6 +186,14 @@ class LoncapaProblem(object): maxscore += responder.get_max_score() return maxscore + def message_post(self,event_info): + """ + Handle an ajax post that contains feedback on feedback + """ + for responder in self.responders.values(): + if hasattr(responder, 'message_post'): + responder.message_post(event_info) + def get_score(self): """ Compute score for this problem. The score is the number of points awarded. diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 989e29c7a2..f8ee12650e 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1854,6 +1854,10 @@ class OpenEndedResponse(LoncapaResponse): prompt = self.xml.find('prompt') rubric = self.xml.find('openendedrubric') + #This is needed to attach feedback to specific responses later + self.submission_id=None + self.grader_id=None + if oeparam is None: raise ValueError("No oeparam found in problem xml.") if prompt is None: @@ -2139,13 +2143,15 @@ class OpenEndedResponse(LoncapaResponse): " Received score_result = {0}".format(score_result)) return fail - for tag in ['score', 'feedback', 'grader_type', 'success']: + for tag in ['score', 'feedback', 'grader_type', 'success', 'grader_id', 'submission_id']: if tag not in score_result: log.error("External grader message is missing required tag: {0}" .format(tag)) return fail feedback = self._format_feedback(score_result) + self.submission_id=score_result['submission_id'] + self.grader_id=score_result['grader_id'] # HACK: for now, just assume it's correct if you got more than 2/3. # Also assumes that score_result['score'] is an integer. diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 08f57ba14c..727449ea99 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -402,10 +402,10 @@ class CapaModule(XModule): event_info = dict() event_info['state'] = self.lcp.get_state() event_info['problem_id'] = self.location.url() - event_info['student_id'] = self.system.anonymous_system_id + event_info['student_id'] = self.system.anonymous_student_id event_info['survey_responses']= get - log.debug(event_info) + success_dict = self.lcp.message_post(event_info) return {'success' : True} diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index e75d3a5a1d..204080dd64 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -203,7 +203,7 @@ class @Problem fd = new FormData() feedback = @$('section.evaluation textarea.feedback-on-feedback')[0] - fd.append(feedback.class, feedback.value) + fd.append('feedback', feedback.value) settings = type: "POST" From b71233fd5054dffb9564817cb75ce31564d4dd4c Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 12:46:07 -0500 Subject: [PATCH 05/27] Add in message passing pipeline --- common/lib/capa/capa/capa_problem.py | 14 ++++- common/lib/capa/capa/responsetypes.py | 62 ++++++++++++++++++- common/lib/xmodule/xmodule/capa_module.py | 4 +- .../xmodule/js/src/capa/display.coffee | 8 ++- 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 585e087b36..9c383d114d 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -189,10 +189,20 @@ class LoncapaProblem(object): def message_post(self,event_info): """ Handle an ajax post that contains feedback on feedback + Returns a boolean success variable + Note: This only allows for feedback to be posted back to the grading controller for the first + open ended response problem on each page. Multiple problems will cause some sync issues. + TODO: Handle multiple problems on one page sync issues. """ + success=False + message = "" + log.debug("in lcp") for responder in self.responders.values(): - if hasattr(responder, 'message_post'): - responder.message_post(event_info) + if hasattr(responder, 'handle_message_post'): + success, message = responder.handle_message_post(event_info) + if success: + break + return success, message def get_score(self): """ diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index f8ee12650e..038586f7f4 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1848,6 +1848,7 @@ class OpenEndedResponse(LoncapaResponse): xml = self.xml self.url = xml.get('url', None) self.queue_name = xml.get('queuename', self.DEFAULT_QUEUE) + self.message_queue_name = xml.get('message-queuename', self.DEFAULT_MESSAGE_QUEUE) # The openendedparam tag encapsulates all grader settings oeparam = self.xml.find('openendedparam') @@ -1921,6 +1922,52 @@ class OpenEndedResponse(LoncapaResponse): except ValueError: self.max_score = 1 + def handle_message_post(self,event_info): + """ + Handles a student message post (a reaction to the grade they received from an open ended grader type) + Returns a boolean success/fail and an error message + """ + survey_responses=event_info['survey_responses'] + for tag in ['feedback', 'submission_id', 'grader_id']: + if tag not in survey_responses: + return False, "Could not find needed tag {0}".format(tag) + try: + submission_id=int(survey_responses['submission_id'][0]) + grader_id = int(survey_responses['grader_id'][0]) + feedback = str(survey_responses['feedback'][0]) + except: + error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." + log.exception(error_message) + return False, error_message + + qinterface = self.system.xqueue['interface'] + qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat) + anonymous_student_id = self.system.anonymous_student_id + queuekey = xqueue_interface.make_hashkey(str(self.system.seed) + qtime + + anonymous_student_id + + self.answer_id) + + xheader = xqueue_interface.make_xheader(lms_key=queuekey,queue_name=self.message_queue_name) + student_info = {'anonymous_student_id': anonymous_student_id, + 'submission_time': qtime, + } + contents= { + 'feedback' : feedback, + 'submission_id' : submission_id, + 'grader_id' : grader_id, + 'student_info' : json.dumps(student_info), + } + + (error, msg) = qinterface.send_to_queue(header=xheader, + body=json.dumps(contents)) + + #Convert error to a success value + success=True + if error: + success=False + + return success, "Successfully sent to queue." + def get_score(self, student_answers): try: @@ -2068,11 +2115,18 @@ class OpenEndedResponse(LoncapaResponse):
""".format(feedback_type=feedback_type, value=value) + def format_feedback_hidden(feedback_type , value): + return """ + + """.format(feedback_type=feedback_type, value=value) + # TODO (vshnayder): design and document the details of this format so # that we can do proper escaping here (e.g. are the graders allowed to # include HTML?) - for tag in ['success', 'feedback']: + for tag in ['success', 'feedback', 'submission_id', 'grader_id']: if tag not in response_items: return format_feedback('errors', 'Error getting feedback') @@ -2088,10 +2142,12 @@ class OpenEndedResponse(LoncapaResponse): return format_feedback('errors', 'No feedback available') feedback_lst = sorted(feedback.items(), key=get_priority) - return u"\n".join(format_feedback(k, v) for k, v in feedback_lst) + feedback_list_part1 = u"\n".join(format_feedback(k, v) for k, v in feedback_lst) else: - return format_feedback('errors', response_items['feedback']) + feedback_list_part1 = format_feedback('errors', response_items['feedback']) + feedback_list_part2=u"\n".join([format_feedback_hidden(k,response_items[k]) for k in response_items.keys() if k in ['submission_id', 'grader_id']]) + return u"\n".join([feedback_list_part1,feedback_list_part2]) def _format_feedback(self, response_items): """ diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 727449ea99..8d72fdf01c 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -405,9 +405,9 @@ class CapaModule(XModule): event_info['student_id'] = self.system.anonymous_student_id event_info['survey_responses']= get - success_dict = self.lcp.message_post(event_info) + success, message = self.lcp.message_post(event_info) - return {'success' : True} + return {'success' : success} def closed(self): ''' Is the student still allowed to submit answers? ''' diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 204080dd64..393435a2e4 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -202,8 +202,12 @@ class @Problem Logger.log 'message_post', @answers fd = new FormData() - feedback = @$('section.evaluation textarea.feedback-on-feedback')[0] - fd.append('feedback', feedback.value) + feedback = @$('section.evaluation textarea.feedback-on-feedback')[0].value + submission_id = $('div.external-grader-message div.submission_id')[0].innerHTML + grader_id = $('div.external-grader-message div.grader_id')[0].innerHTML + fd.append('feedback', feedback) + fd.append('submission_id', submission_id) + fd.append('grader_id', grader_id) settings = type: "POST" From b06ce84afdf7b76e5b824b637a0acac8d634fd66 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 12:58:29 -0500 Subject: [PATCH 06/27] Wire in submit message --- common/lib/capa/capa/capa_problem.py | 2 +- common/lib/capa/capa/responsetypes.py | 16 +++++++++++----- common/lib/xmodule/xmodule/capa_module.py | 2 +- .../xmodule/xmodule/js/src/capa/display.coffee | 5 ++++- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index 9c383d114d..efc96fc717 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -195,7 +195,7 @@ class LoncapaProblem(object): TODO: Handle multiple problems on one page sync issues. """ success=False - message = "" + message = "Could not find a valid responder." log.debug("in lcp") for responder in self.responders.values(): if hasattr(responder, 'handle_message_post'): diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 038586f7f4..e9a363adba 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1932,9 +1932,10 @@ class OpenEndedResponse(LoncapaResponse): if tag not in survey_responses: return False, "Could not find needed tag {0}".format(tag) try: - submission_id=int(survey_responses['submission_id'][0]) - grader_id = int(survey_responses['grader_id'][0]) - feedback = str(survey_responses['feedback'][0]) + log.debug(survey_responses['submission_id']) + submission_id=int(survey_responses['submission_id']) + grader_id = int(survey_responses['grader_id']) + feedback = str(survey_responses['feedback']) except: error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." log.exception(error_message) @@ -1947,7 +1948,12 @@ class OpenEndedResponse(LoncapaResponse): anonymous_student_id + self.answer_id) - xheader = xqueue_interface.make_xheader(lms_key=queuekey,queue_name=self.message_queue_name) + xheader = xqueue_interface.make_xheader( + lms_callback_url=self.system.xqueue['callback_url'], + lms_key=queuekey, + queue_name=self.message_queue_name + ) + student_info = {'anonymous_student_id': anonymous_student_id, 'submission_time': qtime, } @@ -1966,7 +1972,7 @@ class OpenEndedResponse(LoncapaResponse): if error: success=False - return success, "Successfully sent to queue." + return success, "Successfully submitted your feedback." def get_score(self, student_answers): diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 8d72fdf01c..d65fa1f40a 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -407,7 +407,7 @@ class CapaModule(XModule): success, message = self.lcp.message_post(event_info) - return {'success' : success} + return {'success' : success, 'message' : message} def closed(self): ''' Is the student still allowed to submit answers? ''' diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 393435a2e4..1783df0e04 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -215,7 +215,10 @@ class @Problem processData: false contentType: false success: (response) => - @gentle_alert response.success + @gentle_alert response.message + switch response.success + when 'True', 'true' + @$('section.evaluation input.submit-message').hide() $.ajaxWithPrefix("#{@url}/message_post", settings) From ad415583791575524554bb26196ed8b6dd8f3723 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 13:30:20 -0500 Subject: [PATCH 07/27] Hide submit button --- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 1783df0e04..0364efe526 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -216,9 +216,7 @@ class @Problem contentType: false success: (response) => @gentle_alert response.message - switch response.success - when 'True', 'true' - @$('section.evaluation input.submit-message').hide() + @$('section.evaluation input.submit-message').hide() $.ajaxWithPrefix("#{@url}/message_post", settings) From fa97187a3136ce33b2f2f9740bd4d69b0c18b050 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 14:10:00 -0500 Subject: [PATCH 08/27] Patch naming issue --- common/lib/capa/capa/templates/openendedinput.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index f384cc3167..e2353d72a3 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -31,7 +31,7 @@ % if status in ['correct','incorrect']:
Score Evaluation: - +
% endif From 54c541de456d4535bbb06c6536c70471982514da Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 13 Dec 2012 15:28:04 -0500 Subject: [PATCH 09/27] Fix up the feedback-on-feedback styling and add radio button score selection. --- .../capa/capa/templates/openendedinput.html | 16 +++++++-- .../lib/xmodule/xmodule/css/capa/display.scss | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index e2353d72a3..9f745bda72 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -30,9 +30,21 @@ ${msg|n} % if status in ['correct','incorrect']:
- Score Evaluation: + How accurate do you think this grading is? +
+
    +
  • +
  • +
  • +
  • +
  • +
+
+ Additional comments: - +
+ +
% endif diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index b25ab3d3a2..18f1604edc 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -297,6 +297,42 @@ section.problem { float: left; } } + + } + .evaluation { + p { + margin-bottom: 4px; + } + } + + + .feedback-on-feedback { + height: 100px; + margin-right: 20px; + } + + .evaluation-scoring { + .scoring-list { + list-style-type: none; + margin-left: 3px; + + li { + &:first-child { + margin-left: 0px; + } + display:inline; + margin-left: 50px; + + label { + font-size: .9em; + } + + } + } + + } + .submit-message-container { + margin: 10px 0px ; } } From 69ae1cc268192182e6f447d8ad64bff133b98fa8 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Thu, 13 Dec 2012 17:01:21 -0500 Subject: [PATCH 10/27] Clean up the styling and make the evaluation parts collapsible. --- common/lib/capa/capa/templates/openendedinput.html | 7 ++++++- common/lib/xmodule/xmodule/css/capa/display.scss | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 9f745bda72..58cfec06a9 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -27,8 +27,12 @@ % endif
- ${msg|n} + ${msg|n} % if status in ['correct','incorrect']: +
+
+ Respond to Feedback +
How accurate do you think this grading is?
@@ -46,6 +50,7 @@
+
% endif
diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index 18f1604edc..929b6dcb48 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -311,6 +311,15 @@ section.problem { margin-right: 20px; } + .evaluation-response { + header { + text-align: right; + a { + font-size: .85em; + } + } + } + .evaluation-scoring { .scoring-list { list-style-type: none; @@ -670,6 +679,10 @@ section.problem { color: #2C2C2C; font-family: monospace; font-size: 1em; + padding-top: 10px; + header { + font-size: 1.4em; + } .shortform { font-weight: bold; From 8f4efb045695806e23ab444b2c2f1d3adafe7a22 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Fri, 14 Dec 2012 09:47:40 -0500 Subject: [PATCH 11/27] Hook up new radio buttons to the Javascript --- common/lib/capa/capa/templates/openendedinput.html | 4 ++-- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 58cfec06a9..aff55d6740 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -34,7 +34,7 @@ Respond to Feedback
- How accurate do you think this grading is? +

How accurate do you think this feedback is?

  • @@ -44,7 +44,7 @@
- Additional comments: +

Additional comments:

diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 0364efe526..72294e8ff9 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -205,9 +205,13 @@ class @Problem feedback = @$('section.evaluation textarea.feedback-on-feedback')[0].value submission_id = $('div.external-grader-message div.submission_id')[0].innerHTML grader_id = $('div.external-grader-message div.grader_id')[0].innerHTML + score = $(".evaluation-scoring input:radio[name='evaluation-score']:checked").val() fd.append('feedback', feedback) fd.append('submission_id', submission_id) fd.append('grader_id', grader_id) + if(score) + fd.append('score', score) + settings = type: "POST" @@ -216,7 +220,7 @@ class @Problem contentType: false success: (response) => @gentle_alert response.message - @$('section.evaluation input.submit-message').hide() + @$('section.evaluation').slideToggle() $.ajaxWithPrefix("#{@url}/message_post", settings) From de7d6f184a93f451cd9158641481ba41de493402 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Fri, 14 Dec 2012 09:59:59 -0500 Subject: [PATCH 12/27] Parse out the score given into an int. --- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 72294e8ff9..932df2fda9 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -209,8 +209,8 @@ class @Problem fd.append('feedback', feedback) fd.append('submission_id', submission_id) fd.append('grader_id', grader_id) - if(score) - fd.append('score', score) + if(score && parseInt(score) != NaN) + fd.append('score', parseInt(score)) settings = From c87d0f11d62ac725bfc0f39fdb1c7fbabf73a7f2 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Fri, 14 Dec 2012 10:48:22 -0500 Subject: [PATCH 13/27] Show error when no score selected --- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 932df2fda9..441d8b7634 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -209,8 +209,9 @@ class @Problem fd.append('feedback', feedback) fd.append('submission_id', submission_id) fd.append('grader_id', grader_id) - if(score && parseInt(score) != NaN) - fd.append('score', parseInt(score)) + if(!score || parseInt(score) == NaN) + @gentle_alert "You need to pick a rating to submit." + return settings = From 09ed3d12a29e61518f4a1cd57347714c326e8435 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Fri, 14 Dec 2012 12:00:42 -0500 Subject: [PATCH 14/27] Hook up the backend into the new feedback response for scores --- common/lib/capa/capa/responsetypes.py | 4 +++- common/lib/capa/capa/templates/openendedinput.html | 2 +- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index e9a363adba..81843b6edf 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1928,7 +1928,7 @@ class OpenEndedResponse(LoncapaResponse): Returns a boolean success/fail and an error message """ survey_responses=event_info['survey_responses'] - for tag in ['feedback', 'submission_id', 'grader_id']: + for tag in ['feedback', 'submission_id', 'grader_id', 'score']: if tag not in survey_responses: return False, "Could not find needed tag {0}".format(tag) try: @@ -1936,6 +1936,7 @@ class OpenEndedResponse(LoncapaResponse): submission_id=int(survey_responses['submission_id']) grader_id = int(survey_responses['grader_id']) feedback = str(survey_responses['feedback']) + score = int(survey_responses['score']) except: error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." log.exception(error_message) @@ -1961,6 +1962,7 @@ class OpenEndedResponse(LoncapaResponse): 'feedback' : feedback, 'submission_id' : submission_id, 'grader_id' : grader_id, + 'score': score, 'student_info' : json.dumps(student_info), } diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index aff55d6740..27042fda85 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -34,7 +34,7 @@ Respond to Feedback
-

How accurate do you think this feedback is?

+

How accurate do you find this feedback?

  • diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 441d8b7634..005840e9d3 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -209,9 +209,11 @@ class @Problem fd.append('feedback', feedback) fd.append('submission_id', submission_id) fd.append('grader_id', grader_id) - if(!score || parseInt(score) == NaN) - @gentle_alert "You need to pick a rating to submit." + if(!score) + @gentle_alert "You need to pick a rating before you can submit." return + else + fd.append('score', score) settings = From 1ac75b94209a0d4a7ed91348f3c585ee983b56d4 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 12:46:07 -0500 Subject: [PATCH 15/27] Add in message passing pipeline --- common/lib/capa/capa/responsetypes.py | 69 ++------------------------- 1 file changed, 3 insertions(+), 66 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 81843b6edf..720620dbe1 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1922,60 +1922,6 @@ class OpenEndedResponse(LoncapaResponse): except ValueError: self.max_score = 1 - def handle_message_post(self,event_info): - """ - Handles a student message post (a reaction to the grade they received from an open ended grader type) - Returns a boolean success/fail and an error message - """ - survey_responses=event_info['survey_responses'] - for tag in ['feedback', 'submission_id', 'grader_id', 'score']: - if tag not in survey_responses: - return False, "Could not find needed tag {0}".format(tag) - try: - log.debug(survey_responses['submission_id']) - submission_id=int(survey_responses['submission_id']) - grader_id = int(survey_responses['grader_id']) - feedback = str(survey_responses['feedback']) - score = int(survey_responses['score']) - except: - error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." - log.exception(error_message) - return False, error_message - - qinterface = self.system.xqueue['interface'] - qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat) - anonymous_student_id = self.system.anonymous_student_id - queuekey = xqueue_interface.make_hashkey(str(self.system.seed) + qtime + - anonymous_student_id + - self.answer_id) - - xheader = xqueue_interface.make_xheader( - lms_callback_url=self.system.xqueue['callback_url'], - lms_key=queuekey, - queue_name=self.message_queue_name - ) - - student_info = {'anonymous_student_id': anonymous_student_id, - 'submission_time': qtime, - } - contents= { - 'feedback' : feedback, - 'submission_id' : submission_id, - 'grader_id' : grader_id, - 'score': score, - 'student_info' : json.dumps(student_info), - } - - (error, msg) = qinterface.send_to_queue(header=xheader, - body=json.dumps(contents)) - - #Convert error to a success value - success=True - if error: - success=False - - return success, "Successfully submitted your feedback." - def get_score(self, student_answers): try: @@ -2123,18 +2069,11 @@ class OpenEndedResponse(LoncapaResponse):
""".format(feedback_type=feedback_type, value=value) - def format_feedback_hidden(feedback_type , value): - return """ - - """.format(feedback_type=feedback_type, value=value) - # TODO (vshnayder): design and document the details of this format so # that we can do proper escaping here (e.g. are the graders allowed to # include HTML?) - for tag in ['success', 'feedback', 'submission_id', 'grader_id']: + for tag in ['success', 'feedback']: if tag not in response_items: return format_feedback('errors', 'Error getting feedback') @@ -2150,12 +2089,10 @@ class OpenEndedResponse(LoncapaResponse): return format_feedback('errors', 'No feedback available') feedback_lst = sorted(feedback.items(), key=get_priority) - feedback_list_part1 = u"\n".join(format_feedback(k, v) for k, v in feedback_lst) + return u"\n".join(format_feedback(k, v) for k, v in feedback_lst) else: - feedback_list_part1 = format_feedback('errors', response_items['feedback']) + return format_feedback('errors', response_items['feedback']) - feedback_list_part2=u"\n".join([format_feedback_hidden(k,response_items[k]) for k in response_items.keys() if k in ['submission_id', 'grader_id']]) - return u"\n".join([feedback_list_part1,feedback_list_part2]) def _format_feedback(self, response_items): """ From 2c469cad752e1b77d8276a379df65c4c782afbf2 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 12 Dec 2012 12:58:29 -0500 Subject: [PATCH 16/27] Wire in submit message --- common/lib/capa/capa/responsetypes.py | 61 +++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 720620dbe1..038586f7f4 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1922,6 +1922,52 @@ class OpenEndedResponse(LoncapaResponse): except ValueError: self.max_score = 1 + def handle_message_post(self,event_info): + """ + Handles a student message post (a reaction to the grade they received from an open ended grader type) + Returns a boolean success/fail and an error message + """ + survey_responses=event_info['survey_responses'] + for tag in ['feedback', 'submission_id', 'grader_id']: + if tag not in survey_responses: + return False, "Could not find needed tag {0}".format(tag) + try: + submission_id=int(survey_responses['submission_id'][0]) + grader_id = int(survey_responses['grader_id'][0]) + feedback = str(survey_responses['feedback'][0]) + except: + error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." + log.exception(error_message) + return False, error_message + + qinterface = self.system.xqueue['interface'] + qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat) + anonymous_student_id = self.system.anonymous_student_id + queuekey = xqueue_interface.make_hashkey(str(self.system.seed) + qtime + + anonymous_student_id + + self.answer_id) + + xheader = xqueue_interface.make_xheader(lms_key=queuekey,queue_name=self.message_queue_name) + student_info = {'anonymous_student_id': anonymous_student_id, + 'submission_time': qtime, + } + contents= { + 'feedback' : feedback, + 'submission_id' : submission_id, + 'grader_id' : grader_id, + 'student_info' : json.dumps(student_info), + } + + (error, msg) = qinterface.send_to_queue(header=xheader, + body=json.dumps(contents)) + + #Convert error to a success value + success=True + if error: + success=False + + return success, "Successfully sent to queue." + def get_score(self, student_answers): try: @@ -2069,11 +2115,18 @@ class OpenEndedResponse(LoncapaResponse):
""".format(feedback_type=feedback_type, value=value) + def format_feedback_hidden(feedback_type , value): + return """ + + """.format(feedback_type=feedback_type, value=value) + # TODO (vshnayder): design and document the details of this format so # that we can do proper escaping here (e.g. are the graders allowed to # include HTML?) - for tag in ['success', 'feedback']: + for tag in ['success', 'feedback', 'submission_id', 'grader_id']: if tag not in response_items: return format_feedback('errors', 'Error getting feedback') @@ -2089,10 +2142,12 @@ class OpenEndedResponse(LoncapaResponse): return format_feedback('errors', 'No feedback available') feedback_lst = sorted(feedback.items(), key=get_priority) - return u"\n".join(format_feedback(k, v) for k, v in feedback_lst) + feedback_list_part1 = u"\n".join(format_feedback(k, v) for k, v in feedback_lst) else: - return format_feedback('errors', response_items['feedback']) + feedback_list_part1 = format_feedback('errors', response_items['feedback']) + feedback_list_part2=u"\n".join([format_feedback_hidden(k,response_items[k]) for k in response_items.keys() if k in ['submission_id', 'grader_id']]) + return u"\n".join([feedback_list_part1,feedback_list_part2]) def _format_feedback(self, response_items): """ From 11c330bf52a48cfd437e21cd31c12e56aa093b06 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Fri, 14 Dec 2012 17:33:54 -0500 Subject: [PATCH 17/27] Fix rebase issues --- common/lib/xmodule/xmodule/js/src/capa/display.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index 005840e9d3..ba746fecb8 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -211,7 +211,7 @@ class @Problem fd.append('grader_id', grader_id) if(!score) @gentle_alert "You need to pick a rating before you can submit." - return + return else fd.append('score', score) From 5caa42fbe39271c4d10bd069da21feb931ce9b6b Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Fri, 14 Dec 2012 17:39:56 -0500 Subject: [PATCH 18/27] Reset some files --- lms/static/coffee/src/discussion/utils.coffee | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index 6b2714dc54..a032c0248f 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -249,10 +249,7 @@ class @DiscussionUtil $3 else if RE_DISPLAYMATH.test(text) text = text.replace RE_DISPLAYMATH, ($0, $1, $2, $3) -> - #processedText += $1 + processor("$$" + $2 + "$$", 'display') - #bug fix, ordering is off - processedText = processor("$$" + $2 + "$$", 'display') + processedText - processedText = $1 + processedText + processedText += $1 + processor("$$" + $2 + "$$", 'display') $3 else processedText += text From 37af39ef8d3eaa0ada0063d133327211fb976c5a Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Wed, 2 Jan 2013 12:19:24 -0500 Subject: [PATCH 19/27] Change names --- common/lib/capa/capa/templates/openendedinput.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/templates/openendedinput.html b/common/lib/capa/capa/templates/openendedinput.html index 27042fda85..c42ad73faf 100644 --- a/common/lib/capa/capa/templates/openendedinput.html +++ b/common/lib/capa/capa/templates/openendedinput.html @@ -37,11 +37,11 @@

How accurate do you find this feedback?

    -
  • -
  • -
  • -
  • -
  • +
  • +
  • +
  • +
  • +

Additional comments:

From 9559c7b426eb8a6d8b8ff3cb4211a517154a7bed Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 09:41:46 -0500 Subject: [PATCH 20/27] Patch "correct" answer display --- common/lib/capa/capa/responsetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 038586f7f4..1e2dd77d60 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -2211,7 +2211,7 @@ class OpenEndedResponse(LoncapaResponse): # HACK: for now, just assume it's correct if you got more than 2/3. # Also assumes that score_result['score'] is an integer. - score_ratio = int(score_result['score']) / self.max_score + score_ratio = int(score_result['score']) / float(self.max_score) correct = (score_ratio >= 0.66) #Currently ignore msg and only return feedback (which takes the place of msg) From a4eb76017b4f9021910e330efdd1460a02f70742 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 09:51:04 -0500 Subject: [PATCH 21/27] Display max score as well as score --- common/lib/capa/capa/responsetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 1e2dd77d60..9b222ccce1 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -2165,7 +2165,7 @@ class OpenEndedResponse(LoncapaResponse): feedback_template = self.system.render_template("open_ended_feedback.html", { 'grader_type': response_items['grader_type'], - 'score': response_items['score'], + 'score': "{0} / {1}".format(response_items['score'], self.max_score), 'feedback': feedback, }) From 68f0f7e0a8764f38ca98572c94cf0d0a982752d8 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 10:54:47 -0500 Subject: [PATCH 22/27] Handle unicode feedback --- common/lib/capa/capa/responsetypes.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 9b222ccce1..a67c0498cd 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -2108,19 +2108,30 @@ class OpenEndedResponse(LoncapaResponse): """ return priorities.get(elt[0], default_priority) + def encode_values(feedback_type,value): + feedback_type=str(feedback_type).encode('ascii', 'ignore') + if not isinstance(value,basestring): + value=str(value) + value=value.encode('ascii', 'ignore') + return feedback_type,value + def format_feedback(feedback_type, value): - return """ + feedback_type,value=encode_values(feedback_type,value) + feedback= """
{value}
""".format(feedback_type=feedback_type, value=value) + return cgi.escape(feedback) def format_feedback_hidden(feedback_type , value): - return """ + feedback_type,value=encode_values(feedback_type,value) + feedback = """ """.format(feedback_type=feedback_type, value=value) + return cgi.escape(feedback) # TODO (vshnayder): design and document the details of this format so # that we can do proper escaping here (e.g. are the graders allowed to From cce6b70103651d91e15b562f70a47444741ba27c Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 11:11:45 -0500 Subject: [PATCH 23/27] Fixes to log entire state on errors, format feedback better --- common/lib/capa/capa/responsetypes.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index a67c0498cd..341563a24e 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1928,13 +1928,15 @@ class OpenEndedResponse(LoncapaResponse): Returns a boolean success/fail and an error message """ survey_responses=event_info['survey_responses'] - for tag in ['feedback', 'submission_id', 'grader_id']: + for tag in ['feedback', 'submission_id', 'grader_id', 'score']: if tag not in survey_responses: return False, "Could not find needed tag {0}".format(tag) try: - submission_id=int(survey_responses['submission_id'][0]) - grader_id = int(survey_responses['grader_id'][0]) - feedback = str(survey_responses['feedback'][0]) + log.debug(survey_responses['submission_id']) + submission_id=int(survey_responses['submission_id']) + grader_id = int(survey_responses['grader_id']) + feedback = str(survey_responses['feedback']) + score = int(survey_responses['score']) except: error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." log.exception(error_message) @@ -1947,7 +1949,12 @@ class OpenEndedResponse(LoncapaResponse): anonymous_student_id + self.answer_id) - xheader = xqueue_interface.make_xheader(lms_key=queuekey,queue_name=self.message_queue_name) + xheader = xqueue_interface.make_xheader( + lms_callback_url=self.system.xqueue['callback_url'], + lms_key=queuekey, + queue_name=self.message_queue_name + ) + student_info = {'anonymous_student_id': anonymous_student_id, 'submission_time': qtime, } @@ -1955,6 +1962,7 @@ class OpenEndedResponse(LoncapaResponse): 'feedback' : feedback, 'submission_id' : submission_id, 'grader_id' : grader_id, + 'score': score, 'student_info' : json.dumps(student_info), } @@ -1966,7 +1974,7 @@ class OpenEndedResponse(LoncapaResponse): if error: success=False - return success, "Successfully sent to queue." + return success, "Successfully submitted your feedback." def get_score(self, student_answers): From 0c3eb67d5c2b4f04f847e8fe523f873b62a05e37 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 11:15:00 -0500 Subject: [PATCH 24/27] More descriptive error message --- common/lib/capa/capa/responsetypes.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 341563a24e..d279b7e9e2 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1932,13 +1932,13 @@ class OpenEndedResponse(LoncapaResponse): if tag not in survey_responses: return False, "Could not find needed tag {0}".format(tag) try: - log.debug(survey_responses['submission_id']) submission_id=int(survey_responses['submission_id']) grader_id = int(survey_responses['grader_id']) feedback = str(survey_responses['feedback']) score = int(survey_responses['score']) except: - error_message="Could not parse submission id, grader id, or feedback from message_post ajax call." + error_message=("Could not parse submission id, grader id, " + "or feedback from message_post ajax call. Here is the message data: {0}".format(survey_responses)) log.exception(error_message) return False, error_message @@ -2130,7 +2130,7 @@ class OpenEndedResponse(LoncapaResponse): {value} """.format(feedback_type=feedback_type, value=value) - return cgi.escape(feedback) + return feedback def format_feedback_hidden(feedback_type , value): feedback_type,value=encode_values(feedback_type,value) @@ -2139,7 +2139,7 @@ class OpenEndedResponse(LoncapaResponse): {value} """.format(feedback_type=feedback_type, value=value) - return cgi.escape(feedback) + return feedback # TODO (vshnayder): design and document the details of this format so # that we can do proper escaping here (e.g. are the graders allowed to @@ -2165,7 +2165,10 @@ class OpenEndedResponse(LoncapaResponse): else: feedback_list_part1 = format_feedback('errors', response_items['feedback']) - feedback_list_part2=u"\n".join([format_feedback_hidden(k,response_items[k]) for k in response_items.keys() if k in ['submission_id', 'grader_id']]) + feedback_list_part2=(u"\n".join([format_feedback_hidden(feedback_type,value) + for feedback_type,value in response_items.items() + if feedback_type in ['submission_id', 'grader_id']])) + return u"\n".join([feedback_list_part1,feedback_list_part2]) def _format_feedback(self, response_items): From 5567477c6737aa5b1c53a8fabf1180105b93a84a Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 11:19:25 -0500 Subject: [PATCH 25/27] Pass through initial display and answer --- common/lib/capa/capa/responsetypes.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index d279b7e9e2..443f661418 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1905,18 +1905,22 @@ class OpenEndedResponse(LoncapaResponse): # response types) except TypeError, ValueError: log.exception("Grader payload %r is not a json object!", grader_payload) + + self.initial_display = find_with_default(oeparam, 'initial_display', '') + self.answer = find_with_default(oeparam, 'answer_display', 'No answer given.') + parsed_grader_payload.update({ 'location' : self.system.location, 'course_id' : self.system.course_id, 'prompt' : prompt_string, 'rubric' : rubric_string, - }) + 'initial_display' : self.initial_display, + 'answer' : self.answer, + }) updated_grader_payload = json.dumps(parsed_grader_payload) self.payload = {'grader_payload': updated_grader_payload} - self.initial_display = find_with_default(oeparam, 'initial_display', '') - self.answer = find_with_default(oeparam, 'answer_display', 'No answer given.') try: self.max_score = int(find_with_default(oeparam, 'max_score', 1)) except ValueError: @@ -2016,7 +2020,7 @@ class OpenEndedResponse(LoncapaResponse): contents.update({ 'student_info': json.dumps(student_info), 'student_response': submission, - 'max_score' : self.max_score + 'max_score' : self.max_score, }) # Submit request. When successful, 'msg' is the prior length of the queue From b01666f6d686816b62d734c490bce0ad2461c2c8 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 11:23:20 -0500 Subject: [PATCH 26/27] Fix error messages --- common/lib/capa/capa/responsetypes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 443f661418..3e79ca2084 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1938,13 +1938,13 @@ class OpenEndedResponse(LoncapaResponse): try: submission_id=int(survey_responses['submission_id']) grader_id = int(survey_responses['grader_id']) - feedback = str(survey_responses['feedback']) + feedback = str(survey_responses['feedback'].encode('ascii', 'ignore')) score = int(survey_responses['score']) except: error_message=("Could not parse submission id, grader id, " "or feedback from message_post ajax call. Here is the message data: {0}".format(survey_responses)) log.exception(error_message) - return False, error_message + return False, "There was an error saving your feedback. Please contact course staff." qinterface = self.system.xqueue['interface'] qtime = datetime.strftime(datetime.now(), xqueue_interface.dateformat) From 90d902d105386f04d40fee1852d082572ef3e240 Mon Sep 17 00:00:00 2001 From: Vik Paruchuri Date: Thu, 3 Jan 2013 12:11:27 -0500 Subject: [PATCH 27/27] Fix file version --- lms/static/coffee/src/discussion/utils.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index a032c0248f..6b2714dc54 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -249,7 +249,10 @@ class @DiscussionUtil $3 else if RE_DISPLAYMATH.test(text) text = text.replace RE_DISPLAYMATH, ($0, $1, $2, $3) -> - processedText += $1 + processor("$$" + $2 + "$$", 'display') + #processedText += $1 + processor("$$" + $2 + "$$", 'display') + #bug fix, ordering is off + processedText = processor("$$" + $2 + "$$", 'display') + processedText + processedText = $1 + processedText $3 else processedText += text