diff --git a/app.py b/app.py index 134baf3..2bee653 100644 --- a/app.py +++ b/app.py @@ -200,13 +200,16 @@ def _get_problem_info(problem_id): problem_statement = change_md_to_html('{}/{}/statement.md'.format(PROBLEM_INFO_PATH, problem_id), '

No problem statement available.

') + # Get bonus (if there is any) + bonus = change_md_to_html('{}/{}/bonus.md'.format(PROBLEM_INFO_PATH, problem_id), 'No bonus available.') + # Get hints (if there are any) hints = change_md_to_html('{}/{}/hints.md'.format(PROBLEM_INFO_PATH, problem_id), 'No hints available.') # Return only the info that the client needs to know about the problem return {'id': pinfo['problem_id'], 'name': pinfo['problem_name'], 'time_limit': pinfo['time_limit'], 'memory_limit': pinfo['memory_limit'], 'max_score': pinfo['max_score'], - 'statement': problem_statement, 'hints': hints, + 'statement': problem_statement, 'bonus': bonus, 'hints': hints, 'difficulty': pinfo['difficulty'] if 'difficulty' in pinfo else ''} @@ -236,6 +239,10 @@ def handle_submission(): code_filename, code_extension = os.path.splitext(sec_filename) if request.form['type'] == 'java' and code_extension != '.java': return json_error('Missing .java file extension!') + elif request.form['type'] == 'cpp' and code_extension != '.cpp': + return json_error('Missing .cpp file extension!') + elif request.form['type'] == 'python' and code_extension != '.py': + return json_error('Missing .py file extension!') # Make a temporary directory / save files there tempdir = tempfile.mkdtemp(prefix='judge-') @@ -276,7 +283,7 @@ def _get_status(job_id): elif job.is_failed: return {'status': 'internal_error', 'error': 'JOB_FAILED', 'job_id': job_id}, 200 else: - return job.meta, 202 + return job.meta, 202 if job.meta['status'] != 'done' else 200 if __name__ == "__main__": diff --git a/judge_submission.py b/judge_submission.py index 5a4f55a..64129a6 100644 --- a/judge_submission.py +++ b/judge_submission.py @@ -304,15 +304,12 @@ def run_subtask(isolate_dir, problem_info, problem_folder, subtask_info, compile max_time = max(run_verdict['time'], max_time) max_memory = max(run_verdict['memory'], max_memory) - # Update job meta, but don't reveal any bonus verdicts + # Update job meta if problem_info['scoring_method'] in ['average', 'average_stop']: job.meta['score'][subtask_i] = score_sum / len(test_inputs) * subtask_info['score'] - if run_verdict['verdict'] == 'AC' or 'is_bonus' not in subtask_info or not subtask_info['is_bonus']: - job.meta['subtasks'][subtask_i][test_i][0] = run_verdict['verdict'] - job.meta['subtasks'][subtask_i][test_i][1] = run_verdict['time'] - job.meta['subtasks'][subtask_i][test_i][2] = run_verdict['memory'] - else: - job.meta['subtasks'][subtask_i][test_i][0] = 'SK' + job.meta['subtasks'][subtask_i][test_i][0] = run_verdict['verdict'] + job.meta['subtasks'][subtask_i][test_i][1] = run_verdict['time'] + job.meta['subtasks'][subtask_i][test_i][2] = run_verdict['memory'] job.save_meta() # If first wrong answer, track results @@ -472,12 +469,15 @@ def judge_submission(tempdir, problem_id, code_filename, code_type, username): curr_testcase += testcase_count # Do some final cleanup - final_score = round(final_score, 2) + final_score = round(final_score) if testcase == -1: testcase = curr_testcase if final_score > problem_info['max_score']: # AC* :O final_verdict = 'AC*' + job.meta['status'] = 'done' + job.meta['final_score'] = final_score + job.save_meta() # Add submission result to Redis database with open(isolate_dir + '/' + code_filename, 'r') as fcode: @@ -487,8 +487,14 @@ def judge_submission(tempdir, problem_id, code_filename, code_type, username): # Send POST request to webhook URL if WEBHOOK_URL is not None: try: - requests.post(WEBHOOK_URL, data={'problem_id': problem_info['problem_id'], 'username': username, - 'score': final_score, 'job_id': job.get_id()}, timeout=10) + if DEBUG_LOW: + log('Sending POST request to ' + WEBHOOK_URL) + req = requests.post(WEBHOOK_URL, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246'}, + data={'problem_id': problem_info['problem_id'], 'username': username, + 'score': final_score, 'job_id': job.get_id(), + 'secret_key': SECRET_KEY}, timeout=10) + if DEBUG_LOW: + log('Response code: ' + str(req)) except Exception as e: return verdict_error('WEBHOOK_FAIL') diff --git a/misc/redis.conf b/misc/redis.conf index 0a962b6..d4de3f3 100644 --- a/misc/redis.conf +++ b/misc/redis.conf @@ -202,12 +202,6 @@ always-show-logo yes # Will save the DB if both the given number of seconds and the given # number of write operations against the DB occurred. # -# In the example below the behaviour will be to save: -# after 600 sec (10 min) if at least 5 key changed -# after 180 sec (3 min) if at least 10 keys changed -# after 60 sec (1 min) if at least 100 keys changed -# after 30 sec if at least 500 keys changed -# # Note: you can disable saving completely by commenting out all "save" lines. # # It is also possible to remove all the previously configured save @@ -216,10 +210,9 @@ always-show-logo yes # # save "" -save 600 5 -save 180 10 +save 900 1 +save 300 10 save 60 100 -save 30 500 # By default Redis will stop accepting writes if RDB snapshots are enabled # (at least one save point) and the latest background save failed. diff --git a/sample_problem_info/test/solutions/wrong.cpp b/sample_problem_info/test/solutions/wrong.cpp index 075e9ef..949babd 100644 --- a/sample_problem_info/test/solutions/wrong.cpp +++ b/sample_problem_info/test/solutions/wrong.cpp @@ -1,40 +1,40 @@ -#include - -int main() { - int N; - std::cin >> N; - - int sum = 238947324; - if (N == 2 || N == 9) { - for (int i = 0; i < 10000; i++) { - sum *= (i+1); - sum += (sum % i); - sum -= i*9123479; - } - } - - if (N == 4) { - int SIZE = 300000000; - int arr[SIZE]; - for (int i = 2; i < SIZE; i++) { - arr[i] = arr[i-1] * arr[i-2] % arr[i-1] + 817; - } - std::cerr << arr[SIZE-1] << std::endl; - } - - if (N == 5 || N == 8) { - N--; - } - - if (N == 7) { - for (int i = 0; i < 800000000; i++) { - sum *= (i+1); - sum += (sum % (i+1)); - sum -= i*9123479; - } - } - - std::cerr << sum; - std::cout << N; - return 0; -} +#include + +int main() { + int N; + std::cin >> N; + + int sum = 238947324; + if (N == 2 || N == 9) { + for (int i = 0; i < 10000; i++) { + sum *= (i+1); + sum += (sum % i); + sum -= i*9123479; + } + } + + if (N == 4) { + int SIZE = 300000000; + int arr[SIZE]; + for (int i = 2; i < SIZE; i++) { + arr[i] = arr[i-1] * arr[i-2] % arr[i-1] + 817; + } + std::cerr << arr[SIZE-1] << std::endl; + } + + if (N == 5 || N == 8) { + N++; + } + + if (N == 7) { + for (int i = 0; i < 800000000; i++) { + sum *= (i+1); + sum += (sum % (i+1)); + sum -= i*9123479; + } + } + + std::cerr << sum; + std::cout << N; + return 0; +} diff --git a/static/status.js b/static/status.js index 60eecbd..04b6d2a 100644 --- a/static/status.js +++ b/static/status.js @@ -51,7 +51,7 @@ function handleRequestError() { setTimeout(runInterval, numFailed * 2 * QUERY_DELAY); } -function displayTestResult(verdict, subtask, test, time=0, memory=0) { +function displayTestResult(verdict, subtask, test, isBonus, time=0, memory=0) { let testResultsBox = document.querySelector("#submission-result-box .test-results-box"); let template = document.querySelector("#test-result"); @@ -67,18 +67,18 @@ function displayTestResult(verdict, subtask, test, time=0, memory=0) { if (subtask != 0) testNumber.innerText = subtask + "-" + test; else testNumber.innerText = test; - if (verdict == "AC" || verdict == "BO") { + if (verdict == "AC") { tooltip.setAttribute("title", "Correct answer"); - testResult.classList.add(verdict == "AC" ? "test-result-pass" : "test-result-bonus"); + testResult.classList.add(isBonus ? "test-result-bonus" : "test-result-pass"); testVerdict.innerText = "*"; testMemory.innerText = memory + "mb"; testTime.innerText = time + "ms"; } else if (verdict == "SK") { tooltip.setAttribute("title", "Test skipped"); - testResult.classList.add("test-result-fail"); + testResult.classList.add(isBonus ? "test-result-skipped" : "test-result-fail"); testVerdict.innerText = "-"; } else { - testResult.classList.add("test-result-fail"); + testResult.classList.add(isBonus ? "test-result-skipped" : "test-result-fail"); if (verdict == "WA") { tooltip.setAttribute("title", "Wrong answer"); testVerdict.innerText = "x"; @@ -135,14 +135,21 @@ function updateResults(resp) { for (let i = 0; i < resp["subtasks"].length; i++) { let subtask = resp["subtasks"][i]; let subtaskNum = i+1; + let subtaskIsBonus = resp["is_bonus"][i] == 1; + let atLeast1AC = false; + for (let j = 0; j < subtask.length; j++) { + let test = subtask[j] + if (test[0] == "AC") { + atLeast1AC = true; + break; + } + } for (let j = 0; j < subtask.length; j++) { let test = subtask[j]; if (test[0] != "--") { testsCompleted++; - if (resp["is_bonus"][i] == 1 && test[0] == "AC") { - displayTestResult("BO", printSubtasks ? i+1 : 0, printSubtasks ? j+1 : testsTotal+j+1, test[1], test[2].toFixed(1)); - } else if (resp["is_bonus"][i] == 0) { - displayTestResult(test[0], printSubtasks ? i+1 : 0, printSubtasks ? j+1 : testsTotal+j+1, test[1], test[2].toFixed(1)); + if (!subtaskIsBonus || atLeast1AC) { + displayTestResult(test[0], printSubtasks ? i+1 : 0, printSubtasks ? j+1 : testsTotal+j+1, subtaskIsBonus, test[1], test[2].toFixed(1)); } } } diff --git a/static/style.css b/static/style.css index 6af7027..fe65ee0 100644 --- a/static/style.css +++ b/static/style.css @@ -53,6 +53,7 @@ h2 { padding: 10px; margin: 20px; font-weight: bold; + overflow-wrap: anywhere; } .submission-result-compile-error { diff --git a/static/submit.js b/static/submit.js index c6f34d6..6405d86 100644 --- a/static/submit.js +++ b/static/submit.js @@ -1,3 +1,15 @@ +function toggleBonus() { + let bonusButton = document.getElementById("bonus-button"); + let bonusContainer = document.getElementById("bonus-container"); + if (bonusContainer.style.display === "none") { + bonusButton.innerText = "Hide Bonus"; + bonusContainer.style.display = "block"; + } else { + bonusButton.innerText = "Show Bonus"; + bonusContainer.style.display = "none"; + } +} + function toggleHints() { let hintButton = document.getElementById("hint-button"); let hintContainer = document.getElementById("hint-container"); diff --git a/templates/form.html b/templates/form.html index af28ee7..cecb1d4 100644 --- a/templates/form.html +++ b/templates/form.html @@ -12,7 +12,7 @@

Test Submission Form

-
+

@@ -34,7 +34,7 @@

Test Submission Form

- +