diff --git a/.gitignore b/.gitignore index 9380dba..8cfbd3f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,11 @@ *.py[co] *.mo *~ -dmoj/local_settings.py +# dmoj/local_settings.py resources/style.css resources/content-description.css resources/ranks.css resources/table.css sass_processed + + diff --git a/ b/ new file mode 100644 index 0000000..83027ee --- /dev/null +++ b/ @@ -0,0 +1,556 @@ +INFO 2020-01-23 20:59:54,926 judgehandler Judge connected from: ('127.0.0.1', 49606) +INFO 2020-01-23 20:59:54,927 judgehandler Judge authenticated: ('127.0.0.1', 49606) (judge1) +INFO 2020-01-23 21:00:43,918 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:00:43,922 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:00:43,963 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:03,244 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:10,754 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:10,794 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:16,007 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:20,593 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:42,596 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:42,734 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:56,433 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:56,435 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:01:56,474 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:02:32,321 judgelist Free judges: 1 +INFO 2020-01-23 21:02:32,322 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:02:32,346 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:02:32,443 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:02:32,602 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) +TypeError: check() got an unexpected keyword argument 'submission_source' + +INFO 2020-01-23 21:02:32,908 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:03:00,574 judgelist Free judges: 1 +INFO 2020-01-23 21:03:00,574 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:03:00,585 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:03:00,625 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:03:00,713 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) +TypeError: check() got an unexpected keyword argument 'submission_source' + +INFO 2020-01-23 21:03:00,724 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:05:00,306 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:00,341 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:09,432 judgelist Free judges: 1 +INFO 2020-01-23 21:05:09,433 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:05:09,500 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:05:09,535 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:05:09,605 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) +TypeError: check() got an unexpected keyword argument 'submission_source' + +INFO 2020-01-23 21:05:09,614 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:05:26,728 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:26,764 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:30,048 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:30,086 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:44,198 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:44,200 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:44,234 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:05:46,193 judgelist Free judges: 1 +INFO 2020-01-23 21:05:46,194 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:05:46,210 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:05:46,248 judgehandler judge1: Grading has begun on: 34 +INFO 2020-01-23 21:05:46,413 judgehandler judge1: 3 test case(s) completed on: 34 +INFO 2020-01-23 21:05:46,511 judgehandler judge1: Grading has ended on: 34 +INFO 2020-01-23 21:05:46,511 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:06:10,809 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:06:10,852 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:06:20,552 judgelist Free judges: 1 +INFO 2020-01-23 21:06:20,552 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:06:20,568 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:06:20,599 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:06:20,761 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) +TypeError: check() got an unexpected keyword argument 'submission_source' + +INFO 2020-01-23 21:06:20,797 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:06:40,778 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:06:41,412 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:05,264 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:05,306 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:08,465 judgelist Free judges: 1 +INFO 2020-01-23 21:07:08,465 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:07:08,482 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:07:08,521 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:07:08,597 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) +TypeError: check() got an unexpected keyword argument 'judge_input' + +INFO 2020-01-23 21:07:08,607 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:07:34,312 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:34,601 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:42,576 judgelist Free judges: 1 +INFO 2020-01-23 21:07:42,577 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:07:42,581 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:07:42,619 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:07:42,758 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 46, in grade + check = CheckerResult(check, case.points if check else 0.0) + File "/usr/local/lib/python3.6/dist-packages/dmoj/result.py", line 73, in __init__ + assert isinstance(passed, bool) +AssertionError + +INFO 2020-01-23 21:07:42,779 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:07:52,845 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:52,879 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:07:56,775 judgelist Free judges: 1 +INFO 2020-01-23 21:07:56,776 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:07:56,792 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:07:56,830 judgehandler judge1: Grading has begun on: 34 +INFO 2020-01-23 21:07:56,900 judgehandler judge1: 1 test case(s) completed on: 34 +INFO 2020-01-23 21:07:57,003 judgehandler judge1: 2 test case(s) completed on: 34 +INFO 2020-01-23 21:07:57,071 judgehandler judge1: Grading has ended on: 34 +INFO 2020-01-23 21:07:57,071 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:08:16,944 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:08:16,982 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:08:19,552 judgelist Free judges: 1 +INFO 2020-01-23 21:08:19,552 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:08:19,622 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:08:19,656 judgehandler judge1: Grading has begun on: 34 +INFO 2020-01-23 21:08:19,779 judgehandler judge1: 3 test case(s) completed on: 34 +INFO 2020-01-23 21:08:19,850 judgehandler judge1: Grading has ended on: 34 +INFO 2020-01-23 21:08:19,850 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:08:45,463 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:08:45,502 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:08:47,928 judgelist Free judges: 1 +INFO 2020-01-23 21:08:47,928 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:08:47,945 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:08:47,986 judgehandler judge1: Grading has begun on: 34 +INFO 2020-01-23 21:08:48,171 judgehandler judge1: 2 test case(s) completed on: 34 +INFO 2020-01-23 21:08:48,256 judgehandler judge1: 1 test case(s) completed on: 34 +INFO 2020-01-23 21:08:48,326 judgehandler judge1: Grading has ended on: 34 +INFO 2020-01-23 21:08:48,326 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:09:44,861 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:09:44,902 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:09:45,340 judgelist Free judges: 1 +INFO 2020-01-23 21:09:45,340 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:09:45,379 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:09:45,477 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:09:45,549 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 104, in check_result + execution_time=result.execution_time) + File "/home/cuom1999/DMOJ/problems/aplusb/checker.py", line 3, in check + print(a[0]) +TypeError: 'map' object is not subscriptable + +INFO 2020-01-23 21:09:45,567 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:10:05,615 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:10:05,654 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:14:10,308 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:14:10,345 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:14:19,207 judgelist Free judges: 1 +INFO 2020-01-23 21:14:19,207 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:14:19,274 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:14:19,310 judgehandler judge1: Grading has begun on: 34 +INFO 2020-01-23 21:14:19,394 judgehandler judge1: 1 test case(s) completed on: 34 +INFO 2020-01-23 21:14:19,482 judgehandler judge1: 2 test case(s) completed on: 34 +INFO 2020-01-23 21:14:19,551 judgehandler judge1: Grading has ended on: 34 +INFO 2020-01-23 21:14:19,551 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:15:36,115 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:15:36,120 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:15:36,152 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:15:43,219 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:15:43,222 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:15:43,418 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:17:00,163 judgelist Free judges: 1 +INFO 2020-01-23 21:17:00,163 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:17:00,179 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:17:00,221 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:17:00,497 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 90, in check_result + checker = case.checker() + File "/usr/local/lib/python3.6/dist-packages/dmoj/problem.py", line 345, in checker + checker = self.problem.load_checker(name) + File "/usr/local/lib/python3.6/dist-packages/dmoj/problem.py", line 152, in load_checker + self._checkers[name] = checker = load_module_from_file(os.path.join(get_problem_root(self.id), name)) + File "/usr/local/lib/python3.6/dist-packages/dmoj/utils/module.py", line 18, in load_module_from_file + return load_module(name, f.read(), os.path.abspath(filename)) + File "/usr/local/lib/python3.6/dist-packages/dmoj/utils/module.py", line 9, in load_module + exec(compile(code, filename or '', 'exec'), mod.__dict__) + File "/home/cuom1999/DMOJ/problems/aplusb/checker.py", line 6, in + validator_path = os.path.join(get_problem_root('problem_id'), 'validator.cpp') + File "/usr/lib/python3.6/posixpath.py", line 80, in join + a = os.fspath(a) +TypeError: expected str, bytes or os.PathLike object, not NoneType + +INFO 2020-01-23 21:17:00,535 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:17:21,510 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:17:21,579 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:17:24,798 judgelist Free judges: 1 +INFO 2020-01-23 21:17:24,798 judgelist Dispatched submission 34 to: judge1 +INFO 2020-01-23 21:17:24,867 judgehandler Submission acknowledged: 34 +INFO 2020-01-23 21:17:24,903 judgehandler judge1: Grading has begun on: 34 +ERROR 2020-01-23 21:17:24,972 judgehandler Judge judge1 failed while handling submission 34 +Traceback (most recent call last): + File "/home/cuom1999/DMOJ/site/judge/bridge/judgehandler.py", line 230, in on_internal_error + raise ValueError('\n\n' + packet['message']) +ValueError: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/problem.py", line 345, in checker + checker = self.problem.load_checker(name) + File "/usr/local/lib/python3.6/dist-packages/dmoj/problem.py", line 152, in load_checker + self._checkers[name] = checker = load_module_from_file(os.path.join(get_problem_root(self.id), name)) + File "/usr/local/lib/python3.6/dist-packages/dmoj/utils/module.py", line 18, in load_module_from_file + return load_module(name, f.read(), os.path.abspath(filename)) + File "/usr/local/lib/python3.6/dist-packages/dmoj/utils/module.py", line 9, in load_module + exec(compile(code, filename or '', 'exec'), mod.__dict__) + File "/home/cuom1999/DMOJ/problems/aplusb/checker.py", line 8, in + with open(validator_path, 'r') as validator_source: +FileNotFoundError: [Errno 2] No such file or directory: '/home/cuom1999/DMOJ/problems/aplusb/validator.cpp' + +During handling of the above exception, another exception occurred: + +Traceback (most recent call last): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 164, in grading_cleanup_wrapper + self._block_and_grade(problem, language, source, short_circuit, meta, report=report) + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 116, in _block_and_grade + short_circuit=short_circuit): + File "/usr/local/lib/python3.6/dist-packages/dmoj/judge.py", line 208, in grade_cases + result = grader.grade(case) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 41, in grade + check = self.check_result(case, result) + File "/usr/local/lib/python3.6/dist-packages/dmoj/graders/standard.py", line 90, in check_result + checker = case.checker() + File "/usr/local/lib/python3.6/dist-packages/dmoj/problem.py", line 347, in checker + raise InvalidInitException('checker module path does not exist: %s' % name) +dmoj.config.InvalidInitException: checker module path does not exist: checker.py + +INFO 2020-01-23 21:17:24,983 judgelist Judge available after grading 34: judge1 +INFO 2020-01-23 21:17:52,746 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:18:03,849 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:18:09,694 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:18:16,110 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:18:20,167 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:19:15,956 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:19:26,564 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:19:26,816 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:20:12,863 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:20:21,939 judgehandler judge1: Updated problem list +INFO 2020-01-23 21:40:39,960 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:03:01,200 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:29:50,843 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:29:52,146 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:29:58,702 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:30:10,710 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:30:18,273 judgehandler judge1: Updated problem list +INFO 2020-01-23 22:46:52,907 judgehandler judge1: Updated problem list +INFO 2020-01-24 01:35:15,083 judgehandler Judge connected from: ('127.0.0.1', 34192) +INFO 2020-01-24 01:35:15,233 judgehandler Judge authenticated: ('127.0.0.1', 34192) (judge1) +INFO 2020-01-24 01:43:09,664 judgehandler judge1: Updated problem list +INFO 2020-01-24 01:43:09,702 judgehandler judge1: Updated problem list +INFO 2020-01-24 01:46:03,455 judgehandler judge1: Updated problem list +INFO 2020-01-24 01:46:05,299 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:04:07,710 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:04:24,555 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:04:24,734 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:04:24,736 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:06:10,732 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:08:53,761 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:13:33,309 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:14:44,095 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:18:49,742 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:18:53,139 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:24:48,195 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:24:49,403 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:25:12,704 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:25:18,194 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:26:24,931 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:26:26,742 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:26:40,852 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:26:55,225 judgelist Free judges: 1 +INFO 2020-01-24 02:26:55,226 judgelist Dispatched submission 35 to: judge1 +INFO 2020-01-24 02:26:55,247 judgehandler Submission acknowledged: 35 +INFO 2020-01-24 02:26:55,292 judgehandler judge1: Grading has begun on: 35 +INFO 2020-01-24 02:26:55,454 judgehandler judge1: 3 test case(s) completed on: 35 +INFO 2020-01-24 02:26:55,581 judgehandler judge1: Grading has ended on: 35 +INFO 2020-01-24 02:26:55,581 judgelist Judge available after grading 35: judge1 +INFO 2020-01-24 02:28:19,521 judgehandler judge1: Updated problem list +INFO 2020-01-24 02:28:30,526 judgelist Free judges: 1 +INFO 2020-01-24 02:28:30,526 judgelist Dispatched submission 36 to: judge1 +INFO 2020-01-24 02:28:30,545 judgehandler Submission acknowledged: 36 +INFO 2020-01-24 02:28:30,582 judgehandler judge1: Grading has begun on: 36 +INFO 2020-01-24 02:28:30,714 judgehandler judge1: 3 test case(s) completed on: 36 +INFO 2020-01-24 02:28:30,783 judgehandler judge1: Grading has ended on: 36 +INFO 2020-01-24 02:28:30,784 judgelist Judge available after grading 36: judge1 +INFO 2020-01-24 04:00:04,615 judgehandler judge1: Updated problem list +INFO 2020-01-24 04:01:41,763 judgehandler judge1: Updated problem list +INFO 2020-01-24 04:02:04,245 judgelist Free judges: 1 +INFO 2020-01-24 04:02:04,245 judgelist Dispatched submission 37 to: judge1 +INFO 2020-01-24 04:02:04,253 judgehandler Submission acknowledged: 37 +INFO 2020-01-24 04:02:04,288 judgehandler judge1: Grading has begun on: 37 +INFO 2020-01-24 04:02:04,357 judgehandler judge1: 1 test case(s) completed on: 37 +INFO 2020-01-24 04:02:04,460 judgehandler judge1: 2 test case(s) completed on: 37 +INFO 2020-01-24 04:02:04,528 judgehandler judge1: Grading has ended on: 37 +INFO 2020-01-24 04:02:04,529 judgelist Judge available after grading 37: judge1 +INFO 2020-01-24 04:02:20,761 judgelist Free judges: 1 +INFO 2020-01-24 04:02:20,762 judgelist Dispatched submission 38 to: judge1 +INFO 2020-01-24 04:02:20,778 judgehandler Submission acknowledged: 38 +INFO 2020-01-24 04:02:20,815 judgehandler judge1: Grading has begun on: 38 +INFO 2020-01-24 04:02:20,910 judgehandler judge1: 3 test case(s) completed on: 38 +INFO 2020-01-24 04:02:21,051 judgehandler judge1: Grading has ended on: 38 +INFO 2020-01-24 04:02:21,051 judgelist Judge available after grading 38: judge1 +INFO 2020-01-24 04:02:42,811 judgelist Free judges: 1 +INFO 2020-01-24 04:02:42,811 judgelist Dispatched submission 39 to: judge1 +INFO 2020-01-24 04:02:42,828 judgehandler Submission acknowledged: 39 +INFO 2020-01-24 04:02:42,863 judgehandler judge1: Grading has begun on: 39 +INFO 2020-01-24 04:02:42,953 judgehandler judge1: 3 test case(s) completed on: 39 +INFO 2020-01-24 04:02:43,035 judgehandler judge1: Grading has ended on: 39 +INFO 2020-01-24 04:02:43,035 judgelist Judge available after grading 39: judge1 +INFO 2020-01-24 04:03:07,798 judgelist Free judges: 1 +INFO 2020-01-24 04:03:07,798 judgelist Dispatched submission 40 to: judge1 +INFO 2020-01-24 04:03:07,815 judgehandler Submission acknowledged: 40 +INFO 2020-01-24 04:03:07,855 judgehandler judge1: Grading has begun on: 40 +INFO 2020-01-24 04:03:07,983 judgehandler judge1: 3 test case(s) completed on: 40 +INFO 2020-01-24 04:03:08,056 judgehandler judge1: Grading has ended on: 40 +INFO 2020-01-24 04:03:08,056 judgelist Judge available after grading 40: judge1 +INFO 2020-01-24 04:17:47,286 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:02:07,043 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:03:19,384 judgelist Free judges: 1 +INFO 2020-01-24 05:03:19,385 judgelist Dispatched submission 40 to: judge1 +INFO 2020-01-24 05:03:19,394 judgehandler Submission acknowledged: 40 +INFO 2020-01-24 05:03:19,441 judgehandler judge1: Grading has begun on: 40 +INFO 2020-01-24 05:03:19,596 judgehandler judge1: 5 test case(s) completed on: 40 +INFO 2020-01-24 05:03:19,847 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:20,098 judgehandler judge1: 8 test case(s) completed on: 40 +INFO 2020-01-24 05:03:20,921 judgehandler judge1: 4 test case(s) completed on: 40 +INFO 2020-01-24 05:03:21,120 judgehandler judge1: 1 test case(s) completed on: 40 +INFO 2020-01-24 05:03:21,380 judgehandler judge1: 5 test case(s) completed on: 40 +INFO 2020-01-24 05:03:21,521 judgehandler judge1: 3 test case(s) completed on: 40 +INFO 2020-01-24 05:03:21,656 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:21,852 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:22,103 judgehandler judge1: 8 test case(s) completed on: 40 +INFO 2020-01-24 05:03:22,354 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:22,813 judgehandler judge1: 4 test case(s) completed on: 40 +INFO 2020-01-24 05:03:23,394 judgehandler judge1: 1 test case(s) completed on: 40 +INFO 2020-01-24 05:03:23,741 judgehandler judge1: 3 test case(s) completed on: 40 +INFO 2020-01-24 05:03:24,608 judgehandler judge1: 1 test case(s) completed on: 40 +INFO 2020-01-24 05:03:24,757 judgehandler judge1: 6 test case(s) completed on: 40 +INFO 2020-01-24 05:03:24,907 judgehandler judge1: 2 test case(s) completed on: 40 +INFO 2020-01-24 05:03:25,211 judgehandler judge1: 1 test case(s) completed on: 40 +INFO 2020-01-24 05:03:25,355 judgehandler judge1: 4 test case(s) completed on: 40 +INFO 2020-01-24 05:03:25,498 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:25,643 judgehandler judge1: 7 test case(s) completed on: 40 +INFO 2020-01-24 05:03:26,556 judgehandler judge1: 2 test case(s) completed on: 40 +INFO 2020-01-24 05:03:26,717 judgehandler judge1: Grading has ended on: 40 +INFO 2020-01-24 05:03:26,717 judgelist Judge available after grading 40: judge1 +INFO 2020-01-24 05:03:44,777 judgelist Free judges: 1 +INFO 2020-01-24 05:03:44,778 judgelist Dispatched submission 38 to: judge1 +INFO 2020-01-24 05:03:44,794 judgehandler Submission acknowledged: 38 +INFO 2020-01-24 05:03:45,013 judgehandler judge1: Grading has begun on: 38 +INFO 2020-01-24 05:03:45,140 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:45,391 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:45,789 judgehandler judge1: 3 test case(s) completed on: 38 +INFO 2020-01-24 05:03:46,267 judgehandler judge1: 1 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,279 judgehandler judge1: 3 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,514 judgehandler judge1: 3 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,618 judgehandler judge1: 1 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,712 judgehandler judge1: 1 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,805 judgehandler judge1: 1 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,899 judgehandler judge1: 4 test case(s) completed on: 38 +INFO 2020-01-24 05:03:47,994 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:48,134 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:48,275 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:48,399 judgehandler judge1: 8 test case(s) completed on: 38 +INFO 2020-01-24 05:03:48,650 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:48,901 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:49,762 judgehandler judge1: 2 test case(s) completed on: 38 +INFO 2020-01-24 05:03:49,957 judgehandler judge1: 1 test case(s) completed on: 38 +INFO 2020-01-24 05:03:50,194 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:50,314 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:50,703 judgehandler judge1: 7 test case(s) completed on: 38 +INFO 2020-01-24 05:03:50,846 judgehandler judge1: 2 test case(s) completed on: 38 +INFO 2020-01-24 05:03:51,804 judgehandler judge1: Grading has ended on: 38 +INFO 2020-01-24 05:03:51,804 judgelist Judge available after grading 38: judge1 +INFO 2020-01-24 05:04:06,445 judgelist Free judges: 1 +INFO 2020-01-24 05:04:06,446 judgelist Dispatched submission 39 to: judge1 +INFO 2020-01-24 05:04:06,459 judgehandler Submission acknowledged: 39 +INFO 2020-01-24 05:04:06,506 judgehandler judge1: Grading has begun on: 39 +INFO 2020-01-24 05:04:06,677 judgehandler judge1: 4 test case(s) completed on: 39 +INFO 2020-01-24 05:04:06,928 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:07,178 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:07,429 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:07,679 judgehandler judge1: 8 test case(s) completed on: 39 +INFO 2020-01-24 05:04:08,955 judgehandler judge1: 2 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,048 judgehandler judge1: 1 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,142 judgehandler judge1: 1 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,235 judgehandler judge1: 4 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,325 judgehandler judge1: 6 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,436 judgehandler judge1: 8 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,687 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:09,937 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:10,188 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:10,439 judgehandler judge1: 8 test case(s) completed on: 39 +INFO 2020-01-24 05:04:11,345 judgehandler judge1: 5 test case(s) completed on: 39 +INFO 2020-01-24 05:04:11,658 judgehandler judge1: 1 test case(s) completed on: 39 +INFO 2020-01-24 05:04:11,836 judgehandler judge1: 7 test case(s) completed on: 39 +INFO 2020-01-24 05:04:12,014 judgehandler judge1: 3 test case(s) completed on: 39 +INFO 2020-01-24 05:04:12,128 judgehandler judge1: Grading has ended on: 39 +INFO 2020-01-24 05:04:12,128 judgelist Judge available after grading 39: judge1 +INFO 2020-01-24 05:24:11,841 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:24:14,084 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:35:10,473 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:35:30,120 judgehandler judge1: Updated problem list +INFO 2020-01-24 05:36:00,928 judgelist Free judges: 1 +INFO 2020-01-24 05:36:00,928 judgelist Dispatched submission 41 to: judge1 +INFO 2020-01-24 05:36:00,944 judgehandler Submission acknowledged: 41 +INFO 2020-01-24 05:36:00,984 judgehandler judge1: Grading has begun on: 41 +INFO 2020-01-24 05:36:01,275 judgehandler judge1: 8 test case(s) completed on: 41 +INFO 2020-01-24 05:36:01,526 judgehandler judge1: 6 test case(s) completed on: 41 +INFO 2020-01-24 05:36:01,777 judgehandler judge1: 8 test case(s) completed on: 41 +INFO 2020-01-24 05:36:02,027 judgehandler judge1: 7 test case(s) completed on: 41 +INFO 2020-01-24 05:36:02,113 judgehandler judge1: 1 test case(s) completed on: 41 +INFO 2020-01-24 05:36:02,206 judgehandler judge1: Grading has ended on: 41 +INFO 2020-01-24 05:36:02,206 judgelist Judge available after grading 41: judge1 +INFO 2020-01-26 05:15:24,961 judgehandler Judge connected from: ('127.0.0.1', 34940) +INFO 2020-01-26 05:15:24,983 judgehandler Judge authenticated: ('127.0.0.1', 34940) (judge1) +INFO 2020-01-26 05:15:28,838 judgelist Free judges: 1 +INFO 2020-01-26 05:15:28,840 judgelist Dispatched submission 42 to: judge1 +INFO 2020-01-26 05:15:28,861 judgehandler Submission acknowledged: 42 +INFO 2020-01-26 05:15:28,948 judgehandler judge1: Grading has begun on: 42 +INFO 2020-01-26 05:15:29,162 judgehandler judge1: 6 test case(s) completed on: 42 +INFO 2020-01-26 05:15:29,413 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:29,663 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:29,915 judgehandler judge1: 8 test case(s) completed on: 42 +INFO 2020-01-26 05:15:30,166 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:30,416 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:30,667 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:30,918 judgehandler judge1: 8 test case(s) completed on: 42 +INFO 2020-01-26 05:15:31,170 judgehandler judge1: 5 test case(s) completed on: 42 +INFO 2020-01-26 05:15:32,176 judgehandler judge1: 1 test case(s) completed on: 42 +INFO 2020-01-26 05:15:32,608 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:32,731 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:32,800 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:32,869 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:33,824 judgehandler judge1: 1 test case(s) completed on: 42 +INFO 2020-01-26 05:15:34,409 judgehandler judge1: 7 test case(s) completed on: 42 +INFO 2020-01-26 05:15:34,807 judgehandler judge1: 3 test case(s) completed on: 42 +INFO 2020-01-26 05:15:34,911 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:34,986 judgehandler judge1: 1 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,061 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,156 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,249 judgehandler judge1: 1 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,343 judgehandler judge1: 2 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,436 judgehandler judge1: 5 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,531 judgehandler judge1: 3 test case(s) completed on: 42 +INFO 2020-01-26 05:15:35,729 judgehandler judge1: Grading has ended on: 42 +INFO 2020-01-26 05:15:35,729 judgelist Judge available after grading 42: judge1 +INFO 2020-01-26 05:28:39,295 judgehandler Judge disconnected from: ('127.0.0.1', 34940) diff --git a/README.html b/README.html new file mode 100644 index 0000000..53d70c6 --- /dev/null +++ b/README.html @@ -0,0 +1,1078 @@ +README

online-judge

+

1. Activate virtualenv:

+

source dmojsite/bin/activate

+

2. Remember to change the local_settings

+

3. Run server:

+

python manage.py runserver 0.0.0.0:8000

+

4. Create configure file for judge:

+

python dmojauto-conf

+

5. Create folder for problems, change the dir in judge conf file and local_settings.py

+

6. Connect judge:

+
    +
  • python manage.py runbridged
  • +
  • dmoj 0.0.0.0 -p 9999 -c judge/conf1.yml (depend on port in the local_settings.py)
  • +
+

7. Change vietnamese:

+
    +
  • go to /home/cuom1999/DMOJ/site/locale/vi
  • +
  • open .po file
  • +
  • python manage.py compilemessages
  • +
  • python manage.py compilejsi18n
  • +
\ No newline at end of file diff --git a/README.md b/README.md index a96bb39..9d90172 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,22 @@ # online-judge -LQD Online Judge +### 1. Activate virtualenv: +source dmojsite/bin/activate +### 2. Remember to change the local_settings + +### 3. Run server: +python manage.py runserver 0.0.0.0:8000 + +### 4. Create configure file for judge: +python dmojauto-conf + +### 5. Create folder for problems, change the dir in judge conf file and local_settings.py + +### 6. Connect judge: ++ python manage.py runbridged ++ dmoj 0.0.0.0 -p 9999 -c judge/conf1.yml (depend on port in the local_settings.py and directory of conf file) + +### 7. Change vietnamese: + - go to /home/cuom1999/DMOJ/site/locale/vi + - open .po file + - python manage.py compilemessages + - python manage.py compilejsi18n diff --git a/chat_box/__init__.py b/chat_box/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/chat_box/apps.py b/chat_box/apps.py new file mode 100644 index 0000000..fbc3ca1 --- /dev/null +++ b/chat_box/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ChatBoxConfig(AppConfig): + name = 'chat_box' diff --git a/chat_box/consumers.py b/chat_box/consumers.py new file mode 100644 index 0000000..d200968 --- /dev/null +++ b/chat_box/consumers.py @@ -0,0 +1,47 @@ +import json + +from channels.generic.websocket import AsyncWebsocketConsumer + + +class ChatConsumer(AsyncWebsocketConsumer): + async def connect(self): + self.room_name = 'common' + self.room_group_name = 'chat_%s' % self.room_name + + # Join room group + await self.channel_layer.group_add( + self.room_group_name, + self.channel_name, + ) + + await self.accept() + + async def disconnect(self, close_code): + # Leave room group + await self.channel_layer.group_discard( + self.room_group_name, + self.channel_name, + ) + + # Receive message from WebSocket + async def receive(self, text_data): + text_data_json = json.loads(text_data) + message = text_data_json['message'] + + # Send message to room group + await self.channel_layer.group_send( + self.room_group_name, + { + 'type': 'chat_message', + 'message': message, + }, + ) + + # Receive message from room group + async def chat_message(self, event): + message = event['message'] + + # Send message to WebSocket + await self.send(text_data=json.dumps({ + 'message': message, + })) diff --git a/chat_box/migrations/0001_initial.py b/chat_box/migrations/0001_initial.py new file mode 100644 index 0000000..b311ab5 --- /dev/null +++ b/chat_box/migrations/0001_initial.py @@ -0,0 +1,30 @@ +# Generated by Django 2.2.9 on 2020-01-28 05:07 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('judge', '0100_auto_20200127_0059'), + ] + + operations = [ + migrations.CreateModel( + name='Message', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('time', models.DateTimeField(auto_now_add=True, verbose_name='posted time')), + ('body', models.TextField(max_length=8192, verbose_name='body of comment')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='judge.Profile', verbose_name='user')), + ], + options={ + 'verbose_name': 'message', + 'verbose_name_plural': 'messages', + 'ordering': ('-time',), + }, + ), + ] diff --git a/chat_box/migrations/__init__.py b/chat_box/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/chat_box/models.py b/chat_box/models.py new file mode 100644 index 0000000..297b921 --- /dev/null +++ b/chat_box/models.py @@ -0,0 +1,45 @@ +# based on https://github.com/narrowfail/django-channels-chat + +from asgiref.sync import async_to_sync +from channels.layers import get_channel_layer +from django.db import models +from django.db.models import CASCADE +from django.utils.translation import gettext_lazy as _ + + +from judge.models.profile import Profile + + +__all__ = ['Message'] + + +class Message(models.Model): + author = models.ForeignKey(Profile, verbose_name=_('user'), on_delete=CASCADE) + time = models.DateTimeField(verbose_name=_('posted time'), auto_now_add=True) + body = models.TextField(verbose_name=_('body of comment'), max_length=8192) + + def notify_ws_clients(self): + # inform client that there is a new message + notification = { + 'type': 'recieve_group_message', + 'message': '{}'.format(self.id) + } + channel_layer = get_channel_layer() + # print("user.id {}".format(self.user.id)) + # print("user.id {}".format(self.recipient.id)) + + async_to_sync(channel_layer.group_send)("{}".format(self.user.id), notification) + async_to_sync(channel_layer.group_send)("{}".format(self.recipient.id), notification) + + def save(self, *args, **kwargs): + new_message = self.id + self.body = self.body.strip() + super(Message, self).save(*args, **kwargs) + if new_message is None: + self.notify_ws_clients() + + class Meta: + app_label = 'chat_box' + verbose_name = 'message' + verbose_name_plural = 'messages' + ordering = ('-time',) diff --git a/chat_box/routing.py b/chat_box/routing.py new file mode 100644 index 0000000..f420f4f --- /dev/null +++ b/chat_box/routing.py @@ -0,0 +1,7 @@ +from django.urls import re_path + +from . import consumers + +websocket_urlpatterns = [ + re_path(r'ws/chat/', consumers.ChatConsumer), +] diff --git a/chat_box/tests.py b/chat_box/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/chat_box/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/chat_box/views.py b/chat_box/views.py new file mode 100644 index 0000000..a032014 --- /dev/null +++ b/chat_box/views.py @@ -0,0 +1,7 @@ +from django.shortcuts import render +from django.utils.translation import gettext as _ +from django.views import View + + +class ChatView(View): + template_name = 'chat.html' \ No newline at end of file diff --git a/dmoj/local_settings.py b/dmoj/local_settings.py new file mode 100755 index 0000000..607c415 --- /dev/null +++ b/dmoj/local_settings.py @@ -0,0 +1,314 @@ +##################################### +########## Django settings ########## +##################################### +# See +# for more info and help. If you are stuck, you can try Googling about +# Django - many of these settings below have external documentation about them. +# +# The settings listed here are of special interest in configuring the site. + +# SECURITY WARNING: keep the secret key used in production secret! +# You may use +# to generate this key. +SECRET_KEY = 's(8*xdlaiy4r@09cidu#)h%%iey39099g=hp(#+kzz+7vefs4u' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True # Change to False once you are done with runserver testing. + +# Uncomment and set to the domain names this site is intended to serve. +# You must do this once you set DEBUG to False. +ALLOWED_HOSTS = ['0.0.0.0'] + +# Optional apps that DMOJ can make use of. +INSTALLED_APPS += ( +) + +#path to problem folder +DMOJ_PROBLEM_DATA_ROOT = '/home/cuom1999/DMOJ/problems' + +# Caching. You can use memcached or redis instead. +# Documentation: +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache' + } +} + +# Your database credentials. Only MySQL is supported by DMOJ. +# Documentation: +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'dmoj', + 'USER': 'dmoj', + 'PASSWORD': '', + 'HOST': '127.0.0.1', + 'OPTIONS': { + 'charset': 'utf8mb4', + 'sql_mode': 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION', + }, + } +} + +# Sessions. +# Documentation: +#SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' + +# Internationalization. +# Documentation: +LANGUAGE_CODE = 'en-ca' +DEFAULT_USER_TIME_ZONE = 'America/Mexico_City' +USE_I18N = True +USE_L10N = True +USE_TZ = True + +## django-compressor settings, for speeding up page load times by minifying CSS and JavaScript files. +# Documentation: https://django-compressor.readthedocs.io/en/latest/ +COMPRESS_OUTPUT_DIR = 'cache' +COMPRESS_CSS_FILTERS = [ + 'compressor.filters.css_default.CssAbsoluteFilter', + 'compressor.filters.cssmin.CSSMinFilter', +] +COMPRESS_JS_FILTERS = ['compressor.filters.jsmin.JSMinFilter'] +COMPRESS_STORAGE = 'compressor.storage.GzipCompressorFileStorage' +STATICFILES_FINDERS += ('compressor.finders.CompressorFinder',) + + +######################################### +########## Email configuration ########## +######################################### +# See +# for more documentation. You should follow the information there to define +# your email settings. + +# Use this if you are just testing. +EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' + +# The following block is included for your convenience, if you want +# to use Gmail. +#EMAIL_USE_TLS = True +#EMAIL_HOST = 'smtp.gmail.com' +#EMAIL_HOST_USER = '@gmail.com' +#EMAIL_HOST_PASSWORD = '' +#EMAIL_PORT = 587 + +# To use Mailgun, uncomment this block. +# You will need to run `pip install django-mailgun` for to get `MailgunBackend`. +#EMAIL_BACKEND = 'django_mailgun.MailgunBackend' +#MAILGUN_ACCESS_KEY = '' +#MAILGUN_SERVER_NAME = '' + +# You can also use Sendgrid, with `pip install sendgrid-django`. +#EMAIL_BACKEND = 'sgbackend.SendGridBackend' +#SENDGRID_API_KEY = '' + +# The DMOJ site is able to notify administrators of errors via email, +# if configured as shown below. + +# A tuple of (name, email) pairs that specifies those who will be mailed +# when the server experiences an error when DEBUG = False. +ADMINS = ( + ('cuom1999', 'your.email@example.com'), +) + +# The sender for the aforementioned emails. +SERVER_EMAIL = 'DMOJ: Modern Online Judge ' + + +################################################## +########### Static files configuration. ########## +################################################## +# See . + +# Change this to somewhere more permanent., especially if you are using a +# webserver to serve the static files. This is the directory where all the +# static files DMOJ uses will be collected to. +# You must configure your webserver to serve this directory as /static/ in production. +STATIC_ROOT = '/home/cuom1999/DMOJ/static_root' + +# URL to access static files. +#STATIC_URL = '/static/' + +# Uncomment to use hashed filenames with the cache framework. +#STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage' + +############################################ +########## DMOJ-specific settings ########## +############################################ + +## DMOJ site display settings. +SITE_NAME = 'FOOJ' +SITE_LONG_NAME = 'FOOJ: Modern Online Judge' +SITE_ADMIN_EMAIL = 'admin@example.com' +TERMS_OF_SERVICE_URL = '//dmoj.ca/tos' # Use a flatpage. + +## Bridge controls. +# The judge connection address and port; where the judges will connect to the site. +# You should change this to something your judges can actually connect to +# (e.g., a port that is unused and unblocked by a firewall). +BRIDGED_JUDGE_ADDRESS = [('0.0.0.0', 9999)] + +# The bridged daemon bind address and port to communicate with the site. +BRIDGED_DJANGO_ADDRESS = [('localhost', 9998)] + +## DMOJ features. +# Set to True to enable full-text searching for problems. +ENABLE_FTS = True + +# Set of email providers to ban when a user registers, e.g., {'throwawaymail.com'}. +BAD_MAIL_PROVIDERS = set() + +# The number of submissions that a staff user can rejudge at once without +# requiring the permission 'Rejudge a lot of submissions'. +# Uncomment to change the submission limit. +REJUDGE_SUBMISSION_LIMIT = 10 + +## Event server. +# Uncomment to enable live updating. +# EVENT_DAEMON_USE = True + +# Uncomment this section to use websocket/daemon.js included in the site. +#EVENT_DAEMON_POST = '' + +# If you are using the defaults from the guide, it is this: +EVENT_DAEMON_POST = 'ws://127.0.0.1:15101/' + +# These are the publicly accessed interface configurations. +# They should match those used by the script. +#EVENT_DAEMON_GET = '' +#EVENT_DAEMON_GET_SSL = '' +#EVENT_DAEMON_POLL = '' +# i.e. the path to /channels/ exposed by the daemon, through whatever proxy setup you have. + +# Using our standard nginx configuration, these should be. +#EVENT_DAEMON_GET = 'ws:///event/' +#EVENT_DAEMON_GET_SSL = 'wss:///event/' # Optional +#EVENT_DAEMON_POLL = '/channels/' + +# If you would like to use the AMQP-based event server from , +# uncomment this section instead. This is more involved, and recommended to be done +# only after you have a working event server. +#EVENT_DAEMON_AMQP = '' +#EVENT_DAEMON_AMQP_EXCHANGE = '' + +## CDN control. +# Base URL for a copy of ace editor. +# Should contain ace.js, along with mode-*.js. +ACE_URL = '//cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/' +JQUERY_JS = '//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js' +SELECT2_JS_URL = '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js' +SELECT2_CSS_URL = '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css' + +# A map of Earth in Equirectangular projection, for timezone selection. +# Please try not to hotlink this poor site. +TIMEZONE_MAP = 'http://naturalearth.springercarto.com/ne3_data/8192/textures/3_no_ice_clouds_8k.jpg' + +## Camo (https://github.com/atmos/camo) usage. +#CAMO_URL = "" +#CAMO_KEY = "" + +# Domains to exclude from being camo'd. +#CAMO_EXCLUDE = ("https://dmoj.ml", "https://dmoj.ca") + +# Set to True to use https when dealing with protocol-relative URLs. +# See for what they are. +#CAMO_HTTPS = False + +# HTTPS level. Affects elements generated. +# Set to 0 to make http URLs canonical. +# Set to 1 to make the currently used protocol canonical. +# Set to 2 to make https URLs canonical. +#DMOJ_HTTPS = 0 + +## PDF rendering settings. +# Directory to cache the PDF. +# PROBLEM_PDF_CACHE = '/home/dmoj-uwsgi/pdfcache' + +# Path to use for nginx's X-Accel-Redirect feature. +# Should be an internal location mapped to the above directory. +# PROBLEM_PDF_INTERNAL = '/pdfcache' + +# Path to a PhantomJS executable. +#PHANTOMJS = '/usr/local/bin/phantomjs' + +# If you can't use PhantomJS or prefer wkhtmltopdf, set the path to wkhtmltopdf executable instead. +#WKHTMLTOPDF = '/usr/local/bin/wkhtmltopdf' + +# Note that PhantomJS is preferred over wkhtmltopdf and would be used when both are defined. + +## ======== Logging Settings ======== +# Documentation: https://docs.djangoproject.com/en/1.9/ref/settings/#logging +# https://docs.python.org/2/library/logging.config.html#logging-config-dictschema +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'file': { + 'format': '%(levelname)s %(asctime)s %(module)s %(message)s', + }, + 'simple': { + 'format': '%(levelname)s %(message)s', + }, + }, + 'handlers': { + # You may use this handler as example for logging to other files.. + 'bridge': { + 'level': 'INFO', + 'class': 'logging.handlers.RotatingFileHandler', + 'filename': '', + 'maxBytes': 10 * 1024 * 1024, + 'backupCount': 10, + 'formatter': 'file', + }, + 'mail_admins': { + 'level': 'ERROR', + 'class': 'dmoj.throttle_mail.ThrottledEmailHandler', + }, + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'file', + }, + }, + 'loggers': { + # Site 500 error mails. + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': False, + }, + # Judging logs as received by bridged. + 'judge.bridge': { + 'handlers': ['bridge', 'mail_admins'], + 'level': 'INFO', + 'propagate': True, + }, + # Catch all log to stderr. + '': { + 'handlers': ['console'], + }, + # Other loggers of interest. Configure at will. + # - judge.user: logs naughty user behaviours. + # - judge.problem.pdf: PDF generation log. + # - judge.html: HTML parsing errors when processing problem statements etc. + # - judge.mail.activate: logs for the reply to activate feature. + # - event_socket_server + }, +} + +## ======== Integration Settings ======== +## Python Social Auth +# Documentation: https://python-social-auth.readthedocs.io/en/latest/ +# You can define these to enable authentication through the following services. +#SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = '' +#SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = '' +#SOCIAL_AUTH_FACEBOOK_KEY = '' +#SOCIAL_AUTH_FACEBOOK_SECRET = '' +#SOCIAL_AUTH_GITHUB_SECURE_KEY = '' +#SOCIAL_AUTH_GITHUB_SECURE_SECRET = '' +#SOCIAL_AUTH_DROPBOX_OAUTH2_KEY = '' +#SOCIAL_AUTH_DROPBOX_OAUTH2_SECRET = '' + +## ======== Custom Configuration ======== +# You may add whatever django configuration you would like here. +# Do try to keep it separate so you can quickly patch in new settings. diff --git a/dmoj/routing.py b/dmoj/routing.py new file mode 100644 index 0000000..42238b7 --- /dev/null +++ b/dmoj/routing.py @@ -0,0 +1,13 @@ +import chat_box.routing +from channels.auth import AuthMiddlewareStack +from channels.routing import ProtocolTypeRouter, URLRouter + + +application = ProtocolTypeRouter({ + # (http->django views is added by default) + 'websocket': AuthMiddlewareStack( + URLRouter( + chat_box.routing.websocket_urlpatterns, + ), + ), +}) diff --git a/dmoj/settings.py b/dmoj/settings.py index 2625cfa..1e9ab27 100644 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -236,6 +236,8 @@ INSTALLED_APPS += ( 'statici18n', 'impersonate', 'django_jinja', + 'chat_box', + 'channels', ) MIDDLEWARE = ( @@ -495,3 +497,18 @@ try: exec(f.read(), globals()) except IOError: pass + +TESTCASE_VISIBLE_LENGTH = 60 + +DATA_UPLOAD_MAX_NUMBER_FIELDS = 10240 +DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440 + +ASGI_APPLICATION = 'dmoj.routing.application' +CHANNEL_LAYERS = { + 'default': { + 'BACKEND': 'channels_redis.core.RedisChannelLayer', + 'CONFIG': { + "hosts": [('0.0.0.0', 6379)], + }, + }, +} diff --git a/dmoj/urls.py b/dmoj/urls.py index c56ed27..23cdb9c 100644 --- a/dmoj/urls.py +++ b/dmoj/urls.py @@ -1,3 +1,4 @@ +from chat_box.views import ChatView from django.conf import settings from django.conf.urls import include, url from django.contrib import admin @@ -14,9 +15,9 @@ from judge.feed import AtomBlogFeed, AtomCommentFeed, AtomProblemFeed, BlogFeed, from judge.forms import CustomAuthenticationForm from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \ SolutionSitemap, UrlSitemap, UserSitemap -from judge.views import TitledTemplateView, api, blog, comment, contests, language, license, mailgun, organization, \ - preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, ticket, totp, \ - user, widgets +from judge.views import TitledTemplateView, about, api, blog, comment, contests, language, license, mailgun, \ + organization, preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, \ + ticket, totp, user, widgets from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \ problem_data_file, problem_init_view from judge.views.register import ActivationView, RegistrationView @@ -24,6 +25,7 @@ from judge.views.select2 import AssigneeSelect2View, CommentSelect2View, Contest ContestUserSearchSelect2View, OrganizationSelect2View, ProblemSelect2View, TicketUserSelect2View, \ UserSearchSelect2View, UserSelect2View + admin.autodiscover() register_patterns = [ @@ -360,6 +362,12 @@ urlpatterns = [ url(r'^failure$', tasks.demo_failure), url(r'^progress$', tasks.demo_progress), ])), + + url(r'^about/', about.about, name='about'), + + url(r'^custom_checker_sample/', about.custom_checker_sample, name='custom_checker_sample'), + + url(r'chat/', ChatView.as_view(), name='chat'), ] favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png', diff --git a/judge/fixtures/navbar.json b/judge/fixtures/navbar.json index d43868d..2d7ac2c 100644 --- a/judge/fixtures/navbar.json +++ b/judge/fixtures/navbar.json @@ -74,7 +74,7 @@ "path": "/about/", "regex": "^/about/$", "rght": 4, - "tree_id": 5 + "tree_id": 6 }, "model": "judge.navigationbar", "pk": 6 @@ -90,9 +90,25 @@ "path": "/status/", "regex": "^/status/$|^/judge/", "rght": 3, - "tree_id": 5 + "tree_id": 6 }, "model": "judge.navigationbar", "pk": 7 + }, + { + "fields": { + "key": "chat", + "label": "Chat", + "level": 0, + "lft": 1, + "order": 8, + "parent": null, + "path": "/chat/", + "regex": "^/chat", + "rght": 2, + "tree_id": 5 + }, + "model": "judge.navigationbar", + "pk": 8 } ] diff --git a/judge/migrations/0098_auto_20200123_2136.py b/judge/migrations/0098_auto_20200123_2136.py new file mode 100644 index 0000000..333c67c --- /dev/null +++ b/judge/migrations/0098_auto_20200123_2136.py @@ -0,0 +1,155 @@ +# Generated by Django 2.2.9 on 2020-01-23 21:36 + +import django.core.validators +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('judge', '0097_participation_is_disqualified'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='level', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='comment', + name='lft', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='comment', + name='rght', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='contest', + name='format_name', + field=models.CharField(choices=[('atcoder', 'AtCoder'), ('default', 'Default'), ('ecoo', 'ECOO'), ('ioi', 'IOI')], default='default', help_text='The contest format module to use.', max_length=32, verbose_name='contest format'), + ), + migrations.AlterField( + model_name='judge', + name='auth_key', + field=models.CharField(help_text='A key to authenticate this judge', max_length=100, verbose_name='authentication key'), + ), + migrations.AlterField( + model_name='language', + name='description', + field=models.TextField(blank=True, help_text='Use this field to inform users of quirks with your environment, additional restrictions, etc.', verbose_name='language description'), + ), + migrations.AlterField( + model_name='languagelimit', + name='memory_limit', + field=models.IntegerField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1048576)], verbose_name='memory limit'), + ), + migrations.AlterField( + model_name='languagelimit', + name='time_limit', + field=models.FloatField(validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(60)], verbose_name='time limit'), + ), + migrations.AlterField( + model_name='navigationbar', + name='level', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='navigationbar', + name='lft', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='navigationbar', + name='rght', + field=models.PositiveIntegerField(editable=False), + ), + migrations.AlterField( + model_name='problem', + name='allowed_languages', + field=models.ManyToManyField(help_text='List of allowed submission languages.', to='judge.Language', verbose_name='allowed languages'), + ), + migrations.AlterField( + model_name='problem', + name='authors', + field=models.ManyToManyField(blank=True, help_text='These users will be able to edit the problem, and be listed as authors.', related_name='authored_problems', to='judge.Profile', verbose_name='creators'), + ), + migrations.AlterField( + model_name='problem', + name='code', + field=models.CharField(help_text='A short, unique code for the problem, used in the url after /problem/', max_length=20, unique=True, validators=[django.core.validators.RegexValidator('^[a-z0-9]+$', 'Problem code must be ^[a-z0-9]+$')], verbose_name='problem code'), + ), + migrations.AlterField( + model_name='problem', + name='curators', + field=models.ManyToManyField(blank=True, help_text='These users will be able to edit the problem, but not be listed as authors.', related_name='curated_problems', to='judge.Profile', verbose_name='curators'), + ), + migrations.AlterField( + model_name='problem', + name='group', + field=models.ForeignKey(help_text='The group of problem, shown under Category in the problem list.', on_delete=django.db.models.deletion.CASCADE, to='judge.ProblemGroup', verbose_name='problem group'), + ), + migrations.AlterField( + model_name='problem', + name='is_manually_managed', + field=models.BooleanField(db_index=True, default=False, help_text='Whether judges should be allowed to manage data or not.', verbose_name='manually managed'), + ), + migrations.AlterField( + model_name='problem', + name='license', + field=models.ForeignKey(blank=True, help_text='The license under which this problem is published.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='judge.License'), + ), + migrations.AlterField( + model_name='problem', + name='memory_limit', + field=models.PositiveIntegerField(help_text='The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 kilobytes).', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1048576)], verbose_name='memory limit'), + ), + migrations.AlterField( + model_name='problem', + name='name', + field=models.CharField(db_index=True, help_text='The full name of the problem, as shown in the problem list.', max_length=100, verbose_name='problem name'), + ), + migrations.AlterField( + model_name='problem', + name='points', + field=models.FloatField(help_text="Points awarded for problem completion. Points are displayed with a 'p' suffix if partial.", validators=[django.core.validators.MinValueValidator(0)], verbose_name='points'), + ), + migrations.AlterField( + model_name='problem', + name='testers', + field=models.ManyToManyField(blank=True, help_text='These users will be able to view the private problem, but not edit it.', related_name='tested_problems', to='judge.Profile', verbose_name='testers'), + ), + migrations.AlterField( + model_name='problem', + name='time_limit', + field=models.FloatField(help_text='The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) are supported.', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(60)], verbose_name='time limit'), + ), + migrations.AlterField( + model_name='problem', + name='types', + field=models.ManyToManyField(help_text="The type of problem, as shown on the problem's page.", to='judge.ProblemType', verbose_name='problem types'), + ), + migrations.AlterField( + model_name='problemdata', + name='checker', + field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('checker.py', 'Custom checker')], max_length=10, verbose_name='checker'), + ), + migrations.AlterField( + model_name='problemtestcase', + name='checker', + field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('checker.py', 'Custom checker')], max_length=10, verbose_name='checker'), + ), + migrations.AlterField( + model_name='problemtranslation', + name='language', + field=models.CharField(choices=[('de', 'German'), ('en', 'English'), ('es', 'Spanish'), ('fr', 'French'), ('hr', 'Croatian'), ('hu', 'Hungarian'), ('ja', 'Japanese'), ('ko', 'Korean'), ('pt', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sr-latn', 'Serbian (Latin)'), ('tr', 'Turkish'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')], max_length=7, verbose_name='language'), + ), + migrations.AlterField( + model_name='profile', + name='timezone', + field=models.CharField(choices=[('Africa', [('Africa/Abidjan', 'Abidjan'), ('Africa/Accra', 'Accra'), ('Africa/Addis_Ababa', 'Addis_Ababa'), ('Africa/Algiers', 'Algiers'), ('Africa/Asmara', 'Asmara'), ('Africa/Asmera', 'Asmera'), ('Africa/Bamako', 'Bamako'), ('Africa/Bangui', 'Bangui'), ('Africa/Banjul', 'Banjul'), ('Africa/Bissau', 'Bissau'), ('Africa/Blantyre', 'Blantyre'), ('Africa/Brazzaville', 'Brazzaville'), ('Africa/Bujumbura', 'Bujumbura'), ('Africa/Cairo', 'Cairo'), ('Africa/Casablanca', 'Casablanca'), ('Africa/Ceuta', 'Ceuta'), ('Africa/Conakry', 'Conakry'), ('Africa/Dakar', 'Dakar'), ('Africa/Dar_es_Salaam', 'Dar_es_Salaam'), ('Africa/Djibouti', 'Djibouti'), ('Africa/Douala', 'Douala'), ('Africa/El_Aaiun', 'El_Aaiun'), ('Africa/Freetown', 'Freetown'), ('Africa/Gaborone', 'Gaborone'), ('Africa/Harare', 'Harare'), ('Africa/Johannesburg', 'Johannesburg'), ('Africa/Juba', 'Juba'), ('Africa/Kampala', 'Kampala'), ('Africa/Khartoum', 'Khartoum'), ('Africa/Kigali', 'Kigali'), ('Africa/Kinshasa', 'Kinshasa'), ('Africa/Lagos', 'Lagos'), ('Africa/Libreville', 'Libreville'), ('Africa/Lome', 'Lome'), ('Africa/Luanda', 'Luanda'), ('Africa/Lubumbashi', 'Lubumbashi'), ('Africa/Lusaka', 'Lusaka'), ('Africa/Malabo', 'Malabo'), ('Africa/Maputo', 'Maputo'), ('Africa/Maseru', 'Maseru'), ('Africa/Mbabane', 'Mbabane'), ('Africa/Mogadishu', 'Mogadishu'), ('Africa/Monrovia', 'Monrovia'), ('Africa/Nairobi', 'Nairobi'), ('Africa/Ndjamena', 'Ndjamena'), ('Africa/Niamey', 'Niamey'), ('Africa/Nouakchott', 'Nouakchott'), ('Africa/Ouagadougou', 'Ouagadougou'), ('Africa/Porto-Novo', 'Porto-Novo'), ('Africa/Sao_Tome', 'Sao_Tome'), ('Africa/Timbuktu', 'Timbuktu'), ('Africa/Tripoli', 'Tripoli'), ('Africa/Tunis', 'Tunis'), ('Africa/Windhoek', 'Windhoek')]), ('America', [('America/Adak', 'Adak'), ('America/Anchorage', 'Anchorage'), ('America/Anguilla', 'Anguilla'), ('America/Antigua', 'Antigua'), ('America/Araguaina', 'Araguaina'), ('America/Argentina/Buenos_Aires', 'Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'Argentina/Catamarca'), ('America/Argentina/ComodRivadavia', 'Argentina/ComodRivadavia'), ('America/Argentina/Cordoba', 'Argentina/Cordoba'), ('America/Argentina/Jujuy', 'Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'Argentina/Salta'), ('America/Argentina/San_Juan', 'Argentina/San_Juan'), ('America/Argentina/San_Luis', 'Argentina/San_Luis'), ('America/Argentina/Tucuman', 'Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'Argentina/Ushuaia'), ('America/Aruba', 'Aruba'), ('America/Asuncion', 'Asuncion'), ('America/Atikokan', 'Atikokan'), ('America/Atka', 'Atka'), ('America/Bahia', 'Bahia'), ('America/Bahia_Banderas', 'Bahia_Banderas'), ('America/Barbados', 'Barbados'), ('America/Belem', 'Belem'), ('America/Belize', 'Belize'), ('America/Blanc-Sablon', 'Blanc-Sablon'), ('America/Boa_Vista', 'Boa_Vista'), ('America/Bogota', 'Bogota'), ('America/Boise', 'Boise'), ('America/Buenos_Aires', 'Buenos_Aires'), ('America/Cambridge_Bay', 'Cambridge_Bay'), ('America/Campo_Grande', 'Campo_Grande'), ('America/Cancun', 'Cancun'), ('America/Caracas', 'Caracas'), ('America/Catamarca', 'Catamarca'), ('America/Cayenne', 'Cayenne'), ('America/Cayman', 'Cayman'), ('America/Chicago', 'Chicago'), ('America/Chihuahua', 'Chihuahua'), ('America/Coral_Harbour', 'Coral_Harbour'), ('America/Cordoba', 'Cordoba'), ('America/Costa_Rica', 'Costa_Rica'), ('America/Creston', 'Creston'), ('America/Cuiaba', 'Cuiaba'), ('America/Curacao', 'Curacao'), ('America/Danmarkshavn', 'Danmarkshavn'), ('America/Dawson', 'Dawson'), ('America/Dawson_Creek', 'Dawson_Creek'), ('America/Denver', 'Denver'), ('America/Detroit', 'Detroit'), ('America/Dominica', 'Dominica'), ('America/Edmonton', 'Edmonton'), ('America/Eirunepe', 'Eirunepe'), ('America/El_Salvador', 'El_Salvador'), ('America/Ensenada', 'Ensenada'), ('America/Fort_Nelson', 'Fort_Nelson'), ('America/Fort_Wayne', 'Fort_Wayne'), ('America/Fortaleza', 'Fortaleza'), ('America/Glace_Bay', 'Glace_Bay'), ('America/Godthab', 'Godthab'), ('America/Goose_Bay', 'Goose_Bay'), ('America/Grand_Turk', 'Grand_Turk'), ('America/Grenada', 'Grenada'), ('America/Guadeloupe', 'Guadeloupe'), ('America/Guatemala', 'Guatemala'), ('America/Guayaquil', 'Guayaquil'), ('America/Guyana', 'Guyana'), ('America/Halifax', 'Halifax'), ('America/Havana', 'Havana'), ('America/Hermosillo', 'Hermosillo'), ('America/Indiana/Indianapolis', 'Indiana/Indianapolis'), ('America/Indiana/Knox', 'Indiana/Knox'), ('America/Indiana/Marengo', 'Indiana/Marengo'), ('America/Indiana/Petersburg', 'Indiana/Petersburg'), ('America/Indiana/Tell_City', 'Indiana/Tell_City'), ('America/Indiana/Vevay', 'Indiana/Vevay'), ('America/Indiana/Vincennes', 'Indiana/Vincennes'), ('America/Indiana/Winamac', 'Indiana/Winamac'), ('America/Indianapolis', 'Indianapolis'), ('America/Inuvik', 'Inuvik'), ('America/Iqaluit', 'Iqaluit'), ('America/Jamaica', 'Jamaica'), ('America/Jujuy', 'Jujuy'), ('America/Juneau', 'Juneau'), ('America/Kentucky/Louisville', 'Kentucky/Louisville'), ('America/Kentucky/Monticello', 'Kentucky/Monticello'), ('America/Knox_IN', 'Knox_IN'), ('America/Kralendijk', 'Kralendijk'), ('America/La_Paz', 'La_Paz'), ('America/Lima', 'Lima'), ('America/Los_Angeles', 'Los_Angeles'), ('America/Louisville', 'Louisville'), ('America/Lower_Princes', 'Lower_Princes'), ('America/Maceio', 'Maceio'), ('America/Managua', 'Managua'), ('America/Manaus', 'Manaus'), ('America/Marigot', 'Marigot'), ('America/Martinique', 'Martinique'), ('America/Matamoros', 'Matamoros'), ('America/Mazatlan', 'Mazatlan'), ('America/Mendoza', 'Mendoza'), ('America/Menominee', 'Menominee'), ('America/Merida', 'Merida'), ('America/Metlakatla', 'Metlakatla'), ('America/Mexico_City', 'Mexico_City'), ('America/Miquelon', 'Miquelon'), ('America/Moncton', 'Moncton'), ('America/Monterrey', 'Monterrey'), ('America/Montevideo', 'Montevideo'), ('America/Montreal', 'Montreal'), ('America/Montserrat', 'Montserrat'), ('America/Nassau', 'Nassau'), ('America/New_York', 'New_York'), ('America/Nipigon', 'Nipigon'), ('America/Nome', 'Nome'), ('America/Noronha', 'Noronha'), ('America/North_Dakota/Beulah', 'North_Dakota/Beulah'), ('America/North_Dakota/Center', 'North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'North_Dakota/New_Salem'), ('America/Ojinaga', 'Ojinaga'), ('America/Panama', 'Panama'), ('America/Pangnirtung', 'Pangnirtung'), ('America/Paramaribo', 'Paramaribo'), ('America/Phoenix', 'Phoenix'), ('America/Port-au-Prince', 'Port-au-Prince'), ('America/Port_of_Spain', 'Port_of_Spain'), ('America/Porto_Acre', 'Porto_Acre'), ('America/Porto_Velho', 'Porto_Velho'), ('America/Puerto_Rico', 'Puerto_Rico'), ('America/Punta_Arenas', 'Punta_Arenas'), ('America/Rainy_River', 'Rainy_River'), ('America/Rankin_Inlet', 'Rankin_Inlet'), ('America/Recife', 'Recife'), ('America/Regina', 'Regina'), ('America/Resolute', 'Resolute'), ('America/Rio_Branco', 'Rio_Branco'), ('America/Rosario', 'Rosario'), ('America/Santa_Isabel', 'Santa_Isabel'), ('America/Santarem', 'Santarem'), ('America/Santiago', 'Santiago'), ('America/Santo_Domingo', 'Santo_Domingo'), ('America/Sao_Paulo', 'Sao_Paulo'), ('America/Scoresbysund', 'Scoresbysund'), ('America/Shiprock', 'Shiprock'), ('America/Sitka', 'Sitka'), ('America/St_Barthelemy', 'St_Barthelemy'), ('America/St_Johns', 'St_Johns'), ('America/St_Kitts', 'St_Kitts'), ('America/St_Lucia', 'St_Lucia'), ('America/St_Thomas', 'St_Thomas'), ('America/St_Vincent', 'St_Vincent'), ('America/Swift_Current', 'Swift_Current'), ('America/Tegucigalpa', 'Tegucigalpa'), ('America/Thule', 'Thule'), ('America/Thunder_Bay', 'Thunder_Bay'), ('America/Tijuana', 'Tijuana'), ('America/Toronto', 'Toronto'), ('America/Tortola', 'Tortola'), ('America/Vancouver', 'Vancouver'), ('America/Virgin', 'Virgin'), ('America/Whitehorse', 'Whitehorse'), ('America/Winnipeg', 'Winnipeg'), ('America/Yakutat', 'Yakutat'), ('America/Yellowknife', 'Yellowknife')]), ('Antarctica', [('Antarctica/Casey', 'Casey'), ('Antarctica/Davis', 'Davis'), ('Antarctica/DumontDUrville', 'DumontDUrville'), ('Antarctica/Macquarie', 'Macquarie'), ('Antarctica/Mawson', 'Mawson'), ('Antarctica/McMurdo', 'McMurdo'), ('Antarctica/Palmer', 'Palmer'), ('Antarctica/Rothera', 'Rothera'), ('Antarctica/South_Pole', 'South_Pole'), ('Antarctica/Syowa', 'Syowa'), ('Antarctica/Troll', 'Troll'), ('Antarctica/Vostok', 'Vostok')]), ('Arctic', [('Arctic/Longyearbyen', 'Longyearbyen')]), ('Asia', [('Asia/Aden', 'Aden'), ('Asia/Almaty', 'Almaty'), ('Asia/Amman', 'Amman'), ('Asia/Anadyr', 'Anadyr'), ('Asia/Aqtau', 'Aqtau'), ('Asia/Aqtobe', 'Aqtobe'), ('Asia/Ashgabat', 'Ashgabat'), ('Asia/Ashkhabad', 'Ashkhabad'), ('Asia/Atyrau', 'Atyrau'), ('Asia/Baghdad', 'Baghdad'), ('Asia/Bahrain', 'Bahrain'), ('Asia/Baku', 'Baku'), ('Asia/Bangkok', 'Bangkok'), ('Asia/Barnaul', 'Barnaul'), ('Asia/Beirut', 'Beirut'), ('Asia/Bishkek', 'Bishkek'), ('Asia/Brunei', 'Brunei'), ('Asia/Calcutta', 'Calcutta'), ('Asia/Chita', 'Chita'), ('Asia/Choibalsan', 'Choibalsan'), ('Asia/Chongqing', 'Chongqing'), ('Asia/Chungking', 'Chungking'), ('Asia/Colombo', 'Colombo'), ('Asia/Dacca', 'Dacca'), ('Asia/Damascus', 'Damascus'), ('Asia/Dhaka', 'Dhaka'), ('Asia/Dili', 'Dili'), ('Asia/Dubai', 'Dubai'), ('Asia/Dushanbe', 'Dushanbe'), ('Asia/Famagusta', 'Famagusta'), ('Asia/Gaza', 'Gaza'), ('Asia/Harbin', 'Harbin'), ('Asia/Hebron', 'Hebron'), ('Asia/Ho_Chi_Minh', 'Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Hong_Kong'), ('Asia/Hovd', 'Hovd'), ('Asia/Irkutsk', 'Irkutsk'), ('Asia/Istanbul', 'Istanbul'), ('Asia/Jakarta', 'Jakarta'), ('Asia/Jayapura', 'Jayapura'), ('Asia/Jerusalem', 'Jerusalem'), ('Asia/Kabul', 'Kabul'), ('Asia/Kamchatka', 'Kamchatka'), ('Asia/Karachi', 'Karachi'), ('Asia/Kashgar', 'Kashgar'), ('Asia/Kathmandu', 'Kathmandu'), ('Asia/Katmandu', 'Katmandu'), ('Asia/Khandyga', 'Khandyga'), ('Asia/Kolkata', 'Kolkata'), ('Asia/Krasnoyarsk', 'Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Kuala_Lumpur'), ('Asia/Kuching', 'Kuching'), ('Asia/Kuwait', 'Kuwait'), ('Asia/Macao', 'Macao'), ('Asia/Macau', 'Macau'), ('Asia/Magadan', 'Magadan'), ('Asia/Makassar', 'Makassar'), ('Asia/Manila', 'Manila'), ('Asia/Muscat', 'Muscat'), ('Asia/Nicosia', 'Nicosia'), ('Asia/Novokuznetsk', 'Novokuznetsk'), ('Asia/Novosibirsk', 'Novosibirsk'), ('Asia/Omsk', 'Omsk'), ('Asia/Oral', 'Oral'), ('Asia/Phnom_Penh', 'Phnom_Penh'), ('Asia/Pontianak', 'Pontianak'), ('Asia/Pyongyang', 'Pyongyang'), ('Asia/Qatar', 'Qatar'), ('Asia/Qostanay', 'Qostanay'), ('Asia/Qyzylorda', 'Qyzylorda'), ('Asia/Rangoon', 'Rangoon'), ('Asia/Riyadh', 'Riyadh'), ('Asia/Saigon', 'Saigon'), ('Asia/Sakhalin', 'Sakhalin'), ('Asia/Samarkand', 'Samarkand'), ('Asia/Seoul', 'Seoul'), ('Asia/Shanghai', 'Shanghai'), ('Asia/Singapore', 'Singapore'), ('Asia/Srednekolymsk', 'Srednekolymsk'), ('Asia/Taipei', 'Taipei'), ('Asia/Tashkent', 'Tashkent'), ('Asia/Tbilisi', 'Tbilisi'), ('Asia/Tehran', 'Tehran'), ('Asia/Tel_Aviv', 'Tel_Aviv'), ('Asia/Thimbu', 'Thimbu'), ('Asia/Thimphu', 'Thimphu'), ('Asia/Tokyo', 'Tokyo'), ('Asia/Tomsk', 'Tomsk'), ('Asia/Ujung_Pandang', 'Ujung_Pandang'), ('Asia/Ulaanbaatar', 'Ulaanbaatar'), ('Asia/Ulan_Bator', 'Ulan_Bator'), ('Asia/Urumqi', 'Urumqi'), ('Asia/Ust-Nera', 'Ust-Nera'), ('Asia/Vientiane', 'Vientiane'), ('Asia/Vladivostok', 'Vladivostok'), ('Asia/Yakutsk', 'Yakutsk'), ('Asia/Yangon', 'Yangon'), ('Asia/Yekaterinburg', 'Yekaterinburg'), ('Asia/Yerevan', 'Yerevan')]), ('Atlantic', [('Atlantic/Azores', 'Azores'), ('Atlantic/Bermuda', 'Bermuda'), ('Atlantic/Canary', 'Canary'), ('Atlantic/Cape_Verde', 'Cape_Verde'), ('Atlantic/Faeroe', 'Faeroe'), ('Atlantic/Faroe', 'Faroe'), ('Atlantic/Jan_Mayen', 'Jan_Mayen'), ('Atlantic/Madeira', 'Madeira'), ('Atlantic/Reykjavik', 'Reykjavik'), ('Atlantic/South_Georgia', 'South_Georgia'), ('Atlantic/St_Helena', 'St_Helena'), ('Atlantic/Stanley', 'Stanley')]), ('Australia', [('Australia/ACT', 'ACT'), ('Australia/Adelaide', 'Adelaide'), ('Australia/Brisbane', 'Brisbane'), ('Australia/Broken_Hill', 'Broken_Hill'), ('Australia/Canberra', 'Canberra'), ('Australia/Currie', 'Currie'), ('Australia/Darwin', 'Darwin'), ('Australia/Eucla', 'Eucla'), ('Australia/Hobart', 'Hobart'), ('Australia/LHI', 'LHI'), ('Australia/Lindeman', 'Lindeman'), ('Australia/Lord_Howe', 'Lord_Howe'), ('Australia/Melbourne', 'Melbourne'), ('Australia/NSW', 'NSW'), ('Australia/North', 'North'), ('Australia/Perth', 'Perth'), ('Australia/Queensland', 'Queensland'), ('Australia/South', 'South'), ('Australia/Sydney', 'Sydney'), ('Australia/Tasmania', 'Tasmania'), ('Australia/Victoria', 'Victoria'), ('Australia/West', 'West'), ('Australia/Yancowinna', 'Yancowinna')]), ('Brazil', [('Brazil/Acre', 'Acre'), ('Brazil/DeNoronha', 'DeNoronha'), ('Brazil/East', 'East'), ('Brazil/West', 'West')]), ('Canada', [('Canada/Atlantic', 'Atlantic'), ('Canada/Central', 'Central'), ('Canada/Eastern', 'Eastern'), ('Canada/Mountain', 'Mountain'), ('Canada/Newfoundland', 'Newfoundland'), ('Canada/Pacific', 'Pacific'), ('Canada/Saskatchewan', 'Saskatchewan'), ('Canada/Yukon', 'Yukon')]), ('Chile', [('Chile/Continental', 'Continental'), ('Chile/EasterIsland', 'EasterIsland')]), ('Etc', [('Etc/Greenwich', 'Greenwich'), ('Etc/UCT', 'UCT'), ('Etc/UTC', 'UTC'), ('Etc/Universal', 'Universal'), ('Etc/Zulu', 'Zulu')]), ('Europe', [('Europe/Amsterdam', 'Amsterdam'), ('Europe/Andorra', 'Andorra'), ('Europe/Astrakhan', 'Astrakhan'), ('Europe/Athens', 'Athens'), ('Europe/Belfast', 'Belfast'), ('Europe/Belgrade', 'Belgrade'), ('Europe/Berlin', 'Berlin'), ('Europe/Bratislava', 'Bratislava'), ('Europe/Brussels', 'Brussels'), ('Europe/Bucharest', 'Bucharest'), ('Europe/Budapest', 'Budapest'), ('Europe/Busingen', 'Busingen'), ('Europe/Chisinau', 'Chisinau'), ('Europe/Copenhagen', 'Copenhagen'), ('Europe/Dublin', 'Dublin'), ('Europe/Gibraltar', 'Gibraltar'), ('Europe/Guernsey', 'Guernsey'), ('Europe/Helsinki', 'Helsinki'), ('Europe/Isle_of_Man', 'Isle_of_Man'), ('Europe/Istanbul', 'Istanbul'), ('Europe/Jersey', 'Jersey'), ('Europe/Kaliningrad', 'Kaliningrad'), ('Europe/Kiev', 'Kiev'), ('Europe/Kirov', 'Kirov'), ('Europe/Lisbon', 'Lisbon'), ('Europe/Ljubljana', 'Ljubljana'), ('Europe/London', 'London'), ('Europe/Luxembourg', 'Luxembourg'), ('Europe/Madrid', 'Madrid'), ('Europe/Malta', 'Malta'), ('Europe/Mariehamn', 'Mariehamn'), ('Europe/Minsk', 'Minsk'), ('Europe/Monaco', 'Monaco'), ('Europe/Moscow', 'Moscow'), ('Europe/Nicosia', 'Nicosia'), ('Europe/Oslo', 'Oslo'), ('Europe/Paris', 'Paris'), ('Europe/Podgorica', 'Podgorica'), ('Europe/Prague', 'Prague'), ('Europe/Riga', 'Riga'), ('Europe/Rome', 'Rome'), ('Europe/Samara', 'Samara'), ('Europe/San_Marino', 'San_Marino'), ('Europe/Sarajevo', 'Sarajevo'), ('Europe/Saratov', 'Saratov'), ('Europe/Simferopol', 'Simferopol'), ('Europe/Skopje', 'Skopje'), ('Europe/Sofia', 'Sofia'), ('Europe/Stockholm', 'Stockholm'), ('Europe/Tallinn', 'Tallinn'), ('Europe/Tirane', 'Tirane'), ('Europe/Tiraspol', 'Tiraspol'), ('Europe/Ulyanovsk', 'Ulyanovsk'), ('Europe/Uzhgorod', 'Uzhgorod'), ('Europe/Vaduz', 'Vaduz'), ('Europe/Vatican', 'Vatican'), ('Europe/Vienna', 'Vienna'), ('Europe/Vilnius', 'Vilnius'), ('Europe/Volgograd', 'Volgograd'), ('Europe/Warsaw', 'Warsaw'), ('Europe/Zagreb', 'Zagreb'), ('Europe/Zaporozhye', 'Zaporozhye'), ('Europe/Zurich', 'Zurich')]), ('Indian', [('Indian/Antananarivo', 'Antananarivo'), ('Indian/Chagos', 'Chagos'), ('Indian/Christmas', 'Christmas'), ('Indian/Cocos', 'Cocos'), ('Indian/Comoro', 'Comoro'), ('Indian/Kerguelen', 'Kerguelen'), ('Indian/Mahe', 'Mahe'), ('Indian/Maldives', 'Maldives'), ('Indian/Mauritius', 'Mauritius'), ('Indian/Mayotte', 'Mayotte'), ('Indian/Reunion', 'Reunion')]), ('Mexico', [('Mexico/BajaNorte', 'BajaNorte'), ('Mexico/BajaSur', 'BajaSur'), ('Mexico/General', 'General')]), ('Other', [('CET', 'CET'), ('CST6CDT', 'CST6CDT'), ('Cuba', 'Cuba'), ('EET', 'EET'), ('EST', 'EST'), ('EST5EDT', 'EST5EDT'), ('Egypt', 'Egypt'), ('Eire', 'Eire'), ('GB', 'GB'), ('GB-Eire', 'GB-Eire'), ('Greenwich', 'Greenwich'), ('HST', 'HST'), ('Hongkong', 'Hongkong'), ('Iceland', 'Iceland'), ('Iran', 'Iran'), ('Israel', 'Israel'), ('Jamaica', 'Jamaica'), ('Japan', 'Japan'), ('Kwajalein', 'Kwajalein'), ('Libya', 'Libya'), ('MET', 'MET'), ('MST', 'MST'), ('MST7MDT', 'MST7MDT'), ('NZ', 'NZ'), ('NZ-CHAT', 'NZ-CHAT'), ('Navajo', 'Navajo'), ('PRC', 'PRC'), ('PST8PDT', 'PST8PDT'), ('Poland', 'Poland'), ('Portugal', 'Portugal'), ('ROC', 'ROC'), ('ROK', 'ROK'), ('Singapore', 'Singapore'), ('Turkey', 'Turkey'), ('UCT', 'UCT'), ('UTC', 'UTC'), ('Universal', 'Universal'), ('W-SU', 'W-SU'), ('WET', 'WET'), ('Zulu', 'Zulu')]), ('Pacific', [('Pacific/Apia', 'Apia'), ('Pacific/Auckland', 'Auckland'), ('Pacific/Bougainville', 'Bougainville'), ('Pacific/Chatham', 'Chatham'), ('Pacific/Chuuk', 'Chuuk'), ('Pacific/Easter', 'Easter'), ('Pacific/Efate', 'Efate'), ('Pacific/Enderbury', 'Enderbury'), ('Pacific/Fakaofo', 'Fakaofo'), ('Pacific/Fiji', 'Fiji'), ('Pacific/Funafuti', 'Funafuti'), ('Pacific/Galapagos', 'Galapagos'), ('Pacific/Gambier', 'Gambier'), ('Pacific/Guadalcanal', 'Guadalcanal'), ('Pacific/Guam', 'Guam'), ('Pacific/Honolulu', 'Honolulu'), ('Pacific/Johnston', 'Johnston'), ('Pacific/Kiritimati', 'Kiritimati'), ('Pacific/Kosrae', 'Kosrae'), ('Pacific/Kwajalein', 'Kwajalein'), ('Pacific/Majuro', 'Majuro'), ('Pacific/Marquesas', 'Marquesas'), ('Pacific/Midway', 'Midway'), ('Pacific/Nauru', 'Nauru'), ('Pacific/Niue', 'Niue'), ('Pacific/Norfolk', 'Norfolk'), ('Pacific/Noumea', 'Noumea'), ('Pacific/Pago_Pago', 'Pago_Pago'), ('Pacific/Palau', 'Palau'), ('Pacific/Pitcairn', 'Pitcairn'), ('Pacific/Pohnpei', 'Pohnpei'), ('Pacific/Ponape', 'Ponape'), ('Pacific/Port_Moresby', 'Port_Moresby'), ('Pacific/Rarotonga', 'Rarotonga'), ('Pacific/Saipan', 'Saipan'), ('Pacific/Samoa', 'Samoa'), ('Pacific/Tahiti', 'Tahiti'), ('Pacific/Tarawa', 'Tarawa'), ('Pacific/Tongatapu', 'Tongatapu'), ('Pacific/Truk', 'Truk'), ('Pacific/Wake', 'Wake'), ('Pacific/Wallis', 'Wallis'), ('Pacific/Yap', 'Yap')]), ('US', [('US/Alaska', 'Alaska'), ('US/Aleutian', 'Aleutian'), ('US/Arizona', 'Arizona'), ('US/Central', 'Central'), ('US/East-Indiana', 'East-Indiana'), ('US/Eastern', 'Eastern'), ('US/Hawaii', 'Hawaii'), ('US/Indiana-Starke', 'Indiana-Starke'), ('US/Michigan', 'Michigan'), ('US/Mountain', 'Mountain'), ('US/Pacific', 'Pacific'), ('US/Samoa', 'Samoa')])], default='America/Mexico_City', max_length=50, verbose_name='location'), + ), + ] diff --git a/judge/migrations/0099_custom_checker.py b/judge/migrations/0099_custom_checker.py new file mode 100644 index 0000000..b2552b7 --- /dev/null +++ b/judge/migrations/0099_custom_checker.py @@ -0,0 +1,30 @@ +# Generated by Django 2.2.9 on 2020-01-23 22:28 +from django.db import migrations, models + +import judge.models.problem_data +import judge.utils.problem_data + + +class Migration(migrations.Migration): + + dependencies = [ + ('judge', '0098_auto_20200123_2136'), + ] + + operations = [ + migrations.AddField( + model_name='problemdata', + name='custom_checker', + field=models.FileField(blank=True, null=True, storage=judge.utils.problem_data.ProblemDataStorage(), upload_to=judge.models.problem_data.problem_directory_file, verbose_name='custom checker file'), + ), + migrations.AlterField( + model_name='problemdata', + name='checker', + field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker')], max_length=10, verbose_name='checker'), + ), + migrations.AlterField( + model_name='problemtestcase', + name='checker', + field=models.CharField(blank=True, choices=[('standard', 'Standard'), ('floats', 'Floats'), ('floatsabs', 'Floats (absolute)'), ('floatsrel', 'Floats (relative)'), ('rstripped', 'Non-trailing spaces'), ('sorted', 'Unordered'), ('identical', 'Byte identical'), ('linecount', 'Line-by-line'), ('custom', 'Custom checker')], max_length=10, verbose_name='checker'), + ), + ] diff --git a/judge/migrations/0100_auto_20200127_0059.py b/judge/migrations/0100_auto_20200127_0059.py new file mode 100644 index 0000000..e070f7a --- /dev/null +++ b/judge/migrations/0100_auto_20200127_0059.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.9 on 2020-01-27 00:59 + +import django.core.validators +from django.db import migrations, models +import judge.models.problem_data +import judge.utils.problem_data + + +class Migration(migrations.Migration): + + dependencies = [ + ('judge', '0099_custom_checker'), + ] + + operations = [ + migrations.AlterField( + model_name='problemdata', + name='custom_checker', + field=models.FileField(blank=True, null=True, storage=judge.utils.problem_data.ProblemDataStorage(), upload_to=judge.models.problem_data.problem_directory_file, validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['py'])], verbose_name='custom checker file'), + ), + ] diff --git a/judge/models/problem_data.py b/judge/models/problem_data.py index 8ae25b7..6f6c88c 100644 --- a/judge/models/problem_data.py +++ b/judge/models/problem_data.py @@ -1,6 +1,7 @@ import errno import os +from django.core.validators import FileExtensionValidator from django.db import models from django.utils.translation import gettext_lazy as _ @@ -28,6 +29,7 @@ CHECKERS = ( ('sorted', _('Unordered')), ('identical', _('Byte identical')), ('linecount', _('Line-by-line')), + ('custom', _('Custom checker')), ) @@ -44,7 +46,12 @@ class ProblemData(models.Model): checker = models.CharField(max_length=10, verbose_name=_('checker'), choices=CHECKERS, blank=True) checker_args = models.TextField(verbose_name=_('checker arguments'), blank=True, help_text=_('checker arguments as a JSON object')) - + custom_checker = models.FileField(verbose_name=_('custom checker file'), + storage=problem_data_storage, + null=True, + blank=True, + upload_to=problem_directory_file, + validators=[FileExtensionValidator(allowed_extensions=['py'])]) __original_zipfile = None def __init__(self, *args, **kwargs): @@ -69,6 +76,8 @@ class ProblemData(models.Model): self.zipfile.name = _problem_directory_file(new, self.zipfile.name) if self.generator: self.generator.name = _problem_directory_file(new, self.generator.name) + if self.custom_checker: + self.custom_checker.name = _problem_directory_file(new, self.custom_checker.name) self.save() _update_code.alters_data = True diff --git a/judge/utils/problem_data.py b/judge/utils/problem_data.py index 9655f76..9c185fd 100644 --- a/judge/utils/problem_data.py +++ b/judge/utils/problem_data.py @@ -64,6 +64,11 @@ class ProblemDataCompiler(object): cases.append(batch) def make_checker(case): + if (case.checker == 'custom'): + custom_checker_path = split_path_first(case.custom_checker.name) + if len(custom_checker_path) != 2: + raise ProblemDataError(_('How did you corrupt the custom checker path?')) + return(custom_checker_path[1]) if case.checker_args: return { 'name': case.checker, diff --git a/judge/views/about.py b/judge/views/about.py new file mode 100644 index 0000000..d328066 --- /dev/null +++ b/judge/views/about.py @@ -0,0 +1,14 @@ +from django.shortcuts import render +from django.utils.translation import gettext as _ + + +def about(request): + return render(request, 'about/about.html', { + 'title': _('About'), + }) + + +def custom_checker_sample(request): + return render(request, 'about/custom-checker-sample.html', { + 'title': _('Custom Checker Sample'), + }) diff --git a/judge/views/problem_data.py b/judge/views/problem_data.py index 0223170..2c392aa 100644 --- a/judge/views/problem_data.py +++ b/judge/views/problem_data.py @@ -50,7 +50,7 @@ class ProblemDataForm(ModelForm): class Meta: model = ProblemData - fields = ['zipfile', 'generator', 'output_limit', 'output_prefix', 'checker', 'checker_args'] + fields = ['zipfile', 'generator', 'output_limit', 'output_prefix', 'checker', 'checker_args', 'custom_checker'] widgets = { 'checker_args': HiddenInput, } diff --git a/judge/views/submission.py b/judge/views/submission.py index bb496e6..d7ebfc0 100644 --- a/judge/views/submission.py +++ b/judge/views/submission.py @@ -1,28 +1,51 @@ import json +import os.path +import zipfile from operator import attrgetter from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.core.cache import cache -from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist, PermissionDenied -from django.db.models import Prefetch, Q -from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect, JsonResponse -from django.shortcuts import get_object_or_404, render +from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import ObjectDoesNotExist +from django.core.exceptions import PermissionDenied +from django.db.models import Prefetch +from django.db.models import Q +from django.http import Http404 +from django.http import HttpResponse +from django.http import HttpResponseBadRequest +from django.http import HttpResponseRedirect +from django.http import JsonResponse +from django.shortcuts import get_object_or_404 +from django.shortcuts import render from django.urls import reverse from django.utils import timezone from django.utils.functional import cached_property -from django.utils.html import escape, format_html +from django.utils.html import escape +from django.utils.html import format_html from django.utils.safestring import mark_safe -from django.utils.translation import gettext as _, gettext_lazy +from django.utils.translation import gettext as _ +from django.utils.translation import gettext_lazy from django.views.decorators.http import require_POST -from django.views.generic import DetailView, ListView +from django.views.generic import DetailView +from django.views.generic import ListView from judge import event_poster as event from judge.highlight_code import highlight_code -from judge.models import Contest, Language, Problem, ProblemTranslation, Profile, Submission -from judge.utils.problems import get_result_data, user_authored_ids, user_completed_ids, user_editable_ids +from judge.models import Contest +from judge.models import Language +from judge.models import Problem +from judge.models import ProblemTestCase +from judge.models import ProblemTranslation +from judge.models import Profile +from judge.models import Submission +from judge.utils.problems import get_result_data +from judge.utils.problems import user_authored_ids +from judge.utils.problems import user_completed_ids +from judge.utils.problems import user_editable_ids from judge.utils.raw_sql import use_straight_join -from judge.utils.views import DiggPaginatorMixin, TitleMixin +from judge.utils.views import DiggPaginatorMixin +from judge.utils.views import TitleMixin def submission_related(queryset): @@ -66,10 +89,12 @@ class SubmissionDetailBase(LoginRequiredMixin, TitleMixin, SubmissionMixin, Deta submission = self.object return mark_safe(escape(_('Submission of %(problem)s by %(user)s')) % { 'problem': format_html('{1}', - reverse('problem_detail', args=[submission.problem.code]), + reverse('problem_detail', args=[ + submission.problem.code]), submission.problem.translated_name(self.request.LANGUAGE_CODE)), 'user': format_html('{1}', - reverse('user_page', args=[submission.user.user.username]), + reverse('user_page', args=[ + submission.user.user.username]), submission.user.user.username), }) @@ -84,7 +109,8 @@ class SubmissionSource(SubmissionDetailBase): context = super(SubmissionSource, self).get_context_data(**kwargs) submission = self.object context['raw_source'] = submission.source.source.rstrip('\n') - context['highlighted_source'] = highlight_code(submission.source.source, submission.language.pygments) + context['highlighted_source'] = highlight_code( + submission.source.source, submission.language.pygments) return context @@ -111,6 +137,42 @@ def group_test_cases(cases): return result +def get_visible_content(data): + data = data or b'' + data = data.replace(b'\r\n', b'\r').replace(b'\r', b'\n') + if (len(data) > settings.TESTCASE_VISIBLE_LENGTH): + data = data[:settings.TESTCASE_VISIBLE_LENGTH] + data += b'.' * 3 + elif not data.endswith(b'\n'): + data += b'\n' + return data.decode('utf-8') + + +def get_input_answer(case, archive): + result = {} + result['input'] = get_visible_content(archive.read(case.input_file)) + result['answer'] = get_visible_content(archive.read(case.output_file)) + return result + + +def get_problem_data(submission): + archive_path = os.path.join(settings.DMOJ_PROBLEM_DATA_ROOT, + str(submission.problem.data_files.zipfile)) + if not os.path.exists(archive_path): + raise Exception( + 'archive file "%s" does not exist' % archive_path) + try: + archive = zipfile.ZipFile(archive_path, 'r') + except zipfile.BadZipfile: + raise Exception('bad archive: "%s"' % archive_path) + testcases = ProblemTestCase.objects.filter(dataset=submission.problem)\ + .order_by('order') + + problem_data = {case.order: get_input_answer(case, archive) + for case in testcases} + return problem_data + + class SubmissionStatus(SubmissionDetailBase): template_name = 'submission/status.html' @@ -120,8 +182,10 @@ class SubmissionStatus(SubmissionDetailBase): context['last_msg'] = event.last() context['batches'] = group_test_cases(submission.test_cases.all()) context['time_limit'] = submission.problem.time_limit + context['cases_data'] = get_problem_data(submission) try: - lang_limit = submission.problem.language_limits.get(language=submission.language) + lang_limit = submission.problem.language_limits.get( + language=submission.language) except ObjectDoesNotExist: pass else: @@ -135,7 +199,8 @@ class SubmissionTestCaseQuery(SubmissionStatus): def get(self, request, *args, **kwargs): if 'id' not in request.GET or not request.GET['id'].isdigit(): return HttpResponseBadRequest() - self.kwargs[self.pk_url_kwarg] = kwargs[self.pk_url_kwarg] = int(request.GET['id']) + self.kwargs[self.pk_url_kwarg] = kwargs[self.pk_url_kwarg] = int( + request.GET['id']) return super(SubmissionTestCaseQuery, self).get(request, *args, **kwargs) @@ -195,19 +260,24 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView): queryset=ProblemTranslation.objects.filter( language=self.request.LANGUAGE_CODE), to_attr='_trans')) if self.in_contest: - queryset = queryset.filter(contest__participation__contest_id=self.contest.id) + queryset = queryset.filter( + contest__participation__contest_id=self.contest.id) if self.contest.hide_scoreboard and self.contest.is_in_contest(self.request.user): - queryset = queryset.filter(contest__participation__user=self.request.profile) + queryset = queryset.filter( + contest__participation__user=self.request.profile) else: - queryset = queryset.select_related('contest_object').defer('contest_object__description') + queryset = queryset.select_related( + 'contest_object').defer('contest_object__description') # This is not technically correct since contest organizers *should* see these, but # the join would be far too messy if not self.request.user.has_perm('judge.see_private_contest'): - queryset = queryset.exclude(contest_object_id__in=Contest.objects.filter(hide_scoreboard=True)) + queryset = queryset.exclude( + contest_object_id__in=Contest.objects.filter(hide_scoreboard=True)) if self.selected_languages: - queryset = queryset.filter(language_id__in=Language.objects.filter(key__in=self.selected_languages)) + queryset = queryset.filter( + language_id__in=Language.objects.filter(key__in=self.selected_languages)) if self.selected_statuses: queryset = queryset.filter(result__in=self.selected_statuses) @@ -221,7 +291,8 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView): if not self.request.user.has_perm('judge.see_organization_problem'): filter = Q(problem__is_organization_private=False) if self.request.user.is_authenticated: - filter |= Q(problem__organizations__in=self.request.profile.organizations.all()) + filter |= Q( + problem__organizations__in=self.request.profile.organizations.all()) queryset = queryset.filter(filter) return queryset @@ -242,20 +313,26 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView): authenticated = self.request.user.is_authenticated context['dynamic_update'] = False context['show_problem'] = self.show_problem - context['completed_problem_ids'] = user_completed_ids(self.request.profile) if authenticated else [] - context['authored_problem_ids'] = user_authored_ids(self.request.profile) if authenticated else [] - context['editable_problem_ids'] = user_editable_ids(self.request.profile) if authenticated else [] + context['completed_problem_ids'] = user_completed_ids( + self.request.profile) if authenticated else [] + context['authored_problem_ids'] = user_authored_ids( + self.request.profile) if authenticated else [] + context['editable_problem_ids'] = user_editable_ids( + self.request.profile) if authenticated else [] - context['all_languages'] = Language.objects.all().values_list('key', 'name') + context['all_languages'] = Language.objects.all( + ).values_list('key', 'name') context['selected_languages'] = self.selected_languages context['all_statuses'] = self.get_searchable_status_codes() context['selected_statuses'] = self.selected_statuses context['results_json'] = mark_safe(json.dumps(self.get_result_data())) - context['results_colors_json'] = mark_safe(json.dumps(settings.DMOJ_STATS_SUBMISSION_RESULT_COLORS)) + context['results_colors_json'] = mark_safe( + json.dumps(settings.DMOJ_STATS_SUBMISSION_RESULT_COLORS)) - context['page_suffix'] = suffix = ('?' + self.request.GET.urlencode()) if self.request.GET else '' + context['page_suffix'] = suffix = ( + '?' + self.request.GET.urlencode()) if self.request.GET else '' context['first_page_href'] = (self.first_page_href or '.') + suffix context['my_submissions_link'] = self.get_my_submissions_page() context['all_submissions_link'] = self.get_all_submissions_page() @@ -280,14 +357,16 @@ class UserMixin(object): def get(self, request, *args, **kwargs): if 'user' not in kwargs: raise ImproperlyConfigured('Must pass a user') - self.profile = get_object_or_404(Profile, user__username=kwargs['user']) + self.profile = get_object_or_404( + Profile, user__username=kwargs['user']) self.username = kwargs['user'] return super(UserMixin, self).get(request, *args, **kwargs) class ConditionalUserTabMixin(object): def get_context_data(self, **kwargs): - context = super(ConditionalUserTabMixin, self).get_context_data(**kwargs) + context = super(ConditionalUserTabMixin, + self).get_context_data(**kwargs) if self.request.user.is_authenticated and self.request.profile == self.profile: context['tab'] = 'my_submissions_tab' else: @@ -355,19 +434,22 @@ class ProblemSubmissionsBase(SubmissionsListBase): if 'problem' not in kwargs: raise ImproperlyConfigured(_('Must pass a problem')) self.problem = get_object_or_404(Problem, code=kwargs['problem']) - self.problem_name = self.problem.translated_name(self.request.LANGUAGE_CODE) + self.problem_name = self.problem.translated_name( + self.request.LANGUAGE_CODE) return super(ProblemSubmissionsBase, self).get(request, *args, **kwargs) def get_all_submissions_page(self): return reverse('chronological_submissions', kwargs={'problem': self.problem.code}) def get_context_data(self, **kwargs): - context = super(ProblemSubmissionsBase, self).get_context_data(**kwargs) + context = super(ProblemSubmissionsBase, + self).get_context_data(**kwargs) if self.dynamic_update: context['dynamic_update'] = context['page_obj'].number == 1 context['dynamic_problem_id'] = self.problem.id context['last_msg'] = event.last() - context['best_submissions_link'] = reverse('ranked_submissions', kwargs={'problem': self.problem.code}) + context['best_submissions_link'] = reverse('ranked_submissions', kwargs={ + 'problem': self.problem.code}) return context @@ -402,14 +484,17 @@ class UserProblemSubmissions(ConditionalUserTabMixin, UserMixin, ProblemSubmissi def get_content_title(self): if self.request.user.is_authenticated and self.request.profile == self.profile: return format_html('''My submissions for {2}''', - self.username, reverse('user_page', args=[self.username]), + self.username, reverse( + 'user_page', args=[self.username]), self.problem_name, reverse('problem_detail', args=[self.problem.code])) return format_html('''{0}'s submissions for {2}''', - self.username, reverse('user_page', args=[self.username]), + self.username, reverse( + 'user_page', args=[self.username]), self.problem_name, reverse('problem_detail', args=[self.problem.code])) def get_context_data(self, **kwargs): - context = super(UserProblemSubmissions, self).get_context_data(**kwargs) + context = super(UserProblemSubmissions, + self).get_context_data(**kwargs) context['dynamic_user_id'] = self.profile.id return context @@ -417,7 +502,8 @@ class UserProblemSubmissions(ConditionalUserTabMixin, UserMixin, ProblemSubmissi def single_submission(request, submission_id, show_problem=True): request.no_profile_update = True authenticated = request.user.is_authenticated - submission = get_object_or_404(submission_related(Submission.objects.all()), id=int(submission_id)) + submission = get_object_or_404(submission_related( + Submission.objects.all()), id=int(submission_id)) if not submission.problem.is_accessible_by(request.user): raise Http404() @@ -515,11 +601,14 @@ class UserContestSubmissions(ForceContestMixin, UserProblemSubmissions): if self.problem.is_accessible_by(self.request.user): return format_html(_('{0}\'s submissions for ' '{2} in {4}'), - self.username, reverse('user_page', args=[self.username]), - self.problem_name, reverse('problem_detail', args=[self.problem.code]), + self.username, reverse( + 'user_page', args=[self.username]), + self.problem_name, reverse( + 'problem_detail', args=[self.problem.code]), self.contest.name, reverse('contest_view', args=[self.contest.key])) return format_html(_('{0}\'s submissions for ' 'problem {2} in {3}'), - self.username, reverse('user_page', args=[self.username]), + self.username, reverse( + 'user_page', args=[self.username]), self.get_problem_number(self.problem), self.contest.name, reverse('contest_view', args=[self.contest.key])) diff --git a/judge/widgets/pagedown.py b/judge/widgets/pagedown.py index d8d4de9..0968107 100644 --- a/judge/widgets/pagedown.py +++ b/judge/widgets/pagedown.py @@ -31,7 +31,6 @@ else: kwargs.setdefault('css', ('pagedown_widget.css',)) super(PagedownWidget, self).__init__(*args, **kwargs) - class AdminPagedownWidget(PagedownWidget, admin_widgets.AdminTextareaWidget): class Media: css = {'all': [ @@ -40,7 +39,6 @@ else: ]} js = ['admin/js/pagedown.js'] - class MathJaxPagedownWidget(PagedownWidget): class Media: js = [ @@ -49,11 +47,9 @@ else: 'pagedown_math.js', ] - class MathJaxAdminPagedownWidget(AdminPagedownWidget, MathJaxPagedownWidget): pass - class HeavyPreviewPageDownWidget(PagedownWidget): def __init__(self, *args, **kwargs): kwargs.setdefault('template', 'pagedown.html') @@ -86,7 +82,6 @@ else: css = {'all': ['dmmd-preview.css']} js = ['dmmd-preview.js'] - class HeavyPreviewAdminPageDownWidget(AdminPagedownWidget, HeavyPreviewPageDownWidget): class Media: css = {'all': [ diff --git a/requirements.txt b/requirements.txt index 7df0c72..564fa30 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,3 +30,7 @@ packaging celery -e git://github.com/DMOJ/ansi2html.git#egg=ansi2html sqlparse +channels +channels-redis +docker + diff --git a/resources/libs b/resources/libs new file mode 160000 index 0000000..2681309 --- /dev/null +++ b/resources/libs @@ -0,0 +1 @@ +Subproject commit 2681309a5ddd3482e699761488c75d9a62a626ec diff --git a/resources/pagedown b/resources/pagedown new file mode 160000 index 0000000..fce395c --- /dev/null +++ b/resources/pagedown @@ -0,0 +1 @@ +Subproject commit fce395c1e71920e065dbde3e184ffb61ef86996c diff --git a/templates/about/about.html b/templates/about/about.html new file mode 100644 index 0000000..70b97b9 --- /dev/null +++ b/templates/about/about.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block body %} +

+ I am cuom1999. +

+{% endblock %} \ No newline at end of file diff --git a/templates/about/custom-checker-sample.html b/templates/about/custom-checker-sample.html new file mode 100644 index 0000000..a2a74da --- /dev/null +++ b/templates/about/custom-checker-sample.html @@ -0,0 +1,1106 @@ +{% extends "base.html" %} + +{% block body %} + custom

Original Document

+

A checker Python script must implement a function that is called by the judge:

+
def check(process_output, judge_output, **kwargs):
+    # return True/False
+
+ +

Variables in global scope will exist throughout the grading process.

+

**kwargs is a directory containing

+
    +
  • submission_source: the source code of the submission
  • +
  • judge_input: the judge’s input
  • +
  • point_value: the point value of the test case
  • +
  • case_position: the index of the test case
  • +
  • batch: the batched the test case belongs to
  • +
  • submission_language: the language the submission was submitted in
  • +
  • binary_data: a boolean, which is True if the data was not normalized to Linux line endings, and False otherwise
  • +
  • execution_time: the runtime of the program, in seconds
  • +
+

Additionally, if the check method has the flag run_on_error set, it will be run against the submission’s output, even if it receives an IR/TLE/RTE/MLE verdict. +The only built-in checker that has this flag set is the linecount checker.

+

Return:

+

True for correct output, False for incorrect one

+

Sample Checker:

+

Here is the checker for the problem: Print 2 integers having sum equal to n (n is read from input).

+
def check(process_output, judge_output, judge_input, **kwargs):
+    # process the input
+    input_arr = judge_input.split()
+    assert(len(input_arr) == 1)
+    n = int(input_arr[0])
+
+    #  process the contestant's output
+    output_arr = process_output.split()
+
+    if (len(output_arr) != 2):
+        return False
+
+    try:
+        a, b = int(output_arr[0]), int(output_arr[1])
+    except:
+        return False
+
+    if (n == a + b):
+        return True
+    return False
+
+{% endblock body %} \ No newline at end of file diff --git a/templates/blog/list.html b/templates/blog/list.html index c5976d0..a28c442 100644 --- a/templates/blog/list.html +++ b/templates/blog/list.html @@ -266,3 +266,11 @@ {% block after_posts %}{% endblock %} {% endblock %} + +{% block bodyend %} + {{ super() }} + {% if REQUIRE_JAX %} + {% include "mathjax-load.html" %} + {% endif %} + {% include "comments/math.html" %} +{% endblock %} diff --git a/templates/chat/chat.html b/templates/chat/chat.html new file mode 100644 index 0000000..7b1eb9a --- /dev/null +++ b/templates/chat/chat.html @@ -0,0 +1,40 @@ +{% extends "base.html" %} + +{% block js_media %} + + +{% endblock js_media %} + +{% block body %} +
+
+ +{% endblock body %} diff --git a/templates/problem/data.html b/templates/problem/data.html index 83d16ed..389ec64 100644 --- a/templates/problem/data.html +++ b/templates/problem/data.html @@ -26,7 +26,7 @@ var $table = $('#case-table'); $table.on('add-row', function (e, $tr) { - update_select2(); + // update_select2(); $tr.find('input').filter('[id$=file]').each(function () { var $select, val = $(this).replaceWith($select = $(' + + + + + + Fill testcases + + +
{{ _('Show columns:') }} +
@@ -398,7 +485,8 @@ {% if cases_formset.can_delete %} - + {% endif %} @@ -444,7 +532,7 @@ {% endfor %}
{{ _('Checker') }} {{ _('Generator args') }}{{ _('Delete?') }}{{ _('Delete?') }} +
- + {{ _('Add new case') }} diff --git a/templates/submission/status-testcases.html b/templates/submission/status-testcases.html index 2c5740b..b9d9520 100644 --- a/templates/submission/status-testcases.html +++ b/templates/submission/status-testcases.html @@ -36,7 +36,7 @@ {% for case in batch.cases %} - {% if case.status != 'AC' and case.output and (prefix_length is none or prefix_length > 0) %} + {% if ((prefix_length is none or prefix_length > 0) or (request.user.is_superuser)) %} {% if case.extended_feedback %}
- {%- if case.status != 'AC' and case.output and (prefix_length is none or prefix_length > 0) -%} + {%- if ((prefix_length is none or prefix_length > 0) or (request.user.is_superuser)) -%} {%- endif -%} {%- if batch.id -%} @@ -72,16 +72,17 @@ {% endif %}