From b9f4cbacf6856c5a3bcdfeed3c74ec3cf442c75f Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 11 Aug 2015 20:23:22 +0800 Subject: [PATCH 01/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20dockerfile=EF=BC=8C?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=88=9B=E5=BB=BA=E4=B8=B4=E6=97=B6=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index 6dbbdd69..f10b84cd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,5 +7,7 @@ WORKDIR /var/oj/ RUN pip install -r requirements.txt EXPOSE 8080 RUN mkdir LOG +RUN mkdir test_case +RUN mkdir tmp RUN python manage.py migrate CMD python manage.py runserver 0.0.0.0:8080 From 408776910dc720184e3f1e101e7ea998c186a489 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 10:24:06 +0800 Subject: [PATCH 02/24] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E5=88=A4=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/controller/tasks.py | 5 +- judge/judger/client.py | 77 +---------------------- judge/judger/run.py | 125 ++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +- 4 files changed, 132 insertions(+), 78 deletions(-) create mode 100644 judge/judger/run.py diff --git a/judge/controller/tasks.py b/judge/controller/tasks.py index f0c32bc3..d87cde96 100644 --- a/judge/controller/tasks.py +++ b/judge/controller/tasks.py @@ -1,8 +1,11 @@ # coding=utf-8 from __future__ import absolute_import from judge.controller.celery import app +import subprocess32 as subprocess + +subprocess.call("ping baidu.com", timeout=5) @app.task def judge(source_code, language, test_case_id): - print source_code, language, test_case_id \ No newline at end of file + pass \ No newline at end of file diff --git a/judge/judger/client.py b/judge/judger/client.py index cdac0b22..d1595835 100644 --- a/judge/judger/client.py +++ b/judge/judger/client.py @@ -170,79 +170,4 @@ class JudgeClient(object): # http://stackoverflow.com/questions/25382455/python-notimplementederror-pool-objects-cannot-be-passed-between-processes self_dict = self.__dict__.copy() del self_dict['_pool'] - return self_dict - - - -c_src = r""" -#include -#include -int main() -{ - FILE *fp; - fp = NULL; - fprintf(fp, "This is testing for fprintf...\n"); - fputs("This is testing for fputs...\n", fp); - fclose(fp); - printf("111111"); - return 0; -} -""" - -cpp_src = r""" -#include - -using namespace std; - -int main() -{ - int a,b; - cin >> a >> b; - cout << a+b; - return 0; -} -""" - -java_src = r""" -import java.io.*; -import java.util.*; -11 -public class Main -{ - public static void main(String[] args) - { - Scanner in = new Scanner(System.in); - PrintWriter out = new PrintWriter(System.out); - - int a = in.nextInt(); - int b = in.nextInt(); - out.print(a + b); - throw new EmptyStackException(); - - } -} -""" -def judge(languege_code, source_string): - language = languages[str(languege_code)] - src_path = judger_workspace + language["src_name"] - f = open(src_path, "w") - f.write(source_string) - f.close() - - try: - exe_path = compile_(languages[str(languege_code)], src_path, judger_workspace) - except Exception as e: - print e - return [{"result": result["compile_error"]}] - - client = JudgeClient(language_code=languege_code, - exe_path=exe_path, - max_cpu_time=1000000, - max_real_time=200000, - max_memory=1000, - test_case_dir="/var/test_cases/1/") - return client.run() - -print judge(1, c_src) -print judge(2, cpp_src) -print judge(3, java_src) \ No newline at end of file + return self_dict \ No newline at end of file diff --git a/judge/judger/run.py b/judge/judger/run.py new file mode 100644 index 00000000..6a67e163 --- /dev/null +++ b/judge/judger/run.py @@ -0,0 +1,125 @@ +# coding=utf-8 +import sys +from client import JudgeClient +from language import languages +from compiler import compile_ +from result import result + +# +# c_src = r""" +# #include +# #include +# int main() +# { +# FILE *fp; +# fp = NULL; +# fprintf(fp, "This is testing for fprintf...\n"); +# fputs("This is testing for fputs...\n", fp); +# fclose(fp); +# printf("111111"); +# return 0; +# } +# """ +# +# cpp_src = r""" +# #include +# +# using namespace std; +# +# int main() +# { +# int a,b; +# cin >> a >> b; +# cout << a+b; +# return 0; +# } +# """ +# +# java_src = r""" +# import java.io.*; +# import java.util.*; +# 11 +# public class Main +# { +# public static void main(String[] args) +# { +# Scanner in = new Scanner(System.in); +# PrintWriter out = new PrintWriter(System.out); +# +# int a = in.nextInt(); +# int b = in.nextInt(); +# out.print(a + b); +# throw new EmptyStackException(); +# +# } +# } +# """ +# def judge(language_code, source_string): +# language = languages[str(language_code)] +# src_path = judger_workspace + language["src_name"] +# f = open(src_path, "w") +# f.write(source_string) +# f.close() +# +# try: +# exe_path = compile_(languages[str(language_code)], src_path, judger_workspace) +# except Exception as e: +# print e +# return [{"result": result["compile_error"]}] +# +# client = JudgeClient(language_code=language_code, +# exe_path=exe_path, +# max_cpu_time=1000000, +# max_real_time=200000, +# max_memory=1000, +# test_case_dir="/var/test_cases/1/") +# return client.run() +# +# print judge(1, c_src) +# print judge(2, cpp_src) +# print judge(3, java_src) + +judger_workspace = "/var/judger/" +# 简单的解析命令行参数 +# 参数有 -solution_id -max_cpu_time -max_memory -test_case_id +# 获取到的值是['xxx.py', '-solution_id', '1111', '-max_cpu_time', '1000', '-max_memory', '100', '-test_case_id', 'aaaa'] +args = sys.argv +solution_id = args[2] +max_cpu_time = args[4] +max_memory = args[6] +test_case_id = args[8] + +# todo 去数据库查一下 +language_code = 1 +source_string = """ +#include +int main() +{ + int a, b; + scanf("%d %d", &a, &b); + printf("%d", a + b); + return 0; +} +""" +language = languages[str(language_code)] +src_path = judger_workspace + language["src_name"] +f = open(src_path, "w") +f.write(source_string) +f.close() + +try: + exe_path = compile_(languages[str(language_code)], src_path, judger_workspace) +except Exception as e: + print e + print [{"result": result["compile_error"]}] + exit() + +client = JudgeClient(language_code=language_code, + exe_path=exe_path, + max_cpu_time=1000000, + max_real_time=200000, + max_memory=1000, + test_case_dir="/var/test_cases/1/") +print client.run() + + diff --git a/requirements.txt b/requirements.txt index bb0fce33..9835709e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ djangorestframework django-rest-swagger celery gunicorn -coverage \ No newline at end of file +coverage +subprocess32 \ No newline at end of file From 8979def927914143f150ebd0d3c7586ac002698a Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 10:56:03 +0800 Subject: [PATCH 03/24] =?UTF-8?q?=E7=BC=96=E8=AF=91=E6=97=B6=E5=BF=BD?= =?UTF-8?q?=E7=95=A5=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/judger/language.py | 4 +-- judge/judger/run.py | 75 +--------------------------------------- 2 files changed, 3 insertions(+), 76 deletions(-) diff --git a/judge/judger/language.py b/judge/judger/language.py index 5923edb7..3cbf0025 100644 --- a/judge/judger/language.py +++ b/judge/judger/language.py @@ -6,14 +6,14 @@ languages = { "name": "c", "src_name": "main.c", "code": 1, - "compile_command": "gcc -DONLINE_JUDGE -O2 -Wall -std=c99 -pipe {src_path} -lm -o {exe_path}main", + "compile_command": "gcc -DONLINE_JUDGE -O2 -w -std=c99 -pipe {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, "2": { "name": "cpp", "src_name": "main.cpp", "code": 2, - "compile_command": "g++ -DONLINE_JUDGE -O2 -Wall -std=c++11 -pipe {src_path} -lm -o {exe_path}main", + "compile_command": "g++ -DONLINE_JUDGE -O2 -w -std=c++11 -pipe {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, "3": { diff --git a/judge/judger/run.py b/judge/judger/run.py index 6a67e163..03474cfb 100644 --- a/judge/judger/run.py +++ b/judge/judger/run.py @@ -5,81 +5,8 @@ from language import languages from compiler import compile_ from result import result -# -# c_src = r""" -# #include -# #include -# int main() -# { -# FILE *fp; -# fp = NULL; -# fprintf(fp, "This is testing for fprintf...\n"); -# fputs("This is testing for fputs...\n", fp); -# fclose(fp); -# printf("111111"); -# return 0; -# } -# """ -# -# cpp_src = r""" -# #include -# -# using namespace std; -# -# int main() -# { -# int a,b; -# cin >> a >> b; -# cout << a+b; -# return 0; -# } -# """ -# -# java_src = r""" -# import java.io.*; -# import java.util.*; -# 11 -# public class Main -# { -# public static void main(String[] args) -# { -# Scanner in = new Scanner(System.in); -# PrintWriter out = new PrintWriter(System.out); -# -# int a = in.nextInt(); -# int b = in.nextInt(); -# out.print(a + b); -# throw new EmptyStackException(); -# -# } -# } -# """ -# def judge(language_code, source_string): -# language = languages[str(language_code)] -# src_path = judger_workspace + language["src_name"] -# f = open(src_path, "w") -# f.write(source_string) -# f.close() -# -# try: -# exe_path = compile_(languages[str(language_code)], src_path, judger_workspace) -# except Exception as e: -# print e -# return [{"result": result["compile_error"]}] -# -# client = JudgeClient(language_code=language_code, -# exe_path=exe_path, -# max_cpu_time=1000000, -# max_real_time=200000, -# max_memory=1000, -# test_case_dir="/var/test_cases/1/") -# return client.run() -# -# print judge(1, c_src) -# print judge(2, cpp_src) -# print judge(3, java_src) -judger_workspace = "/var/judger/" +judger_workspace = "/var/judger/run/" # 简单的解析命令行参数 # 参数有 -solution_id -max_cpu_time -max_memory -test_case_id # 获取到的值是['xxx.py', '-solution_id', '1111', '-max_cpu_time', '1000', '-max_memory', '100', '-test_case_id', 'aaaa'] From 88be032a384b3d9b4d095d5802a11fbf29bd1b12 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 14:01:34 +0800 Subject: [PATCH 04/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A4=E9=A2=98?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=EF=BC=9B=E5=A2=9E=E5=8A=A0web=20=E5=92=8C=20?= =?UTF-8?q?mongodb=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9A=84=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solution/models.py => config/__init__.py | 0 config/config.py | 2 + judge/README.md | 3 ++ judge/judger/language.py | 6 +-- judge/judger/run.py | 43 ++++++++------- oj/local_settings.py | 23 +++++--- oj/urls.py | 2 + problem/views.py | 13 ++--- requirements.txt | 3 +- solution/views.py | 3 -- static/src/js/app/oj/problem/problem.js | 6 ++- {solution => submission}/__init__.py | 0 {solution => submission}/admin.py | 0 .../migrations/__init__.py | 0 submission/models.py | 1 + submission/serializers.py | 10 ++++ {solution => submission}/tests.py | 0 submission/views.py | 52 +++++++++++++++++++ template/oj/problem/problem.html | 6 +-- 19 files changed, 127 insertions(+), 46 deletions(-) rename solution/models.py => config/__init__.py (100%) create mode 100644 config/config.py create mode 100644 judge/README.md delete mode 100644 solution/views.py rename {solution => submission}/__init__.py (100%) rename {solution => submission}/admin.py (100%) rename {solution => submission}/migrations/__init__.py (100%) create mode 100644 submission/models.py create mode 100644 submission/serializers.py rename {solution => submission}/tests.py (100%) create mode 100644 submission/views.py diff --git a/solution/models.py b/config/__init__.py similarity index 100% rename from solution/models.py rename to config/__init__.py diff --git a/config/config.py b/config/config.py new file mode 100644 index 00000000..89d316b8 --- /dev/null +++ b/config/config.py @@ -0,0 +1,2 @@ +# coding=utf-8 +DB_NAME = "db.sqlite3" diff --git a/judge/README.md b/judge/README.md new file mode 100644 index 00000000..c40444b1 --- /dev/null +++ b/judge/README.md @@ -0,0 +1,3 @@ +/usr/bin/docker run -t -i --privileged -v /var/test_case/:/var/judger/test_case/ -v /var/code/:/var/judger/code/ judger /bin/bash + +python judge/judger/run.py -solution_id 1 -max_cpu_time 1 -max_memory 1 -test_case_id 1 diff --git a/judge/judger/language.py b/judge/judger/language.py index 3cbf0025..c79b2967 100644 --- a/judge/judger/language.py +++ b/judge/judger/language.py @@ -2,21 +2,21 @@ languages = { - "1": { + 1: { "name": "c", "src_name": "main.c", "code": 1, "compile_command": "gcc -DONLINE_JUDGE -O2 -w -std=c99 -pipe {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, - "2": { + 2: { "name": "cpp", "src_name": "main.cpp", "code": 2, "compile_command": "g++ -DONLINE_JUDGE -O2 -w -std=c++11 -pipe {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, - "3": { + 3: { "name": "java", "src_name": "Main.java", "code": 3, diff --git a/judge/judger/run.py b/judge/judger/run.py index 03474cfb..f75e81d8 100644 --- a/judge/judger/run.py +++ b/judge/judger/run.py @@ -1,12 +1,17 @@ # coding=utf-8 import sys +import pymongo + +from bson.objectid import ObjectId + from client import JudgeClient from language import languages from compiler import compile_ from result import result +from settings import judger_workspace +from oj import settings -judger_workspace = "/var/judger/run/" # 简单的解析命令行参数 # 参数有 -solution_id -max_cpu_time -max_memory -test_case_id # 获取到的值是['xxx.py', '-solution_id', '1111', '-max_cpu_time', '1000', '-max_memory', '100', '-test_case_id', 'aaaa'] @@ -16,37 +21,37 @@ max_cpu_time = args[4] max_memory = args[6] test_case_id = args[8] -# todo 去数据库查一下 -language_code = 1 -source_string = """ -#include -int main() -{ - int a, b; - scanf("%d %d", &a, &b); - printf("%d", a + b); - return 0; -} -""" -language = languages[str(language_code)] -src_path = judger_workspace + language["src_name"] + +mongodb_setting = settings.DATABASES["mongodb"] +connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) +collection = connection["oj"]["oj_submission"] + +submission = collection.find_one({"_id": ObjectId(solution_id)}) +if not submission: + exit() + + +# 将代码写入文件 +language = languages[submission["language"]] +src_path = judger_workspace + "run/" + language["src_name"] f = open(src_path, "w") -f.write(source_string) +f.write(submission["code"]) f.close() +# 编译 try: - exe_path = compile_(languages[str(language_code)], src_path, judger_workspace) + exe_path = compile_(language, src_path, judger_workspace + "run/") except Exception as e: print e print [{"result": result["compile_error"]}] exit() -client = JudgeClient(language_code=language_code, +client = JudgeClient(language_code=language, exe_path=exe_path, max_cpu_time=1000000, max_real_time=200000, max_memory=1000, - test_case_dir="/var/test_cases/1/") + test_case_dir="/var/judger/test_case/" + str(test_case_id) + "/") print client.run() diff --git a/oj/local_settings.py b/oj/local_settings.py index a99e0097..2f384965 100644 --- a/oj/local_settings.py +++ b/oj/local_settings.py @@ -1,19 +1,28 @@ # coding=utf-8 import os -LOG_PATH = "LOG/" - -# Database -# https://docs.djangoproject.com/en/1.8/ref/settings/#databases BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# 下面是需要自己修改的 +LOG_PATH = "LOG/" + DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - 'CONN_MAX_AGE': 1, + 'CONN_MAX_AGE': 0.3, + }, + 'mongodb': { + 'HOST': '127.0.0.1', + 'USERNAME': 'root', + 'PASSWORD': 'root', + 'PORT': 27017 } } -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True \ No newline at end of file + +DEBUG = True + +TEST_CASE_DIR = "/var/test_case/" + diff --git a/oj/urls.py b/oj/urls.py index e3fbcdaf..5c7171f4 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -14,6 +14,7 @@ from admin.views import AdminTemplateView from problem.views import ProblemAdminAPIView from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView +from submission.views import SubmissionnAPIView urlpatterns = [ @@ -50,5 +51,6 @@ urlpatterns = [ url(r'^my_solution/(?P\d+)/$', "problem.views.my_solution", name="my_solution_page"), url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), name="join_group_request_admin_api"), + url(r'^api/submission/$', SubmissionnAPIView.as_view(), name="submission_api"), ] diff --git a/problem/views.py b/problem/views.py index f9677b1c..e8f3e9a7 100644 --- a/problem/views.py +++ b/problem/views.py @@ -10,6 +10,8 @@ from django.db.models import Q from rest_framework.views import APIView +from django.conf import settings + from utils.shortcuts import serializer_invalid_response, error_response, success_response, paginate, rand_str from .serizalizers import (CreateProblemSerializer, EditProblemSerializer, ProblemSerializer, ProblemTagSerializer, CreateProblemTagSerializer) @@ -35,13 +37,6 @@ class ProblemTagAdminAPIView(APIView): def get(self, request): return success_response(ProblemTagSerializer(ProblemTag.objects.all(), many=True).data) - keyword = request.GET.get("keyword", None) - if not keyword: - return error_response(u"参数错误") - tags = ProblemTag.objects.filter(name__contains=keyword) - return success_response(ProblemTagSerializer(tags, many=True).data) - - def problem_page(request, problem_id): @@ -159,7 +154,7 @@ class TestCaseUploadAPIView(APIView): f = request.FILES["file"] - tmp_zip = "tmp/" + rand_str() + ".zip" + tmp_zip = "/tmp/" + rand_str() + ".zip" with open(tmp_zip, "wb") as test_case_zip: for chunk in f: test_case_zip.write(chunk) @@ -192,7 +187,7 @@ class TestCaseUploadAPIView(APIView): return error_response(u"测试用例文件不完整,缺少" + name[0] + ".in") problem_test_dir = rand_str() - test_case_dir = "test_case/" + problem_test_dir + "/" + test_case_dir = settings.TEST_CASE_DIR + "test_case/" + problem_test_dir + "/" # 得到了合法的测试用例文件列表 然后去解压缩 os.mkdir(test_case_dir) diff --git a/requirements.txt b/requirements.txt index 9835709e..324d7b0d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,5 @@ django-rest-swagger celery gunicorn coverage -subprocess32 \ No newline at end of file +subprocess32 +pymongo \ No newline at end of file diff --git a/solution/views.py b/solution/views.py deleted file mode 100644 index 91ea44a2..00000000 --- a/solution/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js index a713c07f..5b10211d 100644 --- a/static/src/js/app/oj/problem/problem.js +++ b/static/src/js/app/oj/problem/problem.js @@ -1,8 +1,9 @@ require(["jquery", "code_mirror"], function ($, code_mirror) { var code_editor = code_mirror($("#code-editor")[0], "text/x-csrc"); + var language = "1"; $("#language-selector").change(function () { - var language = $("#language-selector").val(); + language = $("#language-selector").val(); var language_types = {c: "text/x-csrc", cpp: "text/x-c++src", java: "text/x-java"}; code_editor.setOption("mode", language_types[language]); }); @@ -19,6 +20,9 @@ require(["jquery", "code_mirror"], function ($, code_mirror) { $("#submit-code-button").click(function () { show_loading(); + $.ajax({ + + }); setTimeout( function () { $("#a").animate({opacity: '1'}) diff --git a/solution/__init__.py b/submission/__init__.py similarity index 100% rename from solution/__init__.py rename to submission/__init__.py diff --git a/solution/admin.py b/submission/admin.py similarity index 100% rename from solution/admin.py rename to submission/admin.py diff --git a/solution/migrations/__init__.py b/submission/migrations/__init__.py similarity index 100% rename from solution/migrations/__init__.py rename to submission/migrations/__init__.py diff --git a/submission/models.py b/submission/models.py new file mode 100644 index 00000000..9bad5790 --- /dev/null +++ b/submission/models.py @@ -0,0 +1 @@ +# coding=utf-8 diff --git a/submission/serializers.py b/submission/serializers.py new file mode 100644 index 00000000..c64ada6c --- /dev/null +++ b/submission/serializers.py @@ -0,0 +1,10 @@ +# coding=utf-8 +from rest_framework import serializers + + + +class CreateSubmissionSerializer(serializers.Serializer): + problem_id = serializers.IntegerField() + language = serializers.IntegerField() + code = serializers.CharField(max_length=3000) + diff --git a/solution/tests.py b/submission/tests.py similarity index 100% rename from solution/tests.py rename to submission/tests.py diff --git a/submission/views.py b/submission/views.py new file mode 100644 index 00000000..8af26f1f --- /dev/null +++ b/submission/views.py @@ -0,0 +1,52 @@ +# coding=utf-8 +import pymongo +from bson.objectid import ObjectId + +from django.shortcuts import render + +from rest_framework.views import APIView + +from django.conf import settings + +from judge.judger.result import result +from account.decorators import login_required +from utils.shortcuts import serializer_invalid_response, error_response, success_response +from .serializers import CreateSubmissionSerializer + + +class SubmissionnAPIView(APIView): + def _create_mondodb_connection(self): + mongodb_setting = settings.DATABASES["mongodb"] + connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) + return connection["oj"]["oj_submission"] + + # @login_required + def post(self, request): + """ + 提交代码 + --- + request_serializer: CreateSubmissionSerializer + """ + serializer = CreateSubmissionSerializer(data=request.data) + if serializer.is_valid(): + data = serializer.data + data["user_id"] = request.user.id + data["result"] = result["waiting"] + mongodb_setting = settings.DATABASES["mongodb"] + connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) + collection = connection["oj"]["oj_submission"] + submission_id = str(collection.insert_one(data).inserted_id) + return success_response({"submission_id": submission_id}) + else: + return serializer_invalid_response(serializer) + + # @login_required + def get(self, request): + submission_id = request.GET.get("submission_id", None) + if not submission_id: + return error_response(u"参数错误") + submission = self._create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": result.user.id}) + if submission: + return success_response({"result": submission["result"]}) + else: + return error_response(u"提交不存在") diff --git a/template/oj/problem/problem.html b/template/oj/problem/problem.html index 5a7a3b65..b3f1623e 100644 --- a/template/oj/problem/problem.html +++ b/template/oj/problem/problem.html @@ -66,13 +66,13 @@
From 2ba1fa56691214a9f239da1d34ee11fbcd6225d0 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 14:56:18 +0800 Subject: [PATCH 05/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/controller/tasks.py | 10 ++++++---- judge/judger/run.py | 14 +++++++------- problem/views.py | 2 +- submission/views.py | 7 +++++++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/judge/controller/tasks.py b/judge/controller/tasks.py index d87cde96..42b88ee0 100644 --- a/judge/controller/tasks.py +++ b/judge/controller/tasks.py @@ -3,9 +3,11 @@ from __future__ import absolute_import from judge.controller.celery import app import subprocess32 as subprocess -subprocess.call("ping baidu.com", timeout=5) - @app.task -def judge(source_code, language, test_case_id): - pass \ No newline at end of file +def judge(solution_id, time_limit, memory_limit, test_case_id): + subprocess.call("/usr/bin/docker run -t -i --privileged -v /var/test_case/:/var/judger/test_case/ " + "-v /var/code/:/var/judger/code/ judger python judge/judger/run.py " + "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % + (solution_id, str(time_limit), str(memory_limit), test_case_id), + timeout=(time_limit / 100) * 20) diff --git a/judge/judger/run.py b/judge/judger/run.py index f75e81d8..40da1dcb 100644 --- a/judge/judger/run.py +++ b/judge/judger/run.py @@ -13,12 +13,12 @@ from settings import judger_workspace from oj import settings # 简单的解析命令行参数 -# 参数有 -solution_id -max_cpu_time -max_memory -test_case_id -# 获取到的值是['xxx.py', '-solution_id', '1111', '-max_cpu_time', '1000', '-max_memory', '100', '-test_case_id', 'aaaa'] +# 参数有 -solution_id -time_limit -memory_limit -test_case_id +# 获取到的值是['xxx.py', '-solution_id', '1111', '-time_limit', '1000', '-memory_limit', '100', '-test_case_id', 'aaaa'] args = sys.argv solution_id = args[2] -max_cpu_time = args[4] -max_memory = args[6] +time_limit = args[4] +memory_limit = args[6] test_case_id = args[8] @@ -48,9 +48,9 @@ except Exception as e: client = JudgeClient(language_code=language, exe_path=exe_path, - max_cpu_time=1000000, - max_real_time=200000, - max_memory=1000, + max_cpu_time=int(time_limit), + max_real_time=int(time_limit) * 2, + max_memory=int(memory_limit), test_case_dir="/var/judger/test_case/" + str(test_case_id) + "/") print client.run() diff --git a/problem/views.py b/problem/views.py index e8f3e9a7..7669816d 100644 --- a/problem/views.py +++ b/problem/views.py @@ -187,7 +187,7 @@ class TestCaseUploadAPIView(APIView): return error_response(u"测试用例文件不完整,缺少" + name[0] + ".in") problem_test_dir = rand_str() - test_case_dir = settings.TEST_CASE_DIR + "test_case/" + problem_test_dir + "/" + test_case_dir = settings.TEST_CASE_DIR + problem_test_dir + "/" # 得到了合法的测试用例文件列表 然后去解压缩 os.mkdir(test_case_dir) diff --git a/submission/views.py b/submission/views.py index 8af26f1f..54256809 100644 --- a/submission/views.py +++ b/submission/views.py @@ -9,7 +9,9 @@ from rest_framework.views import APIView from django.conf import settings from judge.judger.result import result +from judge.controller.tasks import judge from account.decorators import login_required +from problem.models import Problem from utils.shortcuts import serializer_invalid_response, error_response, success_response from .serializers import CreateSubmissionSerializer @@ -32,10 +34,15 @@ class SubmissionnAPIView(APIView): data = serializer.data data["user_id"] = request.user.id data["result"] = result["waiting"] + try: + problem = Problem.objects.get(id=data["problem_id"]) + except Problem.DoesNotExist: + return error_response(u"题目不存在") mongodb_setting = settings.DATABASES["mongodb"] connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) collection = connection["oj"]["oj_submission"] submission_id = str(collection.insert_one(data).inserted_id) + judge.deply(submission_id, problem.max_cpu_time, problem_) return success_response({"submission_id": submission_id}) else: return serializer_invalid_response(serializer) From 702d51f495032233df3b7ad29a2cb59631ce1cae Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 15:06:19 +0800 Subject: [PATCH 06/24] fix typo --- submission/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submission/views.py b/submission/views.py index 54256809..1208632c 100644 --- a/submission/views.py +++ b/submission/views.py @@ -42,7 +42,7 @@ class SubmissionnAPIView(APIView): connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) collection = connection["oj"]["oj_submission"] submission_id = str(collection.insert_one(data).inserted_id) - judge.deply(submission_id, problem.max_cpu_time, problem_) + judge.delay(submission_id, problem.max_cpu_time, problem.max_memory, problem.test_case_id) return success_response({"submission_id": submission_id}) else: return serializer_invalid_response(serializer) From 92ab7e5fb279e4b05a01e72dc0ebe8e61edcfed5 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 16:49:25 +0800 Subject: [PATCH 07/24] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge/controller/tasks.py | 13 ----------- {judge/judger => judger}/__init__.py | 0 {judge/judger => judger}/client.py | 0 {judge/judger => judger}/compiler.py | 0 {judge/judger => judger}/judge_exceptions.py | 0 {judge/judger => judger}/language.py | 0 {judge/judger => judger}/result.py | 0 {judge/judger => judger}/run.py | 23 ++++++++++++------- {judge/judger => judger}/settings.py | 0 {judge/judger => judger}/utils.py | 0 .../README.md | 0 .../__init__.py | 0 .../celery.py | 2 +- judger_controller/tasks.py | 20 ++++++++++++++++ submission/views.py | 6 ++--- 15 files changed, 39 insertions(+), 25 deletions(-) delete mode 100644 judge/controller/tasks.py rename {judge/judger => judger}/__init__.py (100%) rename {judge/judger => judger}/client.py (100%) rename {judge/judger => judger}/compiler.py (100%) rename {judge/judger => judger}/judge_exceptions.py (100%) rename {judge/judger => judger}/language.py (100%) rename {judge/judger => judger}/result.py (100%) rename {judge/judger => judger}/run.py (70%) rename {judge/judger => judger}/settings.py (100%) rename {judge/judger => judger}/utils.py (100%) rename {judge/controller => judger_controller}/README.md (100%) rename {judge/controller => judger_controller}/__init__.py (100%) rename {judge/controller => judger_controller}/celery.py (83%) create mode 100644 judger_controller/tasks.py diff --git a/judge/controller/tasks.py b/judge/controller/tasks.py deleted file mode 100644 index 42b88ee0..00000000 --- a/judge/controller/tasks.py +++ /dev/null @@ -1,13 +0,0 @@ -# coding=utf-8 -from __future__ import absolute_import -from judge.controller.celery import app -import subprocess32 as subprocess - - -@app.task -def judge(solution_id, time_limit, memory_limit, test_case_id): - subprocess.call("/usr/bin/docker run -t -i --privileged -v /var/test_case/:/var/judger/test_case/ " - "-v /var/code/:/var/judger/code/ judger python judge/judger/run.py " - "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % - (solution_id, str(time_limit), str(memory_limit), test_case_id), - timeout=(time_limit / 100) * 20) diff --git a/judge/judger/__init__.py b/judger/__init__.py similarity index 100% rename from judge/judger/__init__.py rename to judger/__init__.py diff --git a/judge/judger/client.py b/judger/client.py similarity index 100% rename from judge/judger/client.py rename to judger/client.py diff --git a/judge/judger/compiler.py b/judger/compiler.py similarity index 100% rename from judge/judger/compiler.py rename to judger/compiler.py diff --git a/judge/judger/judge_exceptions.py b/judger/judge_exceptions.py similarity index 100% rename from judge/judger/judge_exceptions.py rename to judger/judge_exceptions.py diff --git a/judge/judger/language.py b/judger/language.py similarity index 100% rename from judge/judger/language.py rename to judger/language.py diff --git a/judge/judger/result.py b/judger/result.py similarity index 100% rename from judge/judger/result.py rename to judger/result.py diff --git a/judge/judger/run.py b/judger/run.py similarity index 70% rename from judge/judger/run.py rename to judger/run.py index 40da1dcb..70d6db2e 100644 --- a/judge/judger/run.py +++ b/judger/run.py @@ -10,6 +10,11 @@ from compiler import compile_ from result import result from settings import judger_workspace +import sys +import os +sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..')) +print sys.path + from oj import settings # 简单的解析命令行参数 @@ -46,12 +51,14 @@ except Exception as e: print [{"result": result["compile_error"]}] exit() -client = JudgeClient(language_code=language, - exe_path=exe_path, - max_cpu_time=int(time_limit), - max_real_time=int(time_limit) * 2, - max_memory=int(memory_limit), - test_case_dir="/var/judger/test_case/" + str(test_case_id) + "/") -print client.run() - +try: + client = JudgeClient(language_code=language, + exe_path=exe_path, + max_cpu_time=int(time_limit), + max_real_time=int(time_limit) * 2, + max_memory=int(memory_limit), + test_case_dir="/var/judger/test_case/" + str(test_case_id) + "/") + print client.run() +except Exception as e: + print e diff --git a/judge/judger/settings.py b/judger/settings.py similarity index 100% rename from judge/judger/settings.py rename to judger/settings.py diff --git a/judge/judger/utils.py b/judger/utils.py similarity index 100% rename from judge/judger/utils.py rename to judger/utils.py diff --git a/judge/controller/README.md b/judger_controller/README.md similarity index 100% rename from judge/controller/README.md rename to judger_controller/README.md diff --git a/judge/controller/__init__.py b/judger_controller/__init__.py similarity index 100% rename from judge/controller/__init__.py rename to judger_controller/__init__.py diff --git a/judge/controller/celery.py b/judger_controller/celery.py similarity index 83% rename from judge/controller/celery.py rename to judger_controller/celery.py index 8e776e2d..d7e0d476 100644 --- a/judge/controller/celery.py +++ b/judger_controller/celery.py @@ -2,4 +2,4 @@ from __future__ import absolute_import from celery import Celery -app = Celery("judge", broker="redis://localhost:6379/0", include=["judge.controller.tasks"]) \ No newline at end of file +app = Celery("judge", broker="redis://localhost:6379/0", include=["judger_controller.tasks"]) \ No newline at end of file diff --git a/judger_controller/tasks.py b/judger_controller/tasks.py new file mode 100644 index 00000000..9ac60072 --- /dev/null +++ b/judger_controller/tasks.py @@ -0,0 +1,20 @@ +# coding=utf-8 +from __future__ import absolute_import +from judger_controller.celery import app +import subprocess32 as subprocess + + +@app.task +def judge(solution_id, time_limit, memory_limit, test_case_id): + try: + subprocess.call("docker run -t -i --privileged --rm=true " + "-v /var/test_case/:/var/judger/test_case/ " + "-v /Users/virusdefender/Desktop/:/var/judger/code/ " + "-p 27017:27017 " + "judger " + "python judger/run.py " + "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % + (solution_id, str(time_limit), str(memory_limit), test_case_id), + timeout=(time_limit / 100) * 20, shell=True) + except subprocess.TimeoutExpired: + print "docker timeout" diff --git a/submission/views.py b/submission/views.py index 1208632c..993de50f 100644 --- a/submission/views.py +++ b/submission/views.py @@ -8,8 +8,8 @@ from rest_framework.views import APIView from django.conf import settings -from judge.judger.result import result -from judge.controller.tasks import judge +from judger.result import result +from judger_controller.tasks import judge from account.decorators import login_required from problem.models import Problem from utils.shortcuts import serializer_invalid_response, error_response, success_response @@ -42,7 +42,7 @@ class SubmissionnAPIView(APIView): connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) collection = connection["oj"]["oj_submission"] submission_id = str(collection.insert_one(data).inserted_id) - judge.delay(submission_id, problem.max_cpu_time, problem.max_memory, problem.test_case_id) + judge.delay(submission_id, problem.time_limit, problem.memory_limit, problem.test_case_id) return success_response({"submission_id": submission_id}) else: return serializer_invalid_response(serializer) From 66d3cd3bfeda059e80eee605a08c6d7db13f77b1 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 19:55:41 +0800 Subject: [PATCH 08/24] =?UTF-8?q?=E5=88=A4=E9=A2=98=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E8=B7=91=E8=B5=B7=E6=9D=A5=E4=BA=86=EF=BC=8C?= =?UTF-8?q?=E7=9C=9F=E8=A6=81=E8=A2=AB=E8=87=AA=E5=B7=B1=E8=A0=A2=E5=93=AD?= =?UTF-8?q?=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/__init__.py | 1 - config/config.py | 2 -- judger/client.py | 2 +- judger/compiler.py | 1 - judger/language.py | 4 ++-- judger/run.py | 23 +++++++---------------- judger/settings.py | 9 ++++++++- judger_controller/celery.py | 7 ++++++- judger_controller/settings.py | 6 ++++++ judger_controller/tasks.py | 6 +++--- oj/local_settings.py | 4 +++- static/src/js/app/oj/problem/problem.js | 8 ++++++-- submission/views.py | 1 + 13 files changed, 43 insertions(+), 31 deletions(-) delete mode 100644 config/__init__.py delete mode 100644 config/config.py create mode 100644 judger_controller/settings.py diff --git a/config/__init__.py b/config/__init__.py deleted file mode 100644 index 9bad5790..00000000 --- a/config/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# coding=utf-8 diff --git a/config/config.py b/config/config.py deleted file mode 100644 index 89d316b8..00000000 --- a/config/config.py +++ /dev/null @@ -1,2 +0,0 @@ -# coding=utf-8 -DB_NAME = "db.sqlite3" diff --git a/judger/client.py b/judger/client.py index d1595835..52f65862 100644 --- a/judger/client.py +++ b/judger/client.py @@ -30,7 +30,7 @@ class JudgeClient(object): :param test_case_dir: 测试用例文件夹路径 :return:返回结果list """ - self._language = languages[str(language_code)] + self._language = languages[language_code] self._exe_path = exe_path self._max_cpu_time = max_cpu_time self._max_real_time = max_real_time diff --git a/judger/compiler.py b/judger/compiler.py index d4bca4bb..7f40ff1c 100644 --- a/judger/compiler.py +++ b/judger/compiler.py @@ -32,5 +32,4 @@ def compile_(language_item, src_path, exe_path): if parse_result["exit_code"] or parse_result["term_sig"] or parse_result["siginaled"] or parse_result["exceed"]: raise CompileError("Compile error") - return exe_path diff --git a/judger/language.py b/judger/language.py index c79b2967..a61bd32b 100644 --- a/judger/language.py +++ b/judger/language.py @@ -6,14 +6,14 @@ languages = { "name": "c", "src_name": "main.c", "code": 1, - "compile_command": "gcc -DONLINE_JUDGE -O2 -w -std=c99 -pipe {src_path} -lm -o {exe_path}main", + "compile_command": "gcc -DONLINE_JUDGE -O2 -w -std=c99 {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, 2: { "name": "cpp", "src_name": "main.cpp", "code": 2, - "compile_command": "g++ -DONLINE_JUDGE -O2 -w -std=c++11 -pipe {src_path} -lm -o {exe_path}main", + "compile_command": "g++ -DONLINE_JUDGE -O2 -w -std=c++11 {src_path} -lm -o {exe_path}main", "execute_command": "{exe_path}main" }, 3: { diff --git a/judger/run.py b/judger/run.py index 70d6db2e..1e83bb84 100644 --- a/judger/run.py +++ b/judger/run.py @@ -8,14 +8,8 @@ from client import JudgeClient from language import languages from compiler import compile_ from result import result -from settings import judger_workspace +from settings import judger_workspace, mongodb_config -import sys -import os -sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..')) -print sys.path - -from oj import settings # 简单的解析命令行参数 # 参数有 -solution_id -time_limit -memory_limit -test_case_id @@ -26,16 +20,13 @@ time_limit = args[4] memory_limit = args[6] test_case_id = args[8] - -mongodb_setting = settings.DATABASES["mongodb"] -connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) +connection = pymongo.MongoClient(host=mongodb_config["host"], port=mongodb_config["port"]) collection = connection["oj"]["oj_submission"] submission = collection.find_one({"_id": ObjectId(solution_id)}) if not submission: exit() - # 将代码写入文件 language = languages[submission["language"]] src_path = judger_workspace + "run/" + language["src_name"] @@ -47,18 +38,18 @@ f.close() try: exe_path = compile_(language, src_path, judger_workspace + "run/") except Exception as e: - print e - print [{"result": result["compile_error"]}] + print {"result": result["compile_error"]} exit() - try: - client = JudgeClient(language_code=language, + client = JudgeClient(language_code=submission["language"], exe_path=exe_path, max_cpu_time=int(time_limit), max_real_time=int(time_limit) * 2, max_memory=int(memory_limit), - test_case_dir="/var/judger/test_case/" + str(test_case_id) + "/") + test_case_dir= judger_workspace + "test_case/" + test_case_id + "/") print client.run() except Exception as e: print e + print {"result": result["system_error"]} + diff --git a/judger/settings.py b/judger/settings.py index 8fea94bb..b70f4543 100644 --- a/judger/settings.py +++ b/judger/settings.py @@ -11,5 +11,12 @@ lrun_uid = 1001 # lrun用户组gid lrun_gid = 1002 -#judger工作目录 +# judger工作目录 judger_workspace = "/var/judger/" + +mongodb_config = { + "host": "192.168.59.3", + "username": "root", + "password": "root", + "port": 27017 +} diff --git a/judger_controller/celery.py b/judger_controller/celery.py index d7e0d476..35ba2ac0 100644 --- a/judger_controller/celery.py +++ b/judger_controller/celery.py @@ -1,5 +1,10 @@ # coding=utf-8 from __future__ import absolute_import from celery import Celery +from .settings import redis_config -app = Celery("judge", broker="redis://localhost:6379/0", include=["judger_controller.tasks"]) \ No newline at end of file +app = Celery("judge", broker="redis://" + + redis_config["host"] + ":" + + str(redis_config["port"]) + + "/" + str(redis_config["db"]), + include=["judger_controller.tasks"]) diff --git a/judger_controller/settings.py b/judger_controller/settings.py new file mode 100644 index 00000000..4d492ebd --- /dev/null +++ b/judger_controller/settings.py @@ -0,0 +1,6 @@ +# coding=utf-8 +redis_config = { + "host": "127.0.0.1", + "port": 6379, + "db": 0 +} \ No newline at end of file diff --git a/judger_controller/tasks.py b/judger_controller/tasks.py index 9ac60072..054452c8 100644 --- a/judger_controller/tasks.py +++ b/judger_controller/tasks.py @@ -8,13 +8,13 @@ import subprocess32 as subprocess def judge(solution_id, time_limit, memory_limit, test_case_id): try: subprocess.call("docker run -t -i --privileged --rm=true " - "-v /var/test_case/:/var/judger/test_case/ " + "-v /Users/virusdefender/Desktop/test_case/:/var/judger/test_case/ " "-v /Users/virusdefender/Desktop/:/var/judger/code/ " - "-p 27017:27017 " "judger " "python judger/run.py " "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % (solution_id, str(time_limit), str(memory_limit), test_case_id), - timeout=(time_limit / 100) * 20, shell=True) + # 如果设置的最长运行时间小于1000毫秒,那么/1000就是0,处理一下这个情况,设置为两秒 + timeout=(time_limit / 1000 * 3) or 2, shell=True) except subprocess.TimeoutExpired: print "docker timeout" diff --git a/oj/local_settings.py b/oj/local_settings.py index 2f384965..eff9818c 100644 --- a/oj/local_settings.py +++ b/oj/local_settings.py @@ -7,6 +7,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 下面是需要自己修改的 LOG_PATH = "LOG/" +# 注意这是web 服务器访问的地址,判题度武器访问的地址不一定一样,因为可能不在一台机器上 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', @@ -24,5 +25,6 @@ DATABASES = { DEBUG = True -TEST_CASE_DIR = "/var/test_case/" +# 同理 这是 web 服务器的上传路径 +TEST_CASE_DIR = "/Users/virusdefender/Desktop/test_case/" diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js index 5b10211d..fd544cf7 100644 --- a/static/src/js/app/oj/problem/problem.js +++ b/static/src/js/app/oj/problem/problem.js @@ -1,4 +1,4 @@ -require(["jquery", "code_mirror"], function ($, code_mirror) { +require(["jquery", "code_mirror", "csrf"], function ($, code_mirror, csrfHeader) { var code_editor = code_mirror($("#code-editor")[0], "text/x-csrc"); var language = "1"; @@ -21,7 +21,11 @@ require(["jquery", "code_mirror"], function ($, code_mirror) { $("#submit-code-button").click(function () { show_loading(); $.ajax({ - + beforeSend: csrfHeader, + url: "/api/submission/", + method: "post", + data: JSON.stringify({problem_id: 2, language: language, code: code_editor.getValue()}), + contentType: "application/json" }); setTimeout( function () { diff --git a/submission/views.py b/submission/views.py index 993de50f..7d2ef237 100644 --- a/submission/views.py +++ b/submission/views.py @@ -32,6 +32,7 @@ class SubmissionnAPIView(APIView): serializer = CreateSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data + # data["language"] = int(data["language"]) data["user_id"] = request.user.id data["result"] = result["waiting"] try: From f6c3ceee40917129cadbedc1cb9d13a5a943e0d2 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 22:59:05 +0800 Subject: [PATCH 09/24] =?UTF-8?q?=E5=88=A0=E9=99=A4=20ManyToMany=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=97=A0=E6=95=88=E7=9A=84=20null=3DTrue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem/migrations/0004_auto_20150812_2254.py | 19 +++++++++++++++++++ problem/models.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 problem/migrations/0004_auto_20150812_2254.py diff --git a/problem/migrations/0004_auto_20150812_2254.py b/problem/migrations/0004_auto_20150812_2254.py new file mode 100644 index 00000000..75f85d4a --- /dev/null +++ b/problem/migrations/0004_auto_20150812_2254.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('problem', '0003_auto_20150810_2233'), + ] + + operations = [ + migrations.AlterField( + model_name='problem', + name='tags', + field=models.ManyToManyField(to='problem.ProblemTag'), + ), + ] diff --git a/problem/models.py b/problem/models.py index b9a31813..aaa5ce0e 100644 --- a/problem/models.py +++ b/problem/models.py @@ -49,4 +49,4 @@ class Problem(AbstractProblem): # 难度 0 - n difficulty = models.IntegerField() # 标签 - tags = models.ManyToManyField(ProblemTag, null=True) + tags = models.ManyToManyField(ProblemTag) From 41eec53430d5bb85f3f1a40ef949534c04aca329 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 22:59:27 +0800 Subject: [PATCH 10/24] =?UTF-8?q?=E5=90=88=E5=B9=B6=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/views.py | 59 ++++++++++++++--------- static/src/js/app/admin/user/user_list.js | 2 +- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/account/views.py b/account/views.py index fe144644..f0539039 100644 --- a/account/views.py +++ b/account/views.py @@ -7,9 +7,11 @@ from rest_framework.views import APIView from utils.shortcuts import serializer_invalid_response, error_response, success_response, paginate +from .decorators import login_required from .models import User -from .serializers import UserLoginSerializer, UsernameCheckSerializer, UserRegisterSerializer, \ - UserChangePasswordSerializer, EmailCheckSerializer, UserSerializer, EditUserSerializer +from .serializers import (UserLoginSerializer, UsernameCheckSerializer, + UserRegisterSerializer, UserChangePasswordSerializer, + EmailCheckSerializer, UserSerializer, EditUserSerializer) class UserLoginAPIView(APIView): @@ -118,28 +120,6 @@ class EmailCheckAPIView(APIView): return serializer_invalid_response(serializer) -class UserAPIView(APIView): - def get(self, request): - """ - 用户分页json api接口 - --- - response_serializer: UserSerializer - """ - user = User.objects.all().order_by("-create_time") - admin_type = request.GET.get("admin_type", None) - if admin_type: - try: - user = user.filter(admin_type__gte=int(admin_type)) - except ValueError: - return error_response(u"参数错误") - keyword = request.GET.get("keyword", None) - if keyword: - user = user.filter(Q(username__contains=keyword) | - Q(real_name__contains=keyword) | - Q(email__contains=keyword)) - return paginate(request, user, UserSerializer) - - class UserAdminAPIView(APIView): def put(self, request): """ @@ -165,3 +145,34 @@ class UserAdminAPIView(APIView): return success_response(UserSerializer(user).data) else: return serializer_invalid_response(serializer) + + def get(self, request): + """ + 用户分页json api接口 + --- + response_serializer: UserSerializer + """ + user = User.objects.all().order_by("-create_time") + admin_type = request.GET.get("admin_type", None) + if admin_type: + try: + user = user.filter(admin_type__gte=int(admin_type)) + except ValueError: + return error_response(u"参数错误") + keyword = request.GET.get("keyword", None) + if keyword: + user = user.filter(Q(username__contains=keyword) | + Q(real_name__contains=keyword) | + Q(email__contains=keyword)) + return paginate(request, user, UserSerializer) + + +class UserInfoAPIView(APIView): + @login_required + def get(self, request): + """ + 返回这个用户的个人信息 + --- + response_serializer: UserSerializer + """ + return success_response(UserSerializer(request.user).data) diff --git a/static/src/js/app/admin/user/user_list.js b/static/src/js/app/admin/user/user_list.js index 910c24a6..1e5f254a 100644 --- a/static/src/js/app/admin/user/user_list.js +++ b/static/src/js/app/admin/user/user_list.js @@ -63,7 +63,7 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava getPageData(1); //用户列表初始化 //Ajax get数据 function getPageData(page) { - var url = "/api/admin/users/?paging=true&page=" + page + "&page_size=10"; + var url = "/api/admin/user/?paging=true&page=" + page + "&page_size=10"; if (vm.showAdminOnly == true) url += "&admin_type=1"; if (vm.key_word != "") From 10ad8f85b5a9a2b1febaa570b5025a0d62bca29d Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 22:59:36 +0800 Subject: [PATCH 11/24] =?UTF-8?q?=E6=95=B4=E7=90=86=20url=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/oj/urls.py b/oj/urls.py index 5c7171f4..3165c1a0 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -5,26 +5,28 @@ from django.views.generic import TemplateView from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, EmailCheckAPIView, - UserAPIView, UserAdminAPIView) + UserAdminAPIView, UserInfoAPIView) from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView -from group.views import GroupAdminAPIView, GroupMemberAdminAPIView, JoinGroupAPIView, JoinGroupRequestAdminAPIView +from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView, + JoinGroupAPIView, JoinGroupRequestAdminAPIView) from admin.views import AdminTemplateView -from problem.views import ProblemAdminAPIView -from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView +from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView, ProblemAdminAPIView from submission.views import SubmissionnAPIView - urlpatterns = [ url(r'^install/$', "install.views.install"), url("^$", TemplateView.as_view(template_name="oj/index.html"), name="index_page"), url(r'^docs/', include('rest_framework_swagger.urls')), url(r'^admin/$', TemplateView.as_view(template_name="admin/admin.html"), name="admin_spa_page"), url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"), - url(r'^register/$', TemplateView.as_view(template_name="oj/account/register.html"), name="user_register_page"), - url(r'^change_password/$', TemplateView.as_view(template_name="oj/account/change_password.html"), name="user_change_password_page"), + url(r'^register/$', TemplateView.as_view(template_name="oj/account/register.html"), + name="user_register_page"), + url(r'^change_password/$', TemplateView.as_view(template_name="oj/account/change_password.html"), + name="user_change_password_page"), + url(r'^api/user/$', UserInfoAPIView.as_view(), name="user_info_api"), url(r'^api/login/$', UserLoginAPIView.as_view(), name="user_login_api"), url(r'^api/register/$', UserRegisterAPIView.as_view(), name="user_register_api"), url(r'^api/change_password/$', UserChangePasswordAPIView.as_view(), name="user_change_password_api"), @@ -33,24 +35,27 @@ urlpatterns = [ url(r'^api/admin/announcement/$', AnnouncementAdminAPIView.as_view(), name="announcement_admin_api"), url(r'^api/admin/user/$', UserAdminAPIView.as_view(), name="user_admin_api"), url(r'^problem/(?P\d+)/$', "problem.views.problem_page", name="problem_page"), - url(r'^announcement/(?P\d+)/$', "announcement.views.announcement_page", name="announcement_page"), - + url(r'^announcement/(?P\d+)/$', "announcement.views.announcement_page", + name="announcement_page"), url(r'^api/announcements/$', AnnouncementAPIView.as_view(), name="announcement_list_api"), - url(r'^api/admin/users/$', UserAPIView.as_view(), name="user_list_api"), - - url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"), - url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"), - url(r'^admin/template/(?P\w+)/(?P\w+).html', AdminTemplateView.as_view(), name="admin_template"), + url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), + name="add_contest_page"), + url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), + name="problem_list_page"), + url(r'^admin/template/(?P\w+)/(?P\w+).html', AdminTemplateView.as_view(), + name="admin_template"), url(r'^api/admin/group/$', GroupAdminAPIView.as_view(), name="group_admin_api"), url(r'^api/admin/group_member/$', GroupMemberAdminAPIView.as_view(), name="group_member_admin_api"), url(r'^api/admin/group_join/$', JoinGroupAPIView.as_view(), name="group_join_admin_api"), url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"), url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"), url(r'^api/admin/tag/$', ProblemTagAdminAPIView.as_view(), name="problem_tag_admin_api"), - url(r'^problem/(?P\d+)/my_solutions/', "problem.views.problem_my_solutions_list_page", name="problem_my_solutions_page"), + url(r'^problem/(?P\d+)/my_solutions/', "problem.views.problem_my_solutions_list_page", + name="problem_my_solutions_page"), url(r'^my_solution/(?P\d+)/$', "problem.views.my_solution", name="my_solution_page"), - url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), name="join_group_request_admin_api"), + url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), + name="join_group_request_admin_api"), url(r'^api/submission/$', SubmissionnAPIView.as_view(), name="submission_api"), ] From 309401f7550afe44d50a26f1dcdc0e474290f32b Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 22:59:50 +0800 Subject: [PATCH 12/24] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B0=8F=E7=BB=84?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group/views.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/group/views.py b/group/views.py index 79ccbd49..a9ec8d24 100644 --- a/group/views.py +++ b/group/views.py @@ -94,6 +94,7 @@ class GroupAdminAPIView(APIView, GroupAPIViewBase): response_serializer: GroupSerializer """ group_id = request.GET.get("group_id", None) + # 根据 id 查询小组信息 if group_id: try: group = self.get_group(request, group_id) @@ -102,8 +103,15 @@ class GroupAdminAPIView(APIView, GroupAPIViewBase): return error_response(u"小组不存在") else: groups = self.get_groups(request) + # 搜索小组 if request.GET.get("keyword", None): groups = groups.filter(name__contains=request.GET["keyword"]) + # 只返回我创建的小组 适用于超级管理员 + if request.GET.get("my_group", None): + groups = groups.filter(admin=request.user) + # 只返回指定用户的小组 适用于管理员 + elif request.GET.get("admin_id", None): + groups = groups.filter(admin__id=request.GET["admin_id"]) return paginate(request, groups, GroupSerializer) From 5273e9a48d04e0d36c2a0eb328fbd1104c33cdda Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Wed, 12 Aug 2015 23:18:22 +0800 Subject: [PATCH 13/24] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20decorator=20?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=20swagger=20=E6=97=A0=E6=B3=95=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E6=B3=A8=E9=87=8A=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/decorators.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/account/decorators.py b/account/decorators.py index 01cdd68f..ff1b5b05 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -1,4 +1,5 @@ # coding=utf-8 +from functools import wraps from django.http import HttpResponse from django.shortcuts import render @@ -7,6 +8,7 @@ from .models import User def login_required(func): + @wraps(func) def check(*args, **kwargs): # 在class based views 里面,args 有两个元素,一个是self, 第二个才是request, # 在function based views 里面,args 只有request 一个参数 @@ -21,6 +23,7 @@ def login_required(func): def admin_required(func): + @wraps(func) def check(*args, **kwargs): request = args[-1] if request.user.is_authenticated() and request.user.admin_type: From da03f902c5d96207602dfb1e47d550c10de0f338 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 18:15:00 +0800 Subject: [PATCH 14/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=88=A4=E9=A2=98?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E9=83=A8=E5=88=86=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judger/client.py | 2 +- judger/run.py | 37 ++++++++++++++++++++++++++++++------- judger_controller/tasks.py | 4 ++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/judger/client.py b/judger/client.py index 52f65862..fc7d0b90 100644 --- a/judger/client.py +++ b/judger/client.py @@ -58,7 +58,7 @@ class JudgeClient(object): # todo 系统调用白名单 chroot等参数 command = "lrun" + \ " --max-cpu-time " + str(self._max_cpu_time / 1000.0) + \ - " --max-real-time " + str(self._max_real_time / 1000.0) + \ + " --max-real-time " + str(self._max_real_time / 1000.0 * 2) + \ " --max-memory " + str(self._max_memory * 1000 * 1000) + \ " --network false" + \ " --uid " + str(lrun_uid) + \ diff --git a/judger/run.py b/judger/run.py index 1e83bb84..bdf037b5 100644 --- a/judger/run.py +++ b/judger/run.py @@ -15,7 +15,7 @@ from settings import judger_workspace, mongodb_config # 参数有 -solution_id -time_limit -memory_limit -test_case_id # 获取到的值是['xxx.py', '-solution_id', '1111', '-time_limit', '1000', '-memory_limit', '100', '-test_case_id', 'aaaa'] args = sys.argv -solution_id = args[2] +submission_id = args[2] time_limit = args[4] memory_limit = args[6] test_case_id = args[8] @@ -23,33 +23,56 @@ test_case_id = args[8] connection = pymongo.MongoClient(host=mongodb_config["host"], port=mongodb_config["port"]) collection = connection["oj"]["oj_submission"] -submission = collection.find_one({"_id": ObjectId(solution_id)}) +submission = collection.find_one({"_id": ObjectId(submission_id)}) if not submission: exit() +connection.close() # 将代码写入文件 language = languages[submission["language"]] src_path = judger_workspace + "run/" + language["src_name"] f = open(src_path, "w") -f.write(submission["code"]) +f.write(submission["code"].encode("utf8")) f.close() # 编译 try: exe_path = compile_(language, src_path, judger_workspace + "run/") except Exception as e: - print {"result": result["compile_error"]} + print e + connection = pymongo.MongoClient(host=mongodb_config["host"], port=mongodb_config["port"]) + collection = connection["oj"]["oj_submission"] + data = {"result": result["compile_error"], "info": str(e)} + collection.find_one_and_update({"_id": ObjectId(submission_id)}, {"$set": data}) + connection.close() exit() + +print "Compile successfully" +# 运行 try: client = JudgeClient(language_code=submission["language"], exe_path=exe_path, max_cpu_time=int(time_limit), max_real_time=int(time_limit) * 2, max_memory=int(memory_limit), - test_case_dir= judger_workspace + "test_case/" + test_case_id + "/") - print client.run() + test_case_dir=judger_workspace + "test_case/" + test_case_id + "/") + judge_result = {"result": result["accepted"], "info": client.run()} + + for item in judge_result["info"]: + if item["result"]: + judge_result["result"] = item["result"] + break + except Exception as e: print e - print {"result": result["system_error"]} + judge_result = {"result": result["system_error"], "info": str(e)} + +print "Run successfully" +print judge_result +connection = pymongo.MongoClient(host=mongodb_config["host"], port=mongodb_config["port"]) +collection = connection["oj"]["oj_submission"] +collection.find_one_and_update({"_id": ObjectId(submission_id)}, {"$set": judge_result}) +connection.close() + diff --git a/judger_controller/tasks.py b/judger_controller/tasks.py index 054452c8..ebc7b045 100644 --- a/judger_controller/tasks.py +++ b/judger_controller/tasks.py @@ -14,7 +14,7 @@ def judge(solution_id, time_limit, memory_limit, test_case_id): "python judger/run.py " "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % (solution_id, str(time_limit), str(memory_limit), test_case_id), - # 如果设置的最长运行时间小于1000毫秒,那么/1000就是0,处理一下这个情况,设置为两秒 - timeout=(time_limit / 1000 * 3) or 2, shell=True) + # 设置最长运行时间是3倍的 cpu 时间 + timeout=(time_limit / 1000.0 * 3), shell=True) except subprocess.TimeoutExpired: print "docker timeout" From 5a967789a60cca70b096c1757f9a6d9ce58fa737 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 18:15:54 +0800 Subject: [PATCH 15/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81=E7=9A=84=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/oj/problem/problem.js | 120 +++++++++++++++++++++--- submission/views.py | 6 +- template/oj/problem/problem.html | 53 ++++------- 3 files changed, 128 insertions(+), 51 deletions(-) diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js index fd544cf7..6826e7b2 100644 --- a/static/src/js/app/oj/problem/problem.js +++ b/static/src/js/app/oj/problem/problem.js @@ -1,13 +1,19 @@ -require(["jquery", "code_mirror", "csrf"], function ($, code_mirror, csrfHeader) { +require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, csrfHeader, bs_alert) { var code_editor = code_mirror($("#code-editor")[0], "text/x-csrc"); - var language = "1"; + var language = $("input[name='language'][checked]").val(); + var submission_id; - $("#language-selector").change(function () { - language = $("#language-selector").val(); - var language_types = {c: "text/x-csrc", cpp: "text/x-c++src", java: "text/x-java"}; + $("input[name='language']").change(function () { + language = this.value; + var language_types = {"1": "text/x-csrc", "2": "text/x-c++src", "3": "text/x-java"}; code_editor.setOption("mode", language_types[language]); }); + $("#show-more-btn").click(function () { + $(".hide").attr("class", "problem-section"); + $("#show-more-btn").hide(); + }); + function show_loading() { $("#submit-code-button").attr("disabled", "disabled"); $("#loading-gif").show(); @@ -18,24 +24,108 @@ require(["jquery", "code_mirror", "csrf"], function ($, code_mirror, csrfHeader) $("#loading-gif").hide(); } + + function get_result_html(result) { + console.log(result); + // 0 结果正确 1 运行错误 2 超时 3 超内存 4 编译错误 + // 5 格式错误 6 结果错误 7 系统错误 8 等待判题 + var results = { + 0: {"alert_class": "success", message: "Accepted"}, + 1: {"alert_class": "danger", message: "Runtime Error"}, + 2: {"alert_class": "warning", message: "Time Limit Exceeded"}, + 3: {"alert_class": "warning", message: "Memory Limit Exceeded"}, + 4: {"alert_class": "danger", message: "Compile Error"}, + 5: {"alert_class": "warning", message: "Format Error"}, + 6: {"alert_class": "danger", message: "Wrong Answer"}, + 7: {"alert_class": "danger", message: "System Error"}, + 8: {"alert_class": "info", message: "Waiting"} + }; + + var html = ''; + console.log(html); + return html; + } + + function get_result() { + $.ajax({ + url: "/api/submission/?submission_id=" + submission_id, + method: "get", + dataType: "json", + success: function (data) { + if (!data.code) { + // 8是还没有完成判题 + if (data.data.result == 8) { + // 1秒之后重新去获取 + setTimeout(get_result, 1000); + } + else { + hide_loading(); + $("#result").html(get_result_html(data.data.result)); + } + } + else { + bs_alert(data.data); + hide_loading(); + } + } + }) + } + $("#submit-code-button").click(function () { + var problem_id = window.location.pathname.split("/")[2]; + var code = code_editor.getValue(); + show_loading(); + + if(!code){ + bs_alert("请填写代码!"); + hide_loading(); + return false; + } + + $("#result").html(""); + $.ajax({ beforeSend: csrfHeader, url: "/api/submission/", method: "post", - data: JSON.stringify({problem_id: 2, language: language, code: code_editor.getValue()}), - contentType: "application/json" + data: JSON.stringify({ + problem_id: window.location.pathname.split("/")[2], + language: language, + code: code_editor.getValue() + }), + contentType: "application/json", + success: function (data) { + if (!data.code) { + submission_id = data.data.submission_id; + // 获取到id 之后2秒去查询一下判题结果 + setTimeout(get_result, 2000); + } + else { + bs_alert(data.data); + hide_loading(); + } + } }); - setTimeout( - function () { - $("#a").animate({opacity: '1'}) - }, 3); + }); - $("#show-more-btn").click(function(){ - $(".hide").attr("class", "problem-section"); - $("#show-more-btn").hide(); + $.ajax({ + url : "/api/user/", + method: "get", + dataType: "json", + success: function(data){ + if(data.code){ + $("#submit-code-button").attr("disabled", "disabled"); + $("#result").html(''); + } + } }) - }); diff --git a/submission/views.py b/submission/views.py index 7d2ef237..83cfb886 100644 --- a/submission/views.py +++ b/submission/views.py @@ -22,7 +22,7 @@ class SubmissionnAPIView(APIView): connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) return connection["oj"]["oj_submission"] - # @login_required + @login_required def post(self, request): """ 提交代码 @@ -48,12 +48,12 @@ class SubmissionnAPIView(APIView): else: return serializer_invalid_response(serializer) - # @login_required + @login_required def get(self, request): submission_id = request.GET.get("submission_id", None) if not submission_id: return error_response(u"参数错误") - submission = self._create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": result.user.id}) + submission = self._create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": request.user.id}) if submission: return success_response({"result": submission["result"]}) else: diff --git a/template/oj/problem/problem.html b/template/oj/problem/problem.html index b3f1623e..f3a30211 100644 --- a/template/oj/problem/problem.html +++ b/template/oj/problem/problem.html @@ -9,7 +9,8 @@

{{ problem.title }}

-

发布时间: {{ problem.create_time }} CPU: {{ problem.time_limit }}ms 内存: {{ problem.memory_limit }}M

+

发布时间: {{ problem.create_time }} CPU: {{ problem.time_limit }}ms + 内存: {{ problem.memory_limit }}M

@@ -28,35 +29,35 @@

第一行包括两个数n,k

{% for item in samples %} -
- +
+
 {{ item.input }}
-
-
+
+
- +
 {{ item.output }}
-
+
{% endfor %}
{% if problem.hind %} -
- +
+ -

{{ problem.hint|safe }}

-
- {% endif %} +

{{ problem.hint|safe }}

+
+ {% endif %}

{% for tag in problem.tags.all %} - {{ tag.name }} + {{ tag.name }} {% endfor %}

@@ -66,13 +67,13 @@
@@ -89,24 +90,10 @@ -
-
- - - - + +
+
{% endblock %} From 0aeeab3c8c170345e0d0cf8f6af5543e99da8fc7 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 20:28:23 +0800 Subject: [PATCH 16/24] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=20cpu=20=E6=97=B6=E9=97=B4=E7=9A=84=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judger/run.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/judger/run.py b/judger/run.py index bdf037b5..d14fc617 100644 --- a/judger/run.py +++ b/judger/run.py @@ -62,6 +62,9 @@ try: if item["result"]: judge_result["result"] = item["result"] break + else: + l = sorted(judge_result["info"], key=lambda k: k["cpu_time"]) + judge_result["accepted_answer_info"] = {"time": l[-1]["cpu_time"]} except Exception as e: print e From 2731bc92490bb0e68e7b867758851072185f88c8 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 20:28:41 +0800 Subject: [PATCH 17/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20docker=20=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E9=97=B4=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judger_controller/tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/judger_controller/tasks.py b/judger_controller/tasks.py index ebc7b045..3f4e2559 100644 --- a/judger_controller/tasks.py +++ b/judger_controller/tasks.py @@ -14,7 +14,7 @@ def judge(solution_id, time_limit, memory_limit, test_case_id): "python judger/run.py " "--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % (solution_id, str(time_limit), str(memory_limit), test_case_id), - # 设置最长运行时间是3倍的 cpu 时间 - timeout=(time_limit / 1000.0 * 3), shell=True) + # 设置最长运行时间是5倍的 cpu 时间 + timeout=(time_limit / 1000.0 * 5), shell=True) except subprocess.TimeoutExpired: print "docker timeout" From 58f90146889491c15459494ef8db25ef13ccb0a3 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 20:29:11 +0800 Subject: [PATCH 18/24] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A2=98=E7=9B=AE?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 6 +++--- problem/migrations/0006_merge.py | 15 ++++++++++++++ problem/views.py | 11 +---------- static/src/js/app/oj/problem/problem.js | 21 ++++++++++---------- submission/views.py | 26 +++++++++++++++++++++---- template/oj/problem/problem.html | 6 +++--- 6 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 problem/migrations/0006_merge.py diff --git a/oj/urls.py b/oj/urls.py index 3165c1a0..67755dfd 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -50,9 +50,9 @@ urlpatterns = [ url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"), url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"), url(r'^api/admin/tag/$', ProblemTagAdminAPIView.as_view(), name="problem_tag_admin_api"), - url(r'^problem/(?P\d+)/my_solutions/', "problem.views.problem_my_solutions_list_page", - name="problem_my_solutions_page"), - url(r'^my_solution/(?P\d+)/$', "problem.views.my_solution", name="my_solution_page"), + url(r'^problem/(?P\d+)/my_solutions/', "submission.views.problem_my_submissions_list_page", + name="problem_my_submissions_page"), + url(r'^my_solution/(?P\d+)/$', "submission.views.my_submission", name="my_submission_page"), url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), name="join_group_request_admin_api"), diff --git a/problem/migrations/0006_merge.py b/problem/migrations/0006_merge.py new file mode 100644 index 00000000..f24e12dd --- /dev/null +++ b/problem/migrations/0006_merge.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('problem', '0005_auto_20150813_1807'), + ('problem', '0004_auto_20150812_2254'), + ] + + operations = [ + ] diff --git a/problem/views.py b/problem/views.py index fe201274..a65aa4c3 100644 --- a/problem/views.py +++ b/problem/views.py @@ -47,15 +47,6 @@ def problem_page(request, problem_id): return render(request, "oj/problem/problem.html", {"problem": problem, "samples": json.loads(problem.samples)}) -def problem_my_solutions_list_page(request, problem_id): - return render(request, "oj/problem/my_solutions_list.html") - - -def my_solution(request, solution_id): - return render(request, "oj/problem/my_solution.html") - - - class ProblemAdminAPIView(APIView): def post(self, request): """ @@ -197,7 +188,7 @@ class TestCaseUploadAPIView(APIView): os.mkdir(test_case_dir) for name in l: f = open(test_case_dir + name, "wb") - f.write(test_case_file.read(name)) + f.write(test_case_file.read(name).replace("\r\n", "\n")) f.close() l.sort() diff --git a/static/src/js/app/oj/problem/problem.js b/static/src/js/app/oj/problem/problem.js index 6826e7b2..141405a1 100644 --- a/static/src/js/app/oj/problem/problem.js +++ b/static/src/js/app/oj/problem/problem.js @@ -25,8 +25,7 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, } - function get_result_html(result) { - console.log(result); + function get_result_html(data) { // 0 结果正确 1 运行错误 2 超时 3 超内存 4 编译错误 // 5 格式错误 6 结果错误 7 系统错误 8 等待判题 var results = { @@ -42,14 +41,16 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, }; var html = ''; - console.log(html); + results[data.result].message + + '!   '; + if (!data.result) { + html += "CPU time: " + data.accepted_answer_info.time + "ms   "; + } + html += ('查看详情 '); + return html; } @@ -67,7 +68,7 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, } else { hide_loading(); - $("#result").html(get_result_html(data.data.result)); + $("#result").html(get_result_html(data.data)); } } else { @@ -84,7 +85,7 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, show_loading(); - if(!code){ + if(!code.trim()){ bs_alert("请填写代码!"); hide_loading(); return false; diff --git a/submission/views.py b/submission/views.py index 83cfb886..3d115a01 100644 --- a/submission/views.py +++ b/submission/views.py @@ -1,4 +1,5 @@ # coding=utf-8 +import datetime import pymongo from bson.objectid import ObjectId @@ -16,12 +17,13 @@ from utils.shortcuts import serializer_invalid_response, error_response, success from .serializers import CreateSubmissionSerializer -class SubmissionnAPIView(APIView): - def _create_mondodb_connection(self): +def _create_mondodb_connection(): mongodb_setting = settings.DATABASES["mongodb"] connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) return connection["oj"]["oj_submission"] + +class SubmissionnAPIView(APIView): @login_required def post(self, request): """ @@ -35,6 +37,7 @@ class SubmissionnAPIView(APIView): # data["language"] = int(data["language"]) data["user_id"] = request.user.id data["result"] = result["waiting"] + data["create_time"] = datetime.datetime.now() try: problem = Problem.objects.get(id=data["problem_id"]) except Problem.DoesNotExist: @@ -53,8 +56,23 @@ class SubmissionnAPIView(APIView): submission_id = request.GET.get("submission_id", None) if not submission_id: return error_response(u"参数错误") - submission = self._create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": request.user.id}) + submission = _create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": request.user.id}) if submission: - return success_response({"result": submission["result"]}) + response_data = {"result": submission["result"]} + if submission["result"] == 0: + response_data["accepted_answer_info"] = submission["accepted_answer_info"] + return success_response(response_data) else: return error_response(u"提交不存在") + + +def problem_my_submissions_list_page(request, problem_id): + collection = _create_mondodb_connection() + submissions = collection.find({"problem_id": int(problem_id), "user_id": request.user.id}, + projection=["result", "accepted_answer_info", "create_time"], + sort=[["create_time", -pymongo.ASCENDING]]) + return render(request, "oj/problem/my_solutions_list.html", {"submissions": submissions}) + + +def my_submission(request, solution_id): + return render(request, "oj/problem/my_solution.html") \ No newline at end of file diff --git a/template/oj/problem/problem.html b/template/oj/problem/problem.html index f3a30211..bcb6160c 100644 --- a/template/oj/problem/problem.html +++ b/template/oj/problem/problem.html @@ -21,12 +21,12 @@
-

第一行包括两个数n,k

+

{{ problem.input_description }}

-

第一行包括两个数n,k

+

{{ problem.output_description }}k

{% for item in samples %}
@@ -45,7 +45,7 @@
- {% if problem.hind %} + {% if problem.hint %}
From 94282f3ed859fc0ffc3fde830fe3c22d203ae0aa Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 13 Aug 2015 21:02:17 +0800 Subject: [PATCH 19/24] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=88=91=E7=9A=84?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/settings.py | 1 + oj/urls.py | 6 +- submission/templatetags/__init__.py | 1 + submission/templatetags/submission.py | 28 +++++++++ submission/views.py | 4 +- template/oj/problem/my_solutions_list.html | 53 ---------------- template/oj/problem/my_submissions_list.html | 64 ++++++++++++++++++++ template/oj/problem/problem.html | 4 +- 8 files changed, 101 insertions(+), 60 deletions(-) create mode 100644 submission/templatetags/__init__.py create mode 100644 submission/templatetags/submission.py delete mode 100644 template/oj/problem/my_solutions_list.html create mode 100644 template/oj/problem/my_submissions_list.html diff --git a/oj/settings.py b/oj/settings.py index 01bbadca..8d012d03 100644 --- a/oj/settings.py +++ b/oj/settings.py @@ -51,6 +51,7 @@ INSTALLED_APPS = ( 'group', 'problem', 'admin', + 'submission', 'rest_framework', 'rest_framework_swagger', diff --git a/oj/urls.py b/oj/urls.py index 67755dfd..78791d5a 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -42,7 +42,7 @@ urlpatterns = [ name="add_contest_page"), url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"), - url(r'^admin/template/(?P\w+)/(?P\w+).html', AdminTemplateView.as_view(), + url(r'^admin/template/(?P\w+)/(?P\w+).html$', AdminTemplateView.as_view(), name="admin_template"), url(r'^api/admin/group/$', GroupAdminAPIView.as_view(), name="group_admin_api"), url(r'^api/admin/group_member/$', GroupMemberAdminAPIView.as_view(), name="group_member_admin_api"), @@ -50,9 +50,9 @@ urlpatterns = [ url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"), url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"), url(r'^api/admin/tag/$', ProblemTagAdminAPIView.as_view(), name="problem_tag_admin_api"), - url(r'^problem/(?P\d+)/my_solutions/', "submission.views.problem_my_submissions_list_page", + url(r'^problem/(?P\d+)/my_solutions/$', "submission.views.problem_my_submissions_list_page", name="problem_my_submissions_page"), - url(r'^my_solution/(?P\d+)/$', "submission.views.my_submission", name="my_submission_page"), + url(r'^my_solution/(?P\w+)/$', "submission.views.my_submission", name="my_submission_page"), url(r'^api/admin/join_group_request/$', JoinGroupRequestAdminAPIView.as_view(), name="join_group_request_admin_api"), diff --git a/submission/templatetags/__init__.py b/submission/templatetags/__init__.py new file mode 100644 index 00000000..9bad5790 --- /dev/null +++ b/submission/templatetags/__init__.py @@ -0,0 +1 @@ +# coding=utf-8 diff --git a/submission/templatetags/submission.py b/submission/templatetags/submission.py new file mode 100644 index 00000000..51806f04 --- /dev/null +++ b/submission/templatetags/submission.py @@ -0,0 +1,28 @@ +# coding=utf-8 + + +def translate_result(value): + print value + results = { + 0: "Accepted", + 1: "Runtime Error", + 2: "Time Limit Exceeded", + 3: "Memory Limit Exceeded", + 4: "Compile Error", + 5: "Format Error", + 6: "Wrong Answer", + 7: "System Error", + 8: "Waiting" + } + return results[value] + + +def translate_id(submission_item): + print submission_item + return submission_item["_id"] + +from django import template + +register = template.Library() +register.filter("translate_result", translate_result) +register.filter("translate_id", translate_id) \ No newline at end of file diff --git a/submission/views.py b/submission/views.py index 3d115a01..72a1f4a8 100644 --- a/submission/views.py +++ b/submission/views.py @@ -69,9 +69,9 @@ class SubmissionnAPIView(APIView): def problem_my_submissions_list_page(request, problem_id): collection = _create_mondodb_connection() submissions = collection.find({"problem_id": int(problem_id), "user_id": request.user.id}, - projection=["result", "accepted_answer_info", "create_time"], + projection=["result", "accepted_answer_info", "create_time", "language"], sort=[["create_time", -pymongo.ASCENDING]]) - return render(request, "oj/problem/my_solutions_list.html", {"submissions": submissions}) + return render(request, "oj/problem/my_submissions_list.html", {"submissions": submissions}) def my_submission(request, solution_id): diff --git a/template/oj/problem/my_solutions_list.html b/template/oj/problem/my_solutions_list.html deleted file mode 100644 index 613410ab..00000000 --- a/template/oj/problem/my_solutions_list.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends 'oj_base.html' %} - -{% block body %} - -
- -

Battle Over Cities - Hard Version

-

cpu: 1000ms 内存: 256M

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#提交时间结果运行时间运行内存语言
11Error Format333
2WrongWrong Answer@fat33
3LarryAccepted@twitter33
-
-{% endblock %} \ No newline at end of file diff --git a/template/oj/problem/my_submissions_list.html b/template/oj/problem/my_submissions_list.html new file mode 100644 index 00000000..cc9e1382 --- /dev/null +++ b/template/oj/problem/my_submissions_list.html @@ -0,0 +1,64 @@ +{% extends 'oj_base.html' %} + +{% block body %} + + {% load submission %} +
+ +

Battle Over Cities - Hard Version

+ +

cpu: 1000ms 内存: 256M

+ + + + + + + + + + + + {% for item in submissions %} + {% ifequal item.result 0 %} + + {% else %} + {% ifequal item.result 8 %} + + {% else %} + + {% endifequal %} + + {% endifequal %} + + + + + + + {% endfor %} + + +
#提交时间结果运行时间语言
{{ forloop.counter }}{{ item.create_time }}{{ item.result|translate_result }} + {% if item.accepted_answer_info.time %} + {{ item.accepted_answer_info.time }}ms + {% else %} + -- + {% endif %} + + {% ifequal item.language 1 %} + C + {% else %} + {% ifequal item.language 2 %} + C++ + {% else %} + Java + {% endifequal %} + {% endifequal %} +
+
+{% endblock %} \ No newline at end of file diff --git a/template/oj/problem/problem.html b/template/oj/problem/problem.html index bcb6160c..1764db22 100644 --- a/template/oj/problem/problem.html +++ b/template/oj/problem/problem.html @@ -67,10 +67,10 @@
'); + html += ('查看详情
'); return html; } diff --git a/static/src/js/utils/bs_alert.js b/static/src/js/utils/bs_alert.js index b35f06de..547b9197 100644 --- a/static/src/js/utils/bs_alert.js +++ b/static/src/js/utils/bs_alert.js @@ -1,7 +1,17 @@ define("bs_alert", ["jquery", "bootstrap"], function($){ function bs_alert(content){ + if(!$("#alert-modal").length) { + var html = ''; + $("body").append(html); + } $("#modal-text").html(content); - $("#modal").modal(); + $("#alert-modal").modal(); } return bs_alert; }); \ No newline at end of file diff --git a/submission/views.py b/submission/views.py index 72a1f4a8..0a923e07 100644 --- a/submission/views.py +++ b/submission/views.py @@ -13,12 +13,12 @@ from judger.result import result from judger_controller.tasks import judge from account.decorators import login_required from problem.models import Problem -from utils.shortcuts import serializer_invalid_response, error_response, success_response +from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page from .serializers import CreateSubmissionSerializer def _create_mondodb_connection(): - mongodb_setting = settings.DATABASES["mongodb"] + mongodb_setting = settings["mongodb_setting"] connection = pymongo.MongoClient(host=mongodb_setting["HOST"], port=mongodb_setting["PORT"]) return connection["oj"]["oj_submission"] @@ -66,13 +66,31 @@ class SubmissionnAPIView(APIView): return error_response(u"提交不存在") +@login_required def problem_my_submissions_list_page(request, problem_id): collection = _create_mondodb_connection() submissions = collection.find({"problem_id": int(problem_id), "user_id": request.user.id}, projection=["result", "accepted_answer_info", "create_time", "language"], sort=[["create_time", -pymongo.ASCENDING]]) - return render(request, "oj/problem/my_submissions_list.html", {"submissions": submissions}) + try: + problem = Problem.objects.get(id=problem_id, visible=True) + except Problem.DoesNotExist: + return error_page(request, u"问题不存在") + return render(request, "oj/problem/my_submissions_list.html", + {"submissions": submissions, "problem": problem}) -def my_submission(request, solution_id): - return render(request, "oj/problem/my_solution.html") \ No newline at end of file +@login_required +def my_submission(request, submission_id): + collection = _create_mondodb_connection() + submission = collection.find_one({"user_id": request.user.id, "_id": ObjectId(submission_id)}, + projection=["result", "accepted_answer_info", "create_time", + "language", "code", "problem_id", "info"]) + if not submission: + return error_page(request, u"提交不存在") + try: + problem = Problem.objects.get(id=submission["problem_id"], visible=True) + except Problem.DoesNotExist: + return error_page(request, u"提交不存在") + + return render(request, "oj/problem/my_submission.html", {"submission": submission, "problem": problem}) \ No newline at end of file diff --git a/template/admin/admin.html b/template/admin/admin.html index 69aba419..d5a0e18b 100644 --- a/template/admin/admin.html +++ b/template/admin/admin.html @@ -124,23 +124,7 @@ - + diff --git a/template/admin_base.html b/template/admin_base.html deleted file mode 100644 index 86cf7e28..00000000 --- a/template/admin_base.html +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - 在线评测系统 - 后台管理 - - - {% block css_block %}{% endblock %} - - - - - - - - - - - - - - - - - - -
-
- -
- -
- - - - {% block body %}{% endblock %} - -
-
- - - - - - - -{% block js_block %}{% endblock %} - - - - - \ No newline at end of file diff --git a/template/oj/problem/_problem_header.html b/template/oj/problem/_problem_header.html new file mode 100644 index 00000000..82d118ff --- /dev/null +++ b/template/oj/problem/_problem_header.html @@ -0,0 +1,7 @@ + +

{{ problem.title }}

+ +

发布时间 : {{ problem.create_time }}   + 时间限制 : {{ problem.time_limit }}ms   + 内存限制 : {{ problem.memory_limit }}M +

\ No newline at end of file diff --git a/template/oj/problem/my_submission.html b/template/oj/problem/my_submission.html new file mode 100644 index 00000000..e7f6ce40 --- /dev/null +++ b/template/oj/problem/my_submission.html @@ -0,0 +1,57 @@ +{% extends 'oj_base.html' %} +{% block css_block %} + +{% endblock %} +{% block body %} + {% load submission %} +
+ + {% include "oj/problem/_problem_header.html" %} +
+
+

运行结果 : + {{ submission.result|translate_result }} + +

+ {% ifequal submission.result 0 %} +

时间 : {{ submission.accepted_answer_info.time }}ms 语言 : + {{ submission.language|translate_language }} +

+ {% endifequal %} + {% ifequal submission.result 4 %} +

{{ submission.info }}

+ {% endifequal %} +

提交时间 : {{ submission.create_time }}

+
+
+
+ +
+
+ +{% endblock %} +{% block js_block %} + +{% endblock %} \ No newline at end of file diff --git a/template/oj/problem/my_submissions_list.html b/template/oj/problem/my_submissions_list.html index cc9e1382..b1c63884 100644 --- a/template/oj/problem/my_submissions_list.html +++ b/template/oj/problem/my_submissions_list.html @@ -3,62 +3,48 @@ {% block body %} {% load submission %} -
- -

Battle Over Cities - Hard Version

+
+ +

{{ problem.title }}

-

cpu: 1000ms 内存: 256M

- - - - - - - - - - - - {% for item in submissions %} - {% ifequal item.result 0 %} - - {% else %} - {% ifequal item.result 8 %} - +

发布时间: {{ problem.create_time }}   + 时间限制: {{ problem.time_limit }}ms   + 内存限制: {{ problem.memory_limit }}M

+
#提交时间结果运行时间语言
+ + + + + + + + + + + {% for item in submissions %} + + + + + - {% endifequal %} + -- + {% endif %} + + + + {% endfor %} - {% endifequal %} - - - - - - - {% endfor %} - - -
#提交时间结果运行时间语言
{{ forloop.counter }}{{ item.create_time }}{{ item.result|translate_result }} + {% if item.accepted_answer_info.time %} + {{ item.accepted_answer_info.time }}ms {% else %} -
+ {{ item.language|translate_language }} +
{{ forloop.counter }}{{ item.create_time }}{{ item.result|translate_result }} - {% if item.accepted_answer_info.time %} - {{ item.accepted_answer_info.time }}ms - {% else %} - -- - {% endif %} - - {% ifequal item.language 1 %} - C - {% else %} - {% ifequal item.language 2 %} - C++ - {% else %} - Java - {% endifequal %} - {% endifequal %} -
-
+ + +
{% endblock %} \ No newline at end of file diff --git a/template/oj/problem/problem.html b/template/oj/problem/problem.html index 1764db22..2d8ddbb1 100644 --- a/template/oj/problem/problem.html +++ b/template/oj/problem/problem.html @@ -5,12 +5,9 @@ -

{{ problem.title }}

- -

发布时间: {{ problem.create_time }} CPU: {{ problem.time_limit }}ms - 内存: {{ problem.memory_limit }}M

+ {% include "oj/problem/_problem_header.html" %}
@@ -93,7 +90,7 @@
-
+
{% endblock %} diff --git a/template/oj_base.html b/template/oj_base.html index 0cfcf82c..4a17157d 100644 --- a/template/oj_base.html +++ b/template/oj_base.html @@ -8,13 +8,13 @@ 在线评测系统 - - {% block css_block %}{% endblock %} - - + + + {% block css_block %}{% endblock %} + @@ -47,7 +47,7 @@
  • 比赛
  • 关于
  • - {% if not request.user.is_authenticated %} + {% if request.user.is_authenticated %}