def submit(): """ Retrieves the submission information from the request, creates a submission, then begins the submissions execution. The response simply returns an empty object for data. (In the future, this will return the handle to a web socket). :return: serves a 200 request code and an empty object if it is a good request, 403 if the filetype is unsupproted, 400 if the required fields are missing. """ uploaded_file = request.files['file'] if not uploaded_file: return serve_error('file must be uploaded', response_code=400) if not judge.allowed_filetype(uploaded_file.filename): return serve_error('filename not allowed', response_code=403) if not request.form['pid']: return serve_error('the field \'pid\' must be specified', response_code=400) attempt = models.Submission( username=current_user.username, pid=request.form['pid'].lower(), submit_time=int(time.time()), auto_id=0, file_type=uploaded_file.filename.split('.')[-1].lower(), result='start') attempt.commit_to_session() thread = Thread( target=judge.evaluate, args=(attempt, uploaded_file)) thread.daemon = False thread.start() return serve_response({ 'submissionId': attempt.job })
def _run(self): """Times all of the problems in the problem's test folder. This will iterate through all of the files in the problem's test folder. For each file, it creates a mock submission (so that it does not have to store a submission in the database), and a "Mock" upload file. The "Mock" upload file still depends on the computer's filesystem, because the Judge is dependent upon the computer's filesystem. Each file is run in serial, and the maximum time of all of the judge submissions, times 1.5 (just to give people some wiggle-room). Then, it is "standardized" by dividing by the judge's TIMEOUT_MULTIPLIER for the given file type. :raises NoJudgeSolutionError: in the event that no judge solution is found for the given problem. """ files = os.listdir(self.path) judged_count = 0 found_max = 0 problem_details = (database.session.query(models.Problem) .filter(models.Problem.pid == self.problem.pid).first()) print('Judging', problem_details.name, '...', file=sys.stderr) for fname in files: source = os.path.join(self.path, fname) if not os.path.isfile(source): continue if not judge.allowed_filetype(fname): raise UnsupportedFileTypeError(fname, self.problem.pid) print(' Trying', fname, '...', file=sys.stderr) file_type = fname.rsplit('.', 1)[1].lower() sub = MockSubmission( pid=self.problem.pid, file_type=file_type, job=self.problem.pid ) submission_path = os.path.join(self.submission_path, str(sub.job)) upload = MockUploadFile(source) upload.save(os.path.join(submission_path, fname)) judgement = judge.Judge(sub.pid, submission_path, upload, TIME_LIMIT) status, time = judgement.run() if status == judge.CORRECT_ANSWER: judged_count += 1 time_limit = int(math.ceil( time * 1.5 / judge.TIMEOUT_MULTIPLIER[file_type])) found_max = max(found_max, time_limit) self.problem.time_limit = found_max self.problem.commit_to_session() if judged_count == 0: raise NoJudgeSolutionsError(self.problem.pid, problem_details.name) print('Judged', problem_details.name, 'with time', found_max)
def submit(): """ Retrieves the submission information from the request, creates a submission, then begins the submissions execution. The response is simply a submission identifier of the new submission. :return: serves a 200 request code and an empty object if it is a good request, 403 if the filetype is unsupproted, 400 if the required fields are missing. """ uploaded_file = request.files['file'] if not uploaded_file: return serve_error('file must be uploaded', response_code=400) if not judge.allowed_filetype(uploaded_file.filename): return serve_error('filename not allowed', response_code=403) if not request.form['pid']: return serve_error('the field \'pid\' must be specified', response_code=400) # Obtain the time limit for the problem time_limit = session.query(ProblemData).\ options(load_only("pid", "time_limit")).\ filter(ProblemData.pid==request.form['pid']).\ first().time_limit ext = uploaded_file.filename.split('.')[-1].lower() if 'python' in request.form: ext = request.form['python'] attempt = models.Submission( username=current_user.username, pid=request.form['pid'], submit_time=int(time.time()), auto_id=0, file_type=ext, result='start') attempt.commit_to_session() directory = directory_for_submission(attempt) os.mkdir(directory) uploaded_file.save(os.path.join(directory, uploaded_file.filename)) judge.Judge(attempt, uploaded_file, time_limit).run_threaded() return serve_response({ 'submissionId': attempt.job })
def submit(): """ Retrieves the submission information from the request, creates a submission, then begins the submissions execution. The response is simply a submission identifier of the new submission. :return: serves a 200 request code and an empty object if it is a good request, 403 if the filetype is unsupproted, 400 if the required fields are missing. """ uploaded_file = request.files['file'] if not uploaded_file: return serve_error('file must be uploaded', response_code=400) if not judge.allowed_filetype(uploaded_file.filename): return serve_error('filename not allowed', response_code=403) if not request.form['pid']: return serve_error('the field \'pid\' must be specified', response_code=400) # Obtain the time limit for the problem time_limit = session.query(ProblemData).\ options(load_only("pid", "time_limit")).\ filter(ProblemData.pid==request.form['pid']).\ first().time_limit ext = uploaded_file.filename.rsplit('.')[1].lower() if 'python' in request.form: ext = request.form['python'] attempt = models.Submission( username=current_user.username, pid=request.form['pid'], submit_time=int(time.time()), auto_id=0, file_type=ext, result='start') attempt.commit_to_session() submission_path = os.path.join(app.config['DATA_FOLDER'], 'submits', str(attempt.job)) os.mkdir(submission_path) uploaded_file.save(os.path.join(submission_path, uploaded_file.filename)) def update_status(status, test_number): """Updates the status of the submission and notifies the clients that the submission has a new status. """ attempt.update_status(status) Flasknado.emit('status', { 'submissionId': attempt.job, 'problemId': attempt.pid, 'username': attempt.username, 'submitTime': attempt.submit_time, 'testNum': test_number, 'status': judge.EVENT_STATUS[status] }) judge.Judge(attempt.pid, submission_path, uploaded_file, time_limit, update_status).run_threaded() return serve_response({ 'submissionId': attempt.job })