def save_submission(self, data, suffix=""): """ Save the current student's response submission. If the student already has a response saved, this will overwrite it. Args: data (dict): Data should have a single key 'submission' that contains the text of the student's response. Optionally, the data could have a 'file_url' key that is the path to an associated file for this submission. suffix (str): Not used. Returns: dict: Contains a bool 'success' and unicode string 'msg'. """ if "submission" in data: student_sub_data = data["submission"] success, msg = validate_submission(student_sub_data, self.prompts, self._) if not success: return {"success": False, "msg": msg} try: self.saved_response = json.dumps(prepare_submission_for_serialization(student_sub_data)) self.has_saved = True # Emit analytics event... self.runtime.publish( self, "openassessmentblock.save_submission", {"saved_response": self.saved_response} ) except: return {"success": False, "msg": self._(u"This response could not be saved.")} else: return {"success": True, "msg": u""} else: return {"success": False, "msg": self._(u"This response was not submitted.")}
def save_submission(self, data, suffix=''): """ Save the current student's response submission. If the student already has a response saved, this will overwrite it. Args: data (dict): Data should have a single key 'submission' that contains the text of the student's response. Optionally, the data could have a 'file_urls' key that is the path to an associated file for this submission. suffix (str): Not used. Returns: dict: Contains a bool 'success' and unicode string 'msg'. """ if 'submission' in data: student_sub_data = data['submission'] success, msg = validate_submission(student_sub_data, self.prompts, self._, self.text_response) if not success: return {'success': False, 'msg': msg} try: self.saved_response = json.dumps( prepare_submission_for_serialization(student_sub_data)) self.has_saved = True # Emit analytics event... self.runtime.publish(self, "openassessmentblock.save_submission", {"saved_response": self.saved_response}) except: return { 'success': False, 'msg': self._(u"This response could not be saved.") } else: return {'success': True, 'msg': u''} else: return { 'success': False, 'msg': self._(u"This response was not submitted.") }
def submit(self, data, suffix=''): """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 may contain two attributes: submission and file_urls. submission is the response from the student which should be stored in the Open Assessment system. file_urls is the path to a related file for the submission. file_urls is optional. 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). """ if 'submission' not in data: return (False, 'EBADARGS', self._(u'"submission" required to submit answer.')) status = False student_sub_data = data['submission'] success, msg = validate_submission(student_sub_data, self.prompts, self._, self.text_response) if not success: return (False, 'EBADARGS', msg) student_item_dict = self.get_student_item_dict() # Short-circuit if no user is defined (as in Studio Preview mode) # Since students can't submit, they will never be able to progress in the workflow if self.in_studio_preview: return ( False, 'ENOPREVIEW', self. _(u'To submit a response, view this component in Preview or Live mode.' )) workflow = self.get_workflow_info() status_tag = 'ENOMULTI' # It is an error to submit multiple times for the same item status_text = self._(u'Multiple submissions are not allowed.') if not workflow: try: try: saved_files_descriptions = json.loads( self.saved_files_descriptions) except ValueError: saved_files_descriptions = None submission = self.create_submission(student_item_dict, student_sub_data, saved_files_descriptions) except api.SubmissionRequestError as err: # Handle the case of an answer that's too long as a special case, # so we can display a more specific error message. # Although we limit the number of characters the user can # enter on the client side, the submissions API uses the JSON-serialized # submission to calculate length. If each character submitted # by the user takes more than 1 byte to encode (for example, double-escaped # newline characters or non-ASCII unicode), then the user might # exceed the limits set by the submissions API. In that case, # we display an error message indicating that the answer is too long. answer_too_long = any( "maximum answer size exceeded" in answer_err.lower() for answer_err in err.field_errors.get('answer', [])) if answer_too_long: status_tag = 'EANSWERLENGTH' else: msg = ( u"The submissions API reported an invalid request error " u"when submitting a response for the user: {student_item}" ).format(student_item=student_item_dict) logger.exception(msg) status_tag = 'EBADFORM' except (api.SubmissionError, AssessmentWorkflowError): msg = (u"An unknown error occurred while submitting " u"a response for the user: {student_item}").format( student_item=student_item_dict) logger.exception(msg) status_tag = 'EUNKNOWN' status_text = self._(u'API returned unclassified exception.') else: status = True status_tag = submission.get('student_item') status_text = submission.get('attempt_number') return status, status_tag, status_text
def submit(self, data, suffix=""): """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 may contain two attributes: submission and file_url. submission is the response from the student which should be stored in the Open Assessment system. file_url is the path to a related file for the submission. file_url is optional. 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). """ if "submission" not in data: return (False, "EBADARGS", self._(u'"submission" required to submit answer.')) status = False student_sub_data = data["submission"] success, msg = validate_submission(student_sub_data, self.prompts, self._) if not success: return (False, "EBADARGS", msg) student_item_dict = self.get_student_item_dict() # Short-circuit if no user is defined (as in Studio Preview mode) # Since students can't submit, they will never be able to progress in the workflow if self.in_studio_preview: return (False, "ENOPREVIEW", self._(u"To submit a response, view this component in Preview or Live mode.")) workflow = self.get_workflow_info() status_tag = "ENOMULTI" # It is an error to submit multiple times for the same item status_text = self._(u"Multiple submissions are not allowed.") if not workflow: try: submission = self.create_submission(student_item_dict, student_sub_data) except api.SubmissionRequestError as err: # Handle the case of an answer that's too long as a special case, # so we can display a more specific error message. # Although we limit the number of characters the user can # enter on the client side, the submissions API uses the JSON-serialized # submission to calculate length. If each character submitted # by the user takes more than 1 byte to encode (for example, double-escaped # newline characters or non-ASCII unicode), then the user might # exceed the limits set by the submissions API. In that case, # we display an error message indicating that the answer is too long. answer_too_long = any( "maximum answer size exceeded" in answer_err.lower() for answer_err in err.field_errors.get("answer", []) ) if answer_too_long: status_tag = "EANSWERLENGTH" else: msg = ( u"The submissions API reported an invalid request error " u"when submitting a response for the user: {student_item}" ).format(student_item=student_item_dict) logger.exception(msg) status_tag = "EBADFORM" except (api.SubmissionError, AssessmentWorkflowError): msg = ( u"An unknown error occurred while submitting " u"a response for the user: {student_item}" ).format(student_item=student_item_dict) logger.exception(msg) status_tag = "EUNKNOWN" status_text = self._(u"API returned unclassified exception.") else: status = True status_tag = submission.get("student_item") status_text = submission.get("attempt_number") return status, status_tag, status_text