def POST(self, courseid, taskid): """ POST a new submission """ if self.user_manager.session_logged_in(): username = self.user_manager.session_username() try: course = self.course_factory.get_course(courseid) if not self.user_manager.course_is_open_to_user(course, username): return self.template_helper.get_renderer().course_unavailable() task = course.get_task(taskid) if not self.user_manager.task_is_visible_by_user(task, username): return self.template_helper.get_renderer().task_unavailable() self.user_manager.user_saw_task(username, courseid, taskid) is_staff = self.user_manager.has_staff_rights_on_course(course, username) is_admin = self.user_manager.has_admin_rights_on_course(course, username) userinput = web.input() if "@action" in userinput and userinput["@action"] == "submit": # Verify rights if not self.user_manager.task_can_user_submit(task, username): return json.dumps({"status": "error", "text": "You are not allowed to submit for this task."}) # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(task) userinput = task.adapt_input_for_backend(web.input(**init_var)) if not task.input_is_consistent(userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({"status": "error", "text": "Please answer to all the questions and verify the extensions of the files " "you want to upload. Your responses were not tested."}) del userinput['@action'] # Get debug info if the current user is an admin debug = is_admin if "@debug-mode" in userinput: if userinput["@debug-mode"] == "ssh" and debug and self.remote_ssh_manager.is_active(): debug = "ssh" del userinput['@debug-mode'] # Start the submission submissionid = self.submission_manager.add_job(task, userinput, debug) web.header('Content-Type', 'application/json') return json.dumps({"status": "ok", "submissionid": str(submissionid)}) elif "@action" in userinput and userinput["@action"] == "check" and "submissionid" in userinput: result = self.submission_manager.get_submission(userinput['submissionid']) if result is None: web.header('Content-Type', 'application/json') return json.dumps({'status': "error"}) elif self.submission_manager.is_done(result): web.header('Content-Type', 'application/json') result = self.submission_manager.get_input_from_submission(result) result = self.submission_manager.get_feedback_from_submission(result, show_everything=is_staff) return submission_to_json(result, is_admin) else: web.header('Content-Type', 'application/json') if "ssh_key" in result and self.remote_ssh_manager.is_active(): return json.dumps({'status': "waiting", 'ssh_host': self.remote_ssh_manager.get_url(), 'ssh_key': result["ssh_key"], 'ssh_conn_id': userinput['submissionid']}) else: return json.dumps({'status': "waiting"}) elif "@action" in userinput and userinput["@action"] == "load_submission_input" and "submissionid" in userinput: submission = self.submission_manager.get_submission(userinput["submissionid"]) submission = self.submission_manager.get_input_from_submission(submission) submission = self.submission_manager.get_feedback_from_submission(submission, show_everything=is_staff) if not submission: raise web.notfound() web.header('Content-Type', 'application/json') return submission_to_json(submission, is_admin, True) elif "@action" in userinput and userinput["@action"] == "kill" and "submissionid" in userinput: self.submission_manager.kill_running_submission(userinput["submissionid"]) # ignore return value web.header('Content-Type', 'application/json') return json.dumps({'status': 'done'}) else: raise web.notfound() except: if web.config.debug: raise else: raise web.notfound() else: return self.template_helper.get_renderer().index(self.user_manager.get_auth_methods_fields(), False)
def POST_AUTH(self, courseid, taskid, isLTI): """ POST a new submission """ username = self.user_manager.session_username() try: course = self.course_factory.get_course(courseid) if not self.user_manager.course_is_open_to_user( course, username, isLTI): return self.template_helper.get_renderer().course_unavailable() task = course.get_task(taskid) if not self.user_manager.task_is_visible_by_user( task, username, isLTI): return self.template_helper.get_renderer().task_unavailable() self.user_manager.user_saw_task(username, courseid, taskid) is_staff = self.user_manager.has_staff_rights_on_course( course, username) is_admin = self.user_manager.has_admin_rights_on_course( course, username) userinput = web.input() if "@action" in userinput and userinput["@action"] == "customtest": # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(task) userinput = task.adapt_input_for_backend(web.input(**init_var)) if not task.input_is_consistent( userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({ "status": "error", "text": "Please answer to all the questions and verify the extensions of the files " "you want to upload. Your responses were not tested." }) try: result, grade, problems, tests, custom, archive, stdout, stderr = self.submission_manager.add_unsaved_job( task, userinput) data = { "status": ("done" if result[0] == "success" or result[0] == "failed" else "error"), "result": result[0], "text": ParsableText(result[1]).parse(), "stdout": custom.get("custom_stdout", ""), "stderr": custom.get("custom_stderr", "") } web.header('Content-Type', 'application/json') return json.dumps(data) except Exception as ex: web.header('Content-Type', 'application/json') return json.dumps({"status": "error", "text": str(ex)}) elif "@action" in userinput and userinput["@action"] == "submit": # Verify rights if not self.user_manager.task_can_user_submit( task, username, isLTI): return json.dumps({ "status": "error", "text": "You are not allowed to submit for this task." }) # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(task) userinput = task.adapt_input_for_backend(web.input(**init_var)) if not task.input_is_consistent( userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({ "status": "error", "text": "Please answer to all the questions and verify the extensions of the files " "you want to upload. Your responses were not tested." }) # Get debug info if the current user is an admin debug = is_admin if "@debug-mode" in userinput: if userinput["@debug-mode"] == "ssh" and debug: debug = "ssh" del userinput['@debug-mode'] # Start the submission try: submissionid, oldsubids = self.submission_manager.add_job( task, userinput, debug) web.header('Content-Type', 'application/json') return json.dumps({ "status": "ok", "submissionid": str(submissionid), "remove": oldsubids }) except Exception as ex: web.header('Content-Type', 'application/json') return json.dumps({"status": "error", "text": str(ex)}) elif "@action" in userinput and userinput[ "@action"] == "check" and "submissionid" in userinput: result = self.submission_manager.get_submission( userinput['submissionid']) if result is None: web.header('Content-Type', 'application/json') return json.dumps({'status': "error"}) elif self.submission_manager.is_done(result): web.header('Content-Type', 'application/json') result = self.submission_manager.get_input_from_submission( result) result = self.submission_manager.get_feedback_from_submission( result, show_everything=is_staff) # user_task always exists as we called user_saw_task before user_task = self.database.user_tasks.find_one({ "courseid": task.get_course_id(), "taskid": task.get_id(), "username": self.user_manager.session_username() }) submissionid = user_task.get('submissionid', None) default_submission = self.database.submissions.find_one( {'_id': ObjectId(submissionid) }) if submissionid else None if default_submission is None: self.set_selected_submission(course, task, userinput['submissionid']) return submission_to_json( result, is_admin, False, True if default_submission is None else default_submission['_id'] == result['_id']) else: web.header('Content-Type', 'application/json') if "ssh_host" in result: return json.dumps({ 'status': "waiting", 'ssh_host': result["ssh_host"], 'ssh_port': result["ssh_port"], 'ssh_password': result["ssh_password"] }) # Here we are waiting. Let's send some useful information. waiting_data = self.submission_manager.get_job_queue_info( result["jobid"]) if "jobid" in result else None if waiting_data is not None: nb_tasks_before, approx_wait_time = waiting_data return json.dumps({ 'status': "waiting", 'nb_tasks_before': nb_tasks_before, 'approx_wait_time': approx_wait_time }) return json.dumps({'status': "waiting"}) elif "@action" in userinput and userinput[ "@action"] == "load_submission_input" and "submissionid" in userinput: submission = self.submission_manager.get_submission( userinput["submissionid"]) submission = self.submission_manager.get_input_from_submission( submission) submission = self.submission_manager.get_feedback_from_submission( submission, show_everything=is_staff) if not submission: raise web.notfound() web.header('Content-Type', 'application/json') return submission_to_json(submission, is_admin, True) elif "@action" in userinput and userinput[ "@action"] == "kill" and "submissionid" in userinput: self.submission_manager.kill_running_submission( userinput["submissionid"]) # ignore return value web.header('Content-Type', 'application/json') return json.dumps({'status': 'done'}) elif "@action" in userinput and userinput[ "@action"] == "set_submission" and "submissionid" in userinput: web.header('Content-Type', 'application/json') if task.get_evaluate() != 'student': return json.dumps({'status': "error"}) if self.set_selected_submission(course, task, userinput["submissionid"]): return json.dumps({'status': 'done'}) else: return json.dumps({'status': 'error'}) else: raise web.notfound() except: if web.config.debug: raise else: raise web.notfound()
def LTI_POST(self): userinput = web.input() if "submissionid" in userinput and "questionid" in userinput: # Download a previously submitted file submission = self.submission_manager.get_submission( userinput["submissionid"], True) if submission is None: raise web.notfound() sinput = self.submission_manager.get_input_from_submission( submission, True) if userinput["questionid"] not in sinput: raise web.notfound() if isinstance(sinput[userinput["questionid"]], dict): # File uploaded previously mimetypes.init() mime_type = mimetypes.guess_type( urllib.pathname2url( sinput[userinput["questionid"]]['filename'])) web.header('Content-Type', mime_type[0]) return base64.b64decode( sinput[userinput["questionid"]]['value']) else: # Other file, download it as text web.header('Content-Type', 'text/plain') return sinput[userinput["questionid"]] elif "@action" in userinput and userinput["@action"] == "submit": # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(self.task) userinput = self.task.adapt_input_for_backend( web.input(**init_var)) if not self.task.input_is_consistent( userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({ "status": "error", "text": "Please answer to all the questions and verify the extensions of the files you want " "to upload. Your responses were not tested." }) del userinput['@action'] # Get debug info if the current user is an admin debug = "Administrator" in self.user_manager.session_roles() # Start the submission submissionid = self.submission_manager.add_job( self.task, userinput, debug) web.header('Content-Type', 'application/json') return json.dumps({ "status": "ok", "submissionid": str(submissionid) }) elif "@action" in userinput and userinput[ "@action"] == "check" and "submissionid" in userinput: if self.submission_manager.is_done(userinput['submissionid']): web.header('Content-Type', 'application/json') result = self.submission_manager.get_submission( userinput['submissionid']) result = self.submission_manager.get_input_from_submission( result) result = self.submission_manager.get_feedback_from_submission( result, show_everything="Administrator" in self.user_manager.session_roles()) return submission_to_json( result, "Administrator" in self.user_manager.session_roles()) else: web.header('Content-Type', 'application/json') return json.dumps({'status': "waiting"}) elif "@action" in userinput and userinput[ "@action"] == "load_submission_input" and "submissionid" in userinput: submission = self.submission_manager.get_submission( userinput["submissionid"]) submission = self.submission_manager.get_input_from_submission( submission) submission = self.submission_manager.get_feedback_from_submission( submission, show_everything="Administrator" in self.user_manager.session_roles()) if not submission: raise web.notfound() web.header('Content-Type', 'application/json') return submission_to_json( submission, "Administrator" in self.user_manager.session_roles(), True) elif "@action" in userinput and userinput[ "@action"] == "kill" and "submissionid" in userinput: self.submission_manager.kill_running_submission( userinput["submissionid"]) # ignore return value web.header('Content-Type', 'application/json') return json.dumps({'status': 'done'}) else: # Display the task itself return self.template_helper.get_renderer().task( self.course, self.task, self.submission_manager.get_user_submissions(self.task))
def LTI_POST(self): userinput = web.input() self._logger.debug('post with userinput=' + str(userinput)) is_admin = any(x in self.admin_role for x in self.user_manager.session_roles()) if "submissionid" in userinput and "questionid" in userinput: # Download a previously submitted file submission = self.submission_manager.get_submission( userinput["submissionid"], True) if submission is None: self._logger.info('Error: submission not found') raise web.notfound() sinput = self.submission_manager.get_input_from_submission( submission, True) if userinput["questionid"] not in sinput: self._logger.info('Error: questionid not found') raise web.notfound() if isinstance(sinput[userinput["questionid"]], dict): # File uploaded previously mimetypes.init() mime_type = mimetypes.guess_type( urllib.request.pathname2url( sinput[userinput["questionid"]]['filename'])) web.header('Content-Type', mime_type[0]) return base64.b64decode( sinput[userinput["questionid"]]['value']) else: # Other file, download it as text web.header('Content-Type', 'text/plain') return sinput[userinput["questionid"]] elif "@action" in userinput and userinput["@action"] == "submit": # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(self.task) userinput = self.task.adapt_input_for_backend( web.input(**init_var)) if not self.task.input_is_consistent( userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({ "status": "error", "text": "Please answer to all the questions and verify the extensions of the files you want " "to upload. Your responses were not tested." }) del userinput['@action'] # Get debug info if the current user is an admin debug = is_admin if "@debug-mode" in userinput: if userinput["@debug-mode"] == "ssh" and debug: debug = "ssh" del userinput['@debug-mode'] # Start the submission try: submissionid, oldsubids = self.submission_manager.add_job( self.task, userinput, debug) web.header('Content-Type', 'application/json') return json.dumps({ "status": "ok", "submissionid": str(submissionid), "remove": oldsubids }) except Exception as ex: web.header('Content-Type', 'application/json') return json.dumps({"status": "error", "text": str(ex)}) elif "@action" in userinput and userinput[ "@action"] == "check" and "submissionid" in userinput: result = self.submission_manager.get_submission( userinput['submissionid']) if result is None: web.header('Content-Type', 'application/json') return json.dumps({'status': "error"}) elif self.submission_manager.is_done(result): web.header('Content-Type', 'application/json') result = self.submission_manager.get_submission( userinput['submissionid']) result = self.submission_manager.get_input_from_submission( result) result = self.submission_manager.get_feedback_from_submission( result, show_everything=is_admin) return submission_to_json(result, is_admin) else: web.header('Content-Type', 'application/json') if "ssh_host" in result: return json.dumps({ 'status': "waiting", 'ssh_host': result["ssh_host"], 'ssh_port': result["ssh_port"], 'ssh_password': result["ssh_password"] }) else: return json.dumps({'status': "waiting"}) elif "@action" in userinput and userinput[ "@action"] == "load_submission_input" and "submissionid" in userinput: submission = self.submission_manager.get_submission( userinput["submissionid"]) submission = self.submission_manager.get_input_from_submission( submission) submission = self.submission_manager.get_feedback_from_submission( submission, show_everything=is_admin) if not submission: self._logger.info('ERROR: not submission') raise web.notfound() web.header('Content-Type', 'application/json') return submission_to_json(submission, is_admin, True) elif "@action" in userinput and userinput[ "@action"] == "kill" and "submissionid" in userinput: self.submission_manager.kill_running_submission( userinput["submissionid"]) # ignore return value web.header('Content-Type', 'application/json') return json.dumps({'status': 'done'}) else: # Display the task itself return self.template_helper.get_renderer().task( self.course, self.task, self.submission_manager.get_user_submissions(self.task), is_admin, self.webterm_link)
def LTI_POST(self): userinput = web.input() if "submissionid" in userinput and "questionid" in userinput: # Download a previously submitted file submission = self.submission_manager.get_submission(userinput["submissionid"], True) if submission is None: raise web.notfound() sinput = self.submission_manager.get_input_from_submission(submission, True) if userinput["questionid"] not in sinput: raise web.notfound() if isinstance(sinput[userinput["questionid"]], dict): # File uploaded previously mimetypes.init() mime_type = mimetypes.guess_type(urllib.pathname2url(sinput[userinput["questionid"]]['filename'])) web.header('Content-Type', mime_type[0]) return base64.b64decode(sinput[userinput["questionid"]]['value']) else: # Other file, download it as text web.header('Content-Type', 'text/plain') return sinput[userinput["questionid"]] elif "@action" in userinput and userinput["@action"] == "submit": # Reparse user input with array for multiple choices init_var = list_multiple_multiple_choices_and_files(self.task) userinput = self.task.adapt_input_for_backend(web.input(**init_var)) if not self.task.input_is_consistent(userinput, self.default_allowed_file_extensions, self.default_max_file_size): web.header('Content-Type', 'application/json') return json.dumps({"status": "error", "text": "Please answer to all the questions and verify the extensions of the files you want " "to upload. Your responses were not tested."}) del userinput['@action'] # Get debug info if the current user is an admin debug = "Administrator" in self.user_manager.session_roles() # Start the submission submissionid = self.submission_manager.add_job(self.task, userinput, debug) web.header('Content-Type', 'application/json') return json.dumps({"status": "ok", "submissionid": str(submissionid)}) elif "@action" in userinput and userinput["@action"] == "check" and "submissionid" in userinput: if self.submission_manager.is_done(userinput['submissionid']): web.header('Content-Type', 'application/json') result = self.submission_manager.get_submission(userinput['submissionid']) result = self.submission_manager.get_input_from_submission(result) result = self.submission_manager.get_feedback_from_submission(result, show_everything="Administrator" in self.user_manager.session_roles()) return submission_to_json(result, "Administrator" in self.user_manager.session_roles()) else: web.header('Content-Type', 'application/json') return json.dumps({'status': "waiting"}) elif "@action" in userinput and userinput["@action"] == "load_submission_input" and "submissionid" in userinput: submission = self.submission_manager.get_submission(userinput["submissionid"]) submission = self.submission_manager.get_input_from_submission(submission) submission = self.submission_manager.get_feedback_from_submission(submission, show_everything="Administrator" in self.user_manager.session_roles()) if not submission: raise web.notfound() web.header('Content-Type', 'application/json') return submission_to_json(submission, "Administrator" in self.user_manager.session_roles(), True) elif "@action" in userinput and userinput["@action"] == "kill" and "submissionid" in userinput: self.submission_manager.kill_running_submission(userinput["submissionid"]) # ignore return value web.header('Content-Type', 'application/json') return json.dumps({'status': 'done'}) else: # Display the task itself return self.template_helper.get_renderer().task(self.course, self.task, self.submission_manager.get_user_submissions(self.task))