Accept Merge Request #75 : (virusdefender-dev -> dev)

Merge Request: 完善提交代码判题和显示提交信息页面
Created By: @virusdefender
Accepted By: @virusdefender
URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/75
This commit is contained in:
virusdefender 2015-08-14 10:24:34 +08:00
commit fd07ff4666
56 changed files with 709 additions and 479 deletions

View File

@ -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

View File

@ -1,12 +1,14 @@
# coding=utf-8
from functools import wraps
from django.http import HttpResponse
from django.shortcuts import render
from utils.shortcuts import error_response
from utils.shortcuts import error_response, error_page
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 一个参数
@ -16,11 +18,12 @@ def login_required(func):
if request.is_ajax():
return error_response(u"请先登录")
else:
return render(request, "utils/error.html", {"error": u"请先登录"})
return error_page(request, u"请先登录")
return check
def admin_required(func):
@wraps(func)
def check(*args, **kwargs):
request = args[-1]
if request.user.is_authenticated() and request.user.admin_type:
@ -28,5 +31,5 @@ def admin_required(func):
if request.is_ajax():
return error_response(u"需要管理员权限")
else:
return render(request, "utils/error.html", {"error": "需要管理员权限"})
return error_page(request, u"需要管理员权限")
return check

View File

@ -145,10 +145,10 @@ class UserChangePasswordAPITest(APITestCase):
self.assertEqual(response.data, {"code": 0, "data": u"用户密码修改成功!"})
class UserAPITest(APITestCase):
class UserAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("user_list_api")
self.url = reverse("user_admin_api")
user = User.objects.create(username="testx", real_name="xx", admin_type=SUPER_ADMIN)
user.set_password("testxx")
user.save()

View File

@ -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,7 +120,38 @@ class EmailCheckAPIView(APIView):
return serializer_invalid_response(serializer)
class UserAPIView(APIView):
class UserAdminAPIView(APIView):
def put(self, request):
"""
用户编辑json api接口
---
request_serializer: EditUserSerializer
response_serializer: UserSerializer
"""
serializer = EditUserSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
try:
user = User.objects.get(id=data["id"])
except User.DoesNotExist:
return error_response(u"该用户不存在!")
try:
user = User.objects.get(username=data["username"])
if user.id != data["id"]:
return error_response(u"昵称已经存在")
except User.DoesNotExist:
pass
user.username = data["username"]
user.real_name = data["real_name"]
user.email = data["email"]
user.admin_type = data["admin_type"]
if data["password"]:
user.set_password(data["password"])
user.save()
return success_response(UserSerializer(user).data)
else:
return serializer_invalid_response(serializer)
def get(self, request):
"""
用户分页json api接口
@ -140,28 +173,12 @@ class UserAPIView(APIView):
return paginate(request, user, UserSerializer)
class UserAdminAPIView(APIView):
def put(self, request):
class UserInfoAPIView(APIView):
@login_required
def get(self, request):
"""
用户编辑json api接口
返回这个用户的个人信息
---
request_serializer: EditUserSerializer
response_serializer: UserSerializer
"""
serializer = EditUserSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
try:
user = User.objects.get(id=data["id"])
except User.DoesNotExist:
return error_response(u"该用户不存在!")
user.username = data["username"]
user.real_name = data["real_name"]
user.email = data["email"]
user.admin_type = data["admin_type"]
if data["password"]:
user.set_password(data["password"])
user.save()
return success_response(UserSerializer(user).data)
else:
return serializer_invalid_response(serializer)
return success_response(UserSerializer(request.user).data)

View File

@ -4,7 +4,7 @@ from rest_framework.views import APIView
from django.shortcuts import render
from utils.shortcuts import serializer_invalid_response, error_response, success_response
from utils.shortcuts import paginate
from utils.shortcuts import paginate, error_page
from .models import Announcement
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
EditAnnouncementSerializer)
@ -14,7 +14,7 @@ def announcement_page(request, announcement_id):
try:
announcement = Announcement.objects.get(id=announcement_id, visible=True)
except Announcement.DoesNotExist:
return render(request, "utils/error.html", {"error": u"模板不存在"})
return error_page(request, u"模板不存在")
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})

View File

@ -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)

3
judge/README.md Normal file
View File

@ -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

View File

@ -1,5 +0,0 @@
# coding=utf-8
from __future__ import absolute_import
from celery import Celery
app = Celery("judge", broker="redis://localhost:6379/0", include=["judge.controller.tasks"])

View File

@ -1,8 +0,0 @@
# coding=utf-8
from __future__ import absolute_import
from judge.controller.celery import app
@app.task
def judge(source_code, language, test_case_id):
print source_code, language, test_case_id

View File

@ -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
@ -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) + \
@ -171,78 +171,3 @@ class JudgeClient(object):
self_dict = self.__dict__.copy()
del self_dict['_pool']
return self_dict
c_src = r"""
#include <stdio.h>
#include </dev/random>
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 <iostream>
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)

View File

@ -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

View File

@ -2,21 +2,21 @@
languages = {
"1": {
1: {
"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 {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 -Wall -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": {
3: {
"name": "java",
"src_name": "Main.java",
"code": 3,

81
judger/run.py Normal file
View File

@ -0,0 +1,81 @@
# 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, 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
submission_id = args[2]
time_limit = args[4]
memory_limit = args[6]
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(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"].encode("utf8"))
f.close()
# 编译
try:
exe_path = compile_(language, src_path, judger_workspace + "run/")
except Exception as e:
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 + "/")
judge_result = {"result": result["accepted"], "info": client.run()}
for item in judge_result["info"]:
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
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()

View File

@ -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
}

View File

@ -0,0 +1,10 @@
# coding=utf-8
from __future__ import absolute_import
from celery import Celery
from .settings import redis_config
app = Celery("judge", broker="redis://" +
redis_config["host"] + ":" +
str(redis_config["port"]) +
"/" + str(redis_config["db"]),
include=["judger_controller.tasks"])

View File

@ -0,0 +1,6 @@
# coding=utf-8
redis_config = {
"host": "127.0.0.1",
"port": 6379,
"db": 0
}

View File

@ -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 /Users/virusdefender/Desktop/test_case/:/var/judger/test_case/ "
"-v /Users/virusdefender/Desktop/:/var/judger/code/ "
"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),
# 设置最长运行时间是5倍的 cpu 时间
timeout=(time_limit / 1000.0 * 5), shell=True)
except subprocess.TimeoutExpired:
print "docker timeout"

View File

@ -1,19 +1,29 @@
# 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/"
# 注意这是web 服务器访问的地址,判题度武器访问的地址不一定一样,因为可能不在一台机器上
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'CONN_MAX_AGE': 1,
'CONN_MAX_AGE': 0.3,
}
}
# SECURITY WARNING: don't run with debug turned on in production!
mongodb_setting = {
'HOST': '127.0.0.1',
'USERNAME': 'root',
'PASSWORD': 'root',
'PORT': 27017
}
DEBUG = True
# 同理 这是 web 服务器的上传路径
TEST_CASE_DIR = "/Users/virusdefender/Desktop/test_case/"

View File

@ -51,6 +51,7 @@ INSTALLED_APPS = (
'group',
'problem',
'admin',
'submission',
'rest_framework',
'rest_framework_swagger',

View File

@ -5,16 +5,16 @@ 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"),
@ -22,8 +22,11 @@ urlpatterns = [
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"),
@ -32,23 +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<problem_id>\d+)/$', "problem.views.problem_page", name="problem_page"),
url(r'^announcement/(?P<announcement_id>\d+)/$', "announcement.views.announcement_page", name="announcement_page"),
url(r'^announcement/(?P<announcement_id>\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<template_dir>\w+)/(?P<template_name>\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<template_dir>\w+)/(?P<template_name>\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<problem_id>\d+)/my_solutions/', "problem.views.problem_my_solutions_list_page", name="problem_my_solutions_page"),
url(r'^my_solution/(?P<solution_id>\d+)/$', "problem.views.my_solution", name="my_solution_page"),
url(r'^problem/(?P<problem_id>\d+)/my_submissions/$', "submission.views.problem_my_submissions_list_page",
name="problem_my_submissions_page"),
url(r'^my_submission/(?P<submission_id>\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"),
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"),
]

View File

@ -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'),
),
]

View File

@ -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 = [
]

View File

@ -53,4 +53,4 @@ class Problem(AbstractProblem):
# 难度 0 - n
difficulty = models.IntegerField()
# 标签
tags = models.ManyToManyField(ProblemTag, null=True)
tags = models.ManyToManyField(ProblemTag)

View File

@ -10,7 +10,10 @@ from django.db.models import Q
from rest_framework.views import APIView
from utils.shortcuts import serializer_invalid_response, error_response, success_response, paginate, rand_str
from django.conf import settings
from utils.shortcuts import (serializer_invalid_response, error_response,
success_response, paginate, rand_str, error_page)
from .serizalizers import (CreateProblemSerializer, EditProblemSerializer, ProblemSerializer,
ProblemTagSerializer, CreateProblemTagSerializer)
from .models import Problem, ProblemTag
@ -35,32 +38,16 @@ 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):
try:
problem = Problem.objects.get(id=problem_id)
except Problem.DoesNotExist:
return render(request, "utils/error.html", {"error": u"题目不存在"})
return error_page(request, u"题目不存在")
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):
"""
@ -163,7 +150,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)
@ -196,13 +183,13 @@ 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 + problem_test_dir + "/"
# 得到了合法的测试用例文件列表 然后去解压缩
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()

View File

@ -7,3 +7,5 @@ django-rest-swagger
celery
gunicorn
coverage
subprocess32
pymongo

View File

@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.

View File

@ -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 != "")

View File

@ -1,12 +1,19 @@
require(["jquery", "code_mirror"], function ($, code_mirror) {
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 = $("input[name='language'][checked]").val();
var submission_id;
$("#language-selector").change(function () {
var 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();
@ -17,17 +24,109 @@ require(["jquery", "code_mirror"], function ($, code_mirror) {
$("#loading-gif").hide();
}
function get_result_html(data) {
// 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 = '<div class="alert alert-' +
results[data.result].alert_class + ' result"' +
' role="alert">' +
'<div class="alert-link">' +
results[data.result].message +
'!&nbsp;&nbsp; ';
if (!data.result) {
html += "CPU time: " + data.accepted_answer_info.time + "ms &nbsp;&nbsp;";
}
html += ('<a href="/my_submission/' + submission_id + '/" target="_blank">查看详情</a></div> </div>');
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));
}
}
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();
setTimeout(
function () {
$("#a").animate({opacity: '1'})
}, 3);
if(!code.trim()){
bs_alert("请填写代码!");
hide_loading();
return false;
}
$("#result").html("");
$.ajax({
beforeSend: csrfHeader,
url: "/api/submission/",
method: "post",
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();
}
}
});
$("#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('<div class="alert alert-danger" role="alert"><div class="alert-link">请先<a href="/login/" target="_blank">登录</a>!</div> </div>');
}
}
})
});

View File

@ -1,7 +1,17 @@
define("bs_alert", ["jquery", "bootstrap"], function($){
function bs_alert(content){
if(!$("#alert-modal").length) {
var html = '<div class="modal fade" id="alert-modal" tabindex="-1" role="dialog"> ' +
'<div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> ' +
'<button type="button" class="close" data-dismiss="modal" aria-label="Close">' +
'<spanaria-hidden="true">&times;</span></button> <h4 class="modal-title">提示</h4> ' +
'</div> <div class="modal-body"> <p id="modal-text"></p> </div> <div class="modal-footer"> ' +
'<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button> </div> ' +
'</div> </div> </div>';
$("body").append(html);
}
$("#modal-text").html(content);
$("#modal").modal();
$("#alert-modal").modal();
}
return bs_alert;
});

10
submission/serializers.py Normal file
View File

@ -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)

96
submission/views.py Normal file
View File

@ -0,0 +1,96 @@
# coding=utf-8
import datetime
import pymongo
from bson.objectid import ObjectId
from django.shortcuts import render
from rest_framework.views import APIView
from django.conf import settings
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, error_page
from .serializers import CreateSubmissionSerializer
def _create_mondodb_connection():
mongodb_setting = settings["mongodb_setting"]
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):
"""
提交代码
---
request_serializer: CreateSubmissionSerializer
"""
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"]
data["create_time"] = datetime.datetime.now()
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.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)
@login_required
def get(self, request):
submission_id = request.GET.get("submission_id", None)
if not submission_id:
return error_response(u"参数错误")
submission = _create_mondodb_connection().find_one({"_id": ObjectId(submission_id), "user_id": request.user.id})
if submission:
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"提交不存在")
@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]])
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})
@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})

View File

@ -124,23 +124,7 @@
</div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">提示</h4>
</div>
<div class="modal-body">
<p id="modal-text"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<script src="/static/js/config.js"></script>
<script src="/static/js/require.js"></script>

View File

@ -1,120 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="renderer" content="webkit">
<title>在线评测系统 - 后台管理</title>
<!-- custom css begin -->
{% block css_block %}{% endblock %}
<!-- custom css end -->
<!-- global css begin -->
<link href="/static/css/admin.css" rel="stylesheet">
<!-- global css end -->
</head>
<body>
<!-- nav begin -->
<nav class="navbar navbar-masthead navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">qduoj admin</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">主页</a></li>
<li><a href="#about">题目</a></li>
<li><a href="#contact">提交</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">
李扬
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">我的提交</a></li>
<li><a href="#">我的资料</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">退出</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!-- nav end -->
<!--browser happy begin -->
<!--[if lt IE 9]>
<div class="alert alert-danger text-center" role="alert">
当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>.
</div>
<![endif]-->
<!-- browser happy end -->
<div class="container" ms-controller="admin">
<div class="row">
<!-- admin left begin-->
<div class="col-md-2">
<ul class="list-group">
<li class="list-group-header">List header</li>
<li class="list-group-item" id="li-index"><a href="#index">主页</a></li>
<li class="list-group-item" id="li-announcement"><a href="#announcement">公告</a></li>
<li class="list-group-item"><a href="#">Applications</a></li>
<li class="list-group-header">Another list header</li>
<li class="list-group-item"><a href="#">Help</a></li>
</ul>
</div>
<!-- admin left end -->
<!-- custom body begin -->
{% block body %}{% endblock %}
<!-- custom body end -->
</div>
</div>
<div class="modal fade" id="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">提示</h4>
</div>
<div class="modal-body">
<p id="modal-text"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<script src="/static/js/config.js"></script>
<script src="/static/js/require.js"></script>
<script>
require(["bootstrap", "admin"]);
</script>
{% block js_block %}{% endblock %}
<!-- footer begin -->
<div class="footer">
<p class="text-muted text-center">Copyright © 2015 青岛大学信息工程学院 创新实验室</p>
</div>
<!-- footer end -->
</body>
</html>

View File

@ -0,0 +1,7 @@
<h2 class="text-center">{{ problem.title }}</h2>
<p class="text-muted text-center">发布时间 : {{ problem.create_time }}&nbsp;&nbsp;
时间限制 : {{ problem.time_limit }}ms&nbsp;&nbsp;
内存限制 : {{ problem.memory_limit }}M
</p>

View File

@ -1,31 +0,0 @@
{% extends 'oj_base.html' %}
{% block body %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation">
<a href="problem.html">题目</a></li>
<li role="presentation" class="active"><a href="my_solutions_list.html">我的提交</a></li>
<li role="presentation"><a href="#">讨论</a></li>
</ul>
<h2 class="text-center">Battle Over Cities - Hard Version</h2>
<p class="text-muted text-center">cpu: 1000ms 内存: 256M</p>
<div class="panel panel-default">
<div class="panel-body">
<h4>运行结果:<span class="text-success">Accepted</span></h4>
<p>cpu: 1000ms 内存: 256M 语言:python</p>
</div>
</div>
<div id="code-field">
<textarea id="code-editor">
#include &lt;stdio.h&gt;
int main()
{
printf(&quot;Hello world&quot;);
return 0;
}</textarea>
</div>
</div>
{% endblock %}

View File

@ -1,53 +0,0 @@
{% extends 'oj_base.html' %}
{% block body %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation">
<a href="/problem/1/">题目</a></li>
<li role="presentation" class="active"><a href="my_solutions_list.html">我的提交</a></li>
</ul>
<h2 class="text-center">Battle Over Cities - Hard Version</h2>
<p class="text-muted text-center">cpu: 1000ms 内存: 256M</p>
<table class="table table-bordered">
<thead>
<tr class=""success>
<th>#</th>
<th>提交时间</th>
<th>结果</th>
<th>运行时间</th>
<th>运行内存</th>
<th>语言</th>
</tr>
</thead>
<tbody>
<tr class="warning">
<th scope="row">1</th>
<td>1</td>
<td>Error Format</td>
<td>3</td>
<td>3</td>
<td>3</td>
</tr>
<tr class="danger">
<th scope="row">2</th>
<td>Wrong</td>
<td>Wrong Answer</td>
<td>@fat</td>
<td>3</td>
<td>3</td>
</tr>
<tr class="success">
<th scope="row">3</th>
<td>Larry</td>
<td>Accepted</td>
<td>@twitter</td>
<td>3</td>
<td>3</td>
</tr>
</tbody>
</table>
</div>
{% endblock %}

View File

@ -0,0 +1,57 @@
{% extends 'oj_base.html' %}
{% block css_block %}
<style>
.CodeMirror{
height: auto;
}
</style>
{% endblock %}
{% block body %}
{% load submission %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation">
<a href="/problem/{{ problem.id }}/">题目</a></li>
<li role="presentation" class="active"><a href="/problem/{{ problem.id }}/my_submissions/">我的提交</a></li>
</ul>
{% include "oj/problem/_problem_header.html" %}
<div class="panel panel-default">
<div class="panel-body">
<h4>运行结果 : <span class="text-{{ submission.result|translate_result_class }}">
{{ submission.result|translate_result }}
</span>
</h4>
{% ifequal submission.result 0 %}
<p>时间 : {{ submission.accepted_answer_info.time }}ms 语言 :
{{ submission.language|translate_language }}
</p>
{% endifequal %}
{% ifequal submission.result 4 %}
<p>{{ submission.info }}</p>
{% endifequal %}
<p>提交时间 : {{ submission.create_time }}</p>
</div>
</div>
<div id="code-field">
<textarea id="code-editor">{{ submission.code }}</textarea>
</div>
</div>
{% endblock %}
{% block js_block %}
<script>
require(["jquery", "code_mirror"], function ($, code_mirror) {
{% ifequal submission.language 1 %}
var language = "text/x-csrc";
{% else %}
{% ifequal submission.language 2 %}
var language = "text/x-c++src";
{% else %}
var language = "text/x-java";
{% endifequal %}
{% endifequal %}
var code_editor = code_mirror($("#code-editor")[0], language);
code_editor.setOption("readOnly", true);
});
</script>
{% endblock %}

View File

@ -0,0 +1,50 @@
{% extends 'oj_base.html' %}
{% block body %}
{% load submission %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation">
<a href="/problem/{{ problem.id }}/">题目</a></li>
<li role="presentation" class="active">
<a href="/problem/{{ problem.id }}/my_submissions/">我的提交</a></li>
</ul>
<h2 class="text-center">{{ problem.title }}</h2>
<p class="text-muted text-center">发布时间: {{ problem.create_time }}&nbsp;&nbsp;
时间限制: {{ problem.time_limit }}ms&nbsp;&nbsp;
内存限制: {{ problem.memory_limit }}M</p>
<table class="table table-bordered">
<thead>
<tr class="" success>
<th>#</th>
<th>提交时间</th>
<th>结果</th>
<th>运行时间</th>
<th>语言</th>
</tr>
</thead>
<tbody>
{% for item in submissions %}
<tr class="{{ item.result|translate_result_class }}">
<th scope="row"><a href="/my_submission/{{ item|translate_id }}/">{{ forloop.counter }}</a></th>
<td>{{ item.create_time }}</td>
<td>{{ item.result|translate_result }}</td>
<td>
{% if item.accepted_answer_info.time %}
{{ item.accepted_answer_info.time }}ms
{% else %}
--
{% endif %}
</td>
<td>
{{ item.language|translate_language }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -5,11 +5,9 @@
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active">
<a href="problem.html">题目</a></li>
<li role="presentation"><a href="/problem/1/my_solutions/">我的提交</a></li>
<li role="presentation"><a href="/problem/{{ problem.id }}/my_submissions/">我的提交</a></li>
</ul>
<h2 class="text-center">{{ problem.title }}</h2>
<p class="text-muted text-center">发布时间: {{ problem.create_time }} CPU: {{ problem.time_limit }}ms 内存: {{ problem.memory_limit }}M</p>
{% include "oj/problem/_problem_header.html" %}
<div>
<div class="problem-section">
@ -20,12 +18,12 @@
<div class="problem-section">
<label class="problem-label">输入</label>
<p class="problem-detail">第一行包括两个数n,k</p>
<p class="problem-detail">{{ problem.input_description }}</p>
</div>
<div class="problem-section">
<label class="problem-label">输出</label>
<p class="problem-detail">第一行包括两个数n,k</p>
<p class="problem-detail">{{ problem.output_description }}k</p>
</div>
{% for item in samples %}
<div class="problem-section">
@ -44,7 +42,7 @@
<div>
<button type="button" id="show-more-btn" class="btn btn-info btn-sm">查看隐藏信息</button>
</div>
{% if problem.hind %}
{% if problem.hint %}
<div class="problem-section hide">
<label class="problem-label">提示</label>
@ -66,13 +64,13 @@
<div>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" value="c" checked> c (gcc 4.8)
<input type="radio" name="language" value="1" checked> C (gcc 4.8)
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" value="cpp"> c++ (g++ 4.3)
<input type="radio" name="language" value="2"> C++ (g++ 4.3)
</label>
<label class="radio-inline">
<input type="radio" name="inlineRadioOptions" value="java"> Java (jre 1.7)
<input type="radio" name="language" value="3"> Java (jre 1.7)
</label>
</div>
</div>
@ -89,24 +87,10 @@
<img src="/static/img/loading.gif" id="loading-gif">
</div>
<div id="result">
</div>
<hr>
<div class="result">
<div class="alert alert-success" role="alert" id="a" style="opacity: 0">
<div class="alert-link">
Accepted!&nbsp;&nbsp;时间:378ms 内存: 35m&nbsp;&nbsp;
<a href="#">查看详情</a>
</div>
</div>
<div class="alert alert-danger" role="alert">
<div class="alert-link">Wrong Answer!</div>
</div>
<div class="alert alert-danger" role="alert">
<div class="alert-link">Compile Error!</div>
</div>
<div class="alert alert-warning" role="alert">
<div class="alert-link">Error Format!</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -8,13 +8,13 @@
<title>在线评测系统</title>
<!-- custom css begin -->
{% block css_block %}{% endblock %}
<!-- custom css end -->
<!-- global css begin -->
<link href="/static/css/oj.css" rel="stylesheet">
<!-- global css end -->
<!-- custom css begin -->
{% block css_block %}{% endblock %}
<!-- custom css end -->
</head>
@ -47,7 +47,7 @@
<li><a href="/contests/">比赛</a></li>
<li><a href="/about/">关于</a></li>
</ul>
{% if not request.user.is_authenticated %}
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
@ -80,24 +80,6 @@
{% block body %}{% endblock %}
<!-- custom body end -->
<div class="modal fade" id="modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title">提示</h4>
</div>
<div class="modal-body">
<p id="modal-text"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
<script src="/static/js/config.js"></script>
<script src="/static/js/require.js"></script>
<script>

View File

@ -5,6 +5,6 @@
<title></title>
</head>
<body>
{{ error }}
</body>
</html>

View File

@ -5,6 +5,6 @@
<title></title>
</head>
<body>
{{ info }}
</body>
</html>

View File

@ -3,17 +3,23 @@ import hashlib
import time
import random
from django.shortcuts import render
from django.core.paginator import Paginator
from rest_framework.response import Response
def error_page(request, error_reason):
return render(request, "utils/error.html", {"error": error_reason})
def error_response(error_reason):
return Response(data={"code": 1, "data": error_reason})
def serializer_invalid_response(serializer):
return error_response(serializer.errors)
for k, v in serializer.errors.iteritems():
return error_response(k + " : " + v[0])
def success_response(data):

View File

@ -0,0 +1 @@
# coding=utf-8

View File

@ -0,0 +1,42 @@
# coding=utf-8
def translate_result(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):
return submission_item["_id"]
def translate_language(value):
return {1: "C", 2: "C++", 3: "Java"}[value]
def translate_result_class(value):
if value == 0:
return "success"
elif value == "8":
return "info"
return "danger"
from django import template
register = template.Library()
register.filter("translate_result", translate_result)
register.filter("translate_id", translate_id)
register.filter("translate_language", translate_language)
register.filter("translate_result_class", translate_result_class)