def getUserResults(req, courseId, assignmentId, username): """Get the results for a given username""" req.content_type = 'text/html' strout = websutil.OutputString() try: vmcfg = config.CourseConfig(CourseList().course_config(courseId)) except: traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "", 'errorTrace' : strout.get()}) vmpaths = paths.VmcheckerPaths(vmcfg.root_path()) submission_dir = vmpaths.dir_cur_submission_root(assignmentId, username) r_path = paths.dir_submission_results(submission_dir) strout = websutil.OutputString() try: result_files = [] if os.path.isdir(r_path): update_db.update_grades(courseId, user=username, assignment=assignmentId) for fname in os.listdir(r_path): # skill all files not ending in '.vmr' if not fname.endswith('.vmr'): continue f_path = os.path.join(r_path, fname) if os.path.isfile(f_path): overflow_msg = '' f_size = os.path.getsize(f_path) if f_size > MAX_VMR_FILE_SIZE: overflow_msg = '\n\n<b>File truncated! Actual size: ' + str(f_size) + ' bytes</b>\n' # decode as utf-8 and ignore any errors, because # characters will be badly encoded as json. with codecs.open(f_path, 'r', encoding='utf-8', errors='ignore') as f: result_files.append({fname : (f.read(MAX_VMR_FILE_SIZE) + overflow_msg) }) if len(result_files) == 0: msg = "In the meantime have a fortune cookie: <blockquote>" try: process = subprocess.Popen('/usr/games/fortune', shell=False, stdout=subprocess.PIPE) msg += process.communicate()[0] + "</blockquote>" except: msg += "Knock knock. Who's there? [Silence] </blockquote>" result_files = [ {'fortune.vmr' : msg } ] result_files.append({'queue-contents.vmr' : websutil.get_test_queue_contents(courseId) }) result_files.append({'late-submission.vmr' : websutil.submission_upload_info(courseId, username, assignmentId)}) result_files = websutil.sortResultFiles(result_files) return json.dumps(result_files) except: traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "", 'errorTrace' : strout.get()})
def uploadAssignmentMd5(req, courseId, assignmentId, md5Sum): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({'errorType':ERR_AUTH, 'errorMessage':"", 'errorTrace':""}) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file = strout) return json.dumps({'errorType':ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) # Reset the timeout s.save() # Save file in a temp (fd, tmpname) = tempfile.mkstemp('.txt') with open(tmpname, 'wb', 10000) as f: f.write(md5Sum) os.close(fd) # Call submit.py ## Redirect stdout to catch logging messages from submit strout = websutil.OutputString() sys.stdout = strout try: submit.submit(tmpname, assignmentId, username, courseId) update_db.update_grades(courseId, user=username, assignment=assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file = strout) return json.dumps({'errorType':ERR_EXCEPTION, 'errorMessage':"Tema trimisa prea curand", 'errorTrace':strout.get()}) except: traceback.print_exc(file = strout) return json.dumps({'errorType':ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) return json.dumps({'status':True, 'dumpLog':strout.get()})
def getAllGrades(req, courseId): """Returns a table with all the grades of all students for a given course""" req.content_type = 'text/html' try: update_db.update_grades(courseId) vmcfg = CourseConfig(CourseList().course_config(courseId)) vmpaths = paths.VmcheckerPaths(vmcfg.root_path()) db_conn = sqlite3.connect(vmpaths.db_file()) assignments = vmcfg.assignments() sorted_assg = sorted(assignments, lambda x, y: int(assignments.get(x, "OrderNumber")) - int(assignments.get(y, "OrderNumber"))) grades = {} try: db_cursor = db_conn.cursor() db_cursor.execute( 'SELECT users.name, assignments.name, grades.grade ' 'FROM users, assignments, grades ' 'WHERE 1 ' 'AND users.id = grades.user_id ' 'AND assignments.id = grades.assignment_id') for row in db_cursor: user, assignment, grade = row grades.setdefault(user, {})[assignment] = grade db_cursor.close() finally: db_conn.close() ret = [] for user in sorted(grades.keys()): ret.append({'studentName' : user, 'studentId' : user, 'results' : grades.get(user)}) return json.dumps(ret) except: strout = websutil.OutputString() traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "", 'errorTrace' : strout.get()})
def uploadedFile(req, courseId, assignmentId, tmpname, locale=websutil.DEFAULT_LOCALE): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" websutil.install_i18n(websutil.sanityCheckLocale(locale)) websutil.sanityCheckAssignmentId(assignmentId) websutil.sanityCheckCourseId(courseId) # TODO a better check is needed for tmpname websutil.sanityCheckDotDot(tmpname) # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({ 'errorType': websutil.ERR_AUTH, 'errorMessage': "", 'errorTrace': "" }) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) # Reset the timeout s.save() # Call submit.py ## Redirect stdout to catch logging messages from submit sys.stdout = strout (hasTeam, account) = websutil.getAssignmentAccountName(courseId, assignmentId, username, strout) try: if hasTeam: submit.submit(tmpname, assignmentId, account, courseId, user=username) else: submit.submit(tmpname, assignmentId, account, courseId) update_db.update_grades(courseId, account, assignment=assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': _("Sent too fast"), 'errorTrace': strout.get() }) except submit.SubmittedTooLateError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': _("The assignment was submitted too late"), 'errorTrace': strout.get() }) except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) return json.dumps({'status': True, 'dumpLog': strout.get()})
def uploadAssignment(req, courseId, assignmentId, archiveFile, locale=websutil.DEFAULT_LOCALE): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" websutil.install_i18n(websutil.sanityCheckLocale(locale)) websutil.sanityCheckAssignmentId(assignmentId) websutil.sanityCheckCourseId(courseId) # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({ 'errorType': websutil.ERR_AUTH, 'errorMessage': "", 'errorTrace': "" }) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) # Reset the timeout s.save() if archiveFile.filename == None: return json.dumps({ 'errorType': websutil.ERR_OTHER, 'errorMessage': _("File not uploaded."), 'errorTrace': "" }) # Save file in a temp location with tempfile.NamedTemporaryFile( suffix='.zip', bufsize=websutil.FILE_BUF_SIZE) as tmpfile: shutil.copyfileobj(archiveFile.file, tmpfile, websutil.FILE_BUF_SIZE) tmpfile.flush() # Call submit.py ## Redirect stdout to catch logging messages from submit sys.stdout = strout (hasTeam, account) = websutil.getAssignmentAccountName(courseId, assignmentId, username, strout) try: if hasTeam: submit.submit(tmpfile.name, assignmentId, account, courseId, user=username) else: submit.submit(tmpfile.name, assignmentId, account, courseId) update_db.update_grades(courseId, account, assignment=assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': _("The assignment was submitted too soon"), 'errorTrace': strout.get() }) except submit.SubmittedTooLateError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': _("The assignment was submitted too late"), 'errorTrace': strout.get() }) except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) return json.dumps({ 'status': True, 'dumpLog': strout.get(), 'file': tmpfile.name })
def getResultsHelper(courseId, assignmentId, currentUser, strout, username = None, teamname = None, currentTeam = None): # assume that the session was already checked if username != None and teamname != None: return json.dumps({'errorType' : ERR_OTHER, 'errorMessage' : "Can't query both user and team results at the same time.", 'errorTrace' : ""}) try: vmcfg = StorerCourseConfig(CourseList().course_config(courseId)) except: traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "", 'errorTrace' : strout.get()}) # Check if the current user is allowed to view any other user's grade. # TODO: This should be implemented neater using some group # and permission model. is_authorized = vmcfg.public_results() or \ currentUser in vmcfg.admin_list() or \ username == currentUser or \ teamname == currentTeam if not is_authorized: traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "User is not authorized to view results.", 'errorTrace' : strout.get()}) vmpaths = paths.VmcheckerPaths(vmcfg.root_path()) account = None if username != None: # Get the individual results for this user account = username isTeamAccount = False elif teamname != None: # Get the team results for this team account = teamname isTeamAccount = True else: # Check if the user is part of a team with a mutual account for this submission (isTeamAccount, account) = getAssignmentAccountName(courseId, assignmentId, currentUser, strout) submission_dir = vmpaths.dir_cur_submission_root(assignmentId, account) r_path = paths.dir_submission_results(submission_dir) assignments = vmcfg.assignments() ignored_vmrs = assignments.ignored_vmrs(assignmentId) try: isGraded = False result_files = [] if os.path.isdir(r_path): update_db.update_grades(courseId, account=account, assignment=assignmentId) for fname in os.listdir(r_path): # skill all files not ending in '.vmr' if not fname.endswith('.vmr'): continue if fname in ignored_vmrs: continue f_path = os.path.join(r_path, fname) if os.path.isfile(f_path): overflow_msg = u"" f_size = os.path.getsize(f_path) if f_size > MAX_VMR_FILE_SIZE: overflow_msg = '\n\n' + _('File truncated! Actual size') + ': ' + str(f_size) + ' ' + _('bytes') + '\n' # decode as utf-8 and ignore any errors, because # characters will be badly encoded as json. with codecs.open(f_path, 'r', encoding='utf-8', errors='ignore') as f: content = f.read(MAX_VMR_FILE_SIZE) + overflow_msg.decode("utf-8") content = xssescape(content) result_files.append({fname : content}) if fname == 'grade.vmr' and \ "".join(content.split()) not in submissions.GENERATED_STATUSES: isGraded = True if (len(result_files) == 1 and result_files[0].keys()[0] == "grade.vmr") and \ not vmcfg.assignments().submit_only(assignmentId): msg = _("In the meantime have a fortune cookie") + ": <blockquote>" try: process = subprocess.Popen('/usr/games/fortune', shell=False, stdout=subprocess.PIPE) msg += process.communicate()[0] + "</blockquote>" except: msg += "Knock knock. Who's there? [Silence] </blockquote>" result_files = [ {'fortune.vmr' : msg } ] result_files.append({'queue-contents.vmr' : get_test_queue_contents(vmcfg, courseId) }) if 'submission.vmr' not in ignored_vmrs: result_files.append({'submission.vmr' : submission_upload_info(vmcfg, courseId, assignmentId, account, isTeamAccount, isGraded)}) result_files = sortResultFiles(result_files) return json.dumps(result_files) except: traceback.print_exc(file = strout) return json.dumps({'errorType' : ERR_EXCEPTION, 'errorMessage' : "", 'errorTrace' : strout.get()})
def uploadAssignment(req, courseId, assignmentId, archiveFile): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" websutil.sanityCheckAssignmentId(assignmentId) websutil.sanityCheckCourseId(courseId) # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({ 'errorType': websutil.ERR_AUTH, 'errorMessage': "", 'errorTrace': "" }) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) # Reset the timeout s.save() if archiveFile.filename == None: return json.dumps({ 'errorType': websutil.ERR_OTHER, 'errorMessage': "File not uploaded.", 'errorTrace': "" }) # Save file in a temp (fd, tmpname) = tempfile.mkstemp('.zip') f = open(tmpname, 'wb', 10000) ## Read the file in chunks for chunk in websutil.fbuffer(archiveFile.file): f.write(chunk) f.close() os.close(fd) # Call submit.py ## Redirect stdout to catch logging messages from submit strout = websutil.OutputString() sys.stdout = strout try: submit.submit(tmpname, assignmentId, username, courseId) update_db.update_grades(courseId, user=username, assignment=assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "The assignment was submitted too soon", 'errorTrace': strout.get() }) except submit.SubmittedTooLateError: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "The assignment was submitted too late", 'errorTrace': strout.get() }) except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': websutil.ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) return json.dumps({ 'status': True, 'dumpLog': strout.get(), 'file': tmpname })
def uploadAssignment(req, courseId, assignmentId, archiveFile, locale=websutil.DEFAULT_LOCALE): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" websutil.install_i18n(websutil.sanityCheckLocale(locale)) websutil.sanityCheckAssignmentId(assignmentId) websutil.sanityCheckCourseId(courseId) # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({'errorType':websutil.ERR_AUTH, 'errorMessage':"", 'errorTrace':""}) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) # Reset the timeout s.save() if archiveFile.filename == None: return json.dumps({'errorType':websutil.ERR_OTHER, 'errorMessage':_("File not uploaded."), 'errorTrace':""}) # Save file in a temp (fd, tmpname) = tempfile.mkstemp('.zip') f = open(tmpname, 'wb', 10000) ## Read the file in chunks for chunk in websutil.fbuffer(archiveFile.file): f.write(chunk) f.close() os.close(fd) # Call submit.py ## Redirect stdout to catch logging messages from submit sys.stdout = strout (hasTeam, account) = websutil.getAssignmentAccountName(courseId, assignmentId, username, strout) try: if hasTeam: submit.submit(tmpname, assignmentId, account, courseId, user = username) else: submit.submit(tmpname, assignmentId, account, courseId) update_db.update_grades(courseId, account, assignment = assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':_("The assignment was submitted too soon"), 'errorTrace':strout.get()}) except submit.SubmittedTooLateError: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':_("The assignment was submitted too late"), 'errorTrace':strout.get()}) except: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) return json.dumps({'status':True, 'dumpLog':strout.get(), 'file': tmpname})
def uploadedFile(req, courseId, assignmentId, tmpname, locale=websutil.DEFAULT_LOCALE): """ Saves a temp file of the uploaded archive and calls vmchecker.submit.submit method to put the homework in the testing queue""" websutil.install_i18n(websutil.sanityCheckLocale(locale)) websutil.sanityCheckAssignmentId(assignmentId) websutil.sanityCheckCourseId(courseId) # TODO a better check is needed for tmpname websutil.sanityCheckDotDot(tmpname) # Check permission req.content_type = 'text/html' s = Session.Session(req) if s.is_new(): s.invalidate() return json.dumps({'errorType':websutil.ERR_AUTH, 'errorMessage':"", 'errorTrace':""}) strout = websutil.OutputString() try: s.load() username = s['username'] except: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) # Reset the timeout s.save() # Call submit.py ## Redirect stdout to catch logging messages from submit sys.stdout = strout (hasTeam, account) = websutil.getAssignmentAccountName(courseId, assignmentId, username, strout) try: if hasTeam: submit.submit(tmpname, assignmentId, account, courseId, user = username) else: submit.submit(tmpname, assignmentId, account, courseId) update_db.update_grades(courseId, account, assignment = assignmentId) except submit.SubmittedTooSoonError: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':_("Sent too fast"), 'errorTrace':strout.get()}) except submit.SubmittedTooLateError: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':_("The assignment was submitted too late"), 'errorTrace':strout.get()}) except: traceback.print_exc(file = strout) return json.dumps({'errorType':websutil.ERR_EXCEPTION, 'errorMessage':"", 'errorTrace':strout.get()}) return json.dumps({'status':True, 'dumpLog':strout.get()})
def getResultsHelper(courseId, assignmentId, currentUser, strout, username=None, teamname=None, currentTeam=None): # assume that the session was already checked if username != None and teamname != None: return json.dumps({ 'errorType': ERR_OTHER, 'errorMessage': "Can't query both user and team results at the same time.", 'errorTrace': "" }) try: vmcfg = StorerCourseConfig(CourseList().course_config(courseId)) except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() }) # Check if the current user is allowed to view any other user's grade. # TODO: This should be implemented neater using some group # and permission model. is_authorized = vmcfg.public_results() or \ currentUser in vmcfg.admin_list() or \ username == currentUser or \ teamname == currentTeam if not is_authorized: traceback.print_exc(file=strout) return json.dumps({ 'errorType': ERR_EXCEPTION, 'errorMessage': "User is not authorized to view results.", 'errorTrace': strout.get() }) vmpaths = paths.VmcheckerPaths(vmcfg.root_path()) account = None if username != None: # Get the individual results for this user account = username isTeamAccount = False elif teamname != None: # Get the team results for this team account = teamname isTeamAccount = True else: # Check if the user is part of a team with a mutual account for this submission (isTeamAccount, account) = getAssignmentAccountName(courseId, assignmentId, currentUser, strout) submission_dir = vmpaths.dir_cur_submission_root(assignmentId, account) r_path = paths.dir_submission_results(submission_dir) assignments = vmcfg.assignments() ignored_vmrs = assignments.ignored_vmrs(assignmentId) try: isGraded = False result_files = [] if os.path.isdir(r_path): update_db.update_grades(courseId, account=account, assignment=assignmentId) for fname in os.listdir(r_path): # skill all files not ending in '.vmr' if not fname.endswith('.vmr'): continue if fname in ignored_vmrs: continue f_path = os.path.join(r_path, fname) if os.path.isfile(f_path): overflow_msg = '' f_size = os.path.getsize(f_path) if f_size > MAX_VMR_FILE_SIZE: overflow_msg = '\n\n' + _( 'File truncated! Actual size') + ': ' + str( f_size) + ' ' + _('bytes') + '\n' # decode as utf-8 and ignore any errors, because # characters will be badly encoded as json. with codecs.open(f_path, 'r', encoding='utf-8', errors='ignore') as f: content = f.read(MAX_VMR_FILE_SIZE) + overflow_msg content = xssescape(content) result_files.append({fname: content}) if fname == 'grade.vmr' and \ "".join(content.split()) not in submissions.GENERATED_STATUSES: isGraded = True if (len(result_files) == 1 and result_files[0].keys()[0] == "grade.vmr") and \ not vmcfg.assignments().submit_only(assignmentId): msg = _("In the meantime have a fortune cookie") + ": <blockquote>" try: process = subprocess.Popen('/usr/games/fortune', shell=False, stdout=subprocess.PIPE) msg += process.communicate()[0] + "</blockquote>" except: msg += "Knock knock. Who's there? [Silence] </blockquote>" result_files = [{'fortune.vmr': msg}] result_files.append({ 'queue-contents.vmr': get_test_queue_contents(vmcfg, courseId) }) if 'submission.vmr' not in ignored_vmrs: result_files.append({ 'submission.vmr': submission_upload_info(vmcfg, courseId, assignmentId, account, isTeamAccount, isGraded) }) result_files = sortResultFiles(result_files) return json.dumps(result_files) except: traceback.print_exc(file=strout) return json.dumps({ 'errorType': ERR_EXCEPTION, 'errorMessage': "", 'errorTrace': strout.get() })