mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2025-11-04 14:49:58 +08:00
add test case upload api
This commit is contained in:
parent
e34da1ac33
commit
48f79ec504
@ -31,9 +31,5 @@ DEBUG = True
|
|||||||
|
|
||||||
ALLOWED_HOSTS = ["*"]
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
# 在 debug 关闭的情况下,静态文件不是有 django runserver 来处理的,应该由 nginx 返回
|
TEST_CASE_DIR = "/tmp"
|
||||||
# 在 debug 开启的情况下,django 会在下面两个文件夹中寻找对应的静态文件。
|
|
||||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "frontend/static/"), BASE_DIR]
|
|
||||||
|
|
||||||
# 模板文件夹
|
|
||||||
OJ_TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/src/')]
|
|
||||||
|
|||||||
@ -40,9 +40,6 @@ DEBUG = False
|
|||||||
|
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
# 在 debug 关闭的情况下,静态文件不是有 django runserver 来处理的,应该由 nginx 返回
|
|
||||||
# 在 debug 开启的情况下,django 会在下面两个文件夹中寻找对应的静态文件。
|
|
||||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static/release/")]
|
|
||||||
|
|
||||||
# 模板文件夹
|
TEST_CASE_DIR = "/test_case"
|
||||||
OJ_TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/release/')]
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@ ROOT_URLCONF = 'oj.urls'
|
|||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': OJ_TEMPLATE_DIRS,
|
'DIRS': [],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
@ -171,8 +171,6 @@ CELERY_TASK_SERIALIZER = "json"
|
|||||||
|
|
||||||
DATABASE_ROUTERS = ['oj.db_router.DBRouter']
|
DATABASE_ROUTERS = ['oj.db_router.DBRouter']
|
||||||
|
|
||||||
TEST_CASE_DIR = os.path.join(BASE_DIR, 'test_case/')
|
|
||||||
|
|
||||||
IMAGE_UPLOAD_DIR = os.path.join(BASE_DIR, 'upload/')
|
IMAGE_UPLOAD_DIR = os.path.join(BASE_DIR, 'upload/')
|
||||||
|
|
||||||
# 用于限制用户恶意提交大量代码
|
# 用于限制用户恶意提交大量代码
|
||||||
|
|||||||
@ -7,4 +7,5 @@ urlpatterns = [
|
|||||||
url(r"^api/", include("conf.urls.oj")),
|
url(r"^api/", include("conf.urls.oj")),
|
||||||
url(r"^api/admin/", include("conf.urls.admin")),
|
url(r"^api/admin/", include("conf.urls.admin")),
|
||||||
url(r"^api/", include("problem.urls.oj")),
|
url(r"^api/", include("problem.urls.oj")),
|
||||||
|
url(r"^api/admin/", include("problem.urls.admin")),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
from django import forms
|
||||||
|
|
||||||
|
|
||||||
|
class TestCaseUploadForm(forms.Form):
|
||||||
|
spj = forms.BooleanField()
|
||||||
|
file = forms.FileField()
|
||||||
@ -1,6 +1,7 @@
|
|||||||
from utils.api.tests import APITestCase
|
from utils.api.tests import APITestCase
|
||||||
|
|
||||||
from .models import ProblemTag
|
from .models import ProblemTag
|
||||||
|
from .views.admin import TestCaseUploadAPI
|
||||||
|
|
||||||
|
|
||||||
class ProblemTagListAPITest(APITestCase):
|
class ProblemTagListAPITest(APITestCase):
|
||||||
@ -10,3 +11,15 @@ class ProblemTagListAPITest(APITestCase):
|
|||||||
resp = self.client.get(self.reverse("problem_tag_list_api"))
|
resp = self.client.get(self.reverse("problem_tag_list_api"))
|
||||||
self.assertSuccess(resp)
|
self.assertSuccess(resp)
|
||||||
self.assertEqual(resp.data["data"], ["name1", "name2"])
|
self.assertEqual(resp.data["data"], ["name1", "name2"])
|
||||||
|
|
||||||
|
|
||||||
|
class TestCaseUploadAPITest(APITestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.api = TestCaseUploadAPI()
|
||||||
|
|
||||||
|
def test_filter_file_name(self):
|
||||||
|
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in", ".DS_Store"], spj=False), ["1.in", "1.out"])
|
||||||
|
self.assertEqual(self.api.filter_name_list(["2.in", "2.out"], spj=False), [])
|
||||||
|
|
||||||
|
self.assertEqual(self.api.filter_name_list(["1.in", "1.out", "2.in"], spj=True), ["1.in", "2.in"])
|
||||||
|
self.assertEqual(self.api.filter_name_list(["2.in", "3.in"], spj=True), [])
|
||||||
|
|||||||
7
problem/urls/admin.py
Normal file
7
problem/urls/admin.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from ..views.admin import TestCaseUploadAPI
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r"^test_case/upload$", TestCaseUploadAPI.as_view(), name="test_case_upload_api")
|
||||||
|
]
|
||||||
@ -1,6 +1,6 @@
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from ..views import ProblemTagAPI
|
from ..views.oj import ProblemTagAPI
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r"^tags$", ProblemTagAPI.as_view(), name="problem_tag_list_api")
|
url(r"^tags$", ProblemTagAPI.as_view(), name="problem_tag_list_api")
|
||||||
|
|||||||
0
problem/views/__init__.py
Normal file
0
problem/views/__init__.py
Normal file
68
problem/views/admin.py
Normal file
68
problem/views/admin.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import os
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
from utils.api import CSRFExemptAPIView
|
||||||
|
from account.decorators import admin_required
|
||||||
|
from utils.shortcuts import rand_str
|
||||||
|
|
||||||
|
from ..serializers import TestCaseUploadForm
|
||||||
|
|
||||||
|
|
||||||
|
class TestCaseUploadAPI(CSRFExemptAPIView):
|
||||||
|
request_parsers = ()
|
||||||
|
|
||||||
|
def filter_name_list(self, name_list, spj):
|
||||||
|
ret = []
|
||||||
|
prefix = 1
|
||||||
|
if spj:
|
||||||
|
while True:
|
||||||
|
in_name = str(prefix) + ".in"
|
||||||
|
if in_name in name_list:
|
||||||
|
ret.append(in_name)
|
||||||
|
prefix += 1
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return sorted(ret)
|
||||||
|
else:
|
||||||
|
while True:
|
||||||
|
in_name = str(prefix) + ".in"
|
||||||
|
out_name = str(prefix) + ".out"
|
||||||
|
if in_name in name_list and out_name in name_list:
|
||||||
|
ret.append(in_name)
|
||||||
|
ret.append(out_name)
|
||||||
|
prefix += 1
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
return sorted(ret)
|
||||||
|
|
||||||
|
@admin_required
|
||||||
|
def post(self, request):
|
||||||
|
form = TestCaseUploadForm(request.POST, request.FILES)
|
||||||
|
if form.is_valid():
|
||||||
|
spj = form.cleaned_data["spj"]
|
||||||
|
file = form.cleaned_data["file"]
|
||||||
|
else:
|
||||||
|
return self.error("Upload failed")
|
||||||
|
tmp_file = os.path.join("/tmp", rand_str() + ".zip")
|
||||||
|
with open(tmp_file, "wb") as f:
|
||||||
|
for chunk in file:
|
||||||
|
f.write(chunk)
|
||||||
|
try:
|
||||||
|
zip_file = zipfile.ZipFile(tmp_file)
|
||||||
|
except zipfile.BadZipfile:
|
||||||
|
return self.error("Bad zip file")
|
||||||
|
name_list = zip_file.namelist()
|
||||||
|
test_case_list = self.filter_name_list(name_list, spj=spj)
|
||||||
|
if not test_case_list:
|
||||||
|
return self.error("Empty file")
|
||||||
|
|
||||||
|
test_case_id = rand_str()
|
||||||
|
test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id)
|
||||||
|
os.mkdir(test_case_dir)
|
||||||
|
|
||||||
|
for item in test_case_list:
|
||||||
|
with open(os.path.join(test_case_dir, item), "wb") as f:
|
||||||
|
f.write(zip_file.read(item).replace(b"\r\n", b"\n"))
|
||||||
|
return self.success(test_case_list)
|
||||||
@ -1,6 +1,6 @@
|
|||||||
from utils.api import APIView
|
from utils.api import APIView
|
||||||
|
|
||||||
from .models import ProblemTag
|
from ..models import ProblemTag
|
||||||
|
|
||||||
|
|
||||||
class ProblemTagAPI(APIView):
|
class ProblemTagAPI(APIView):
|
||||||
@ -11,7 +11,7 @@ class JSONField(serializers.Field):
|
|||||||
|
|
||||||
class DateTimeTZField(serializers.DateTimeField):
|
class DateTimeTZField(serializers.DateTimeField):
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
self.format = "%Y-%-m-%d %H:%M:%S"
|
self.format = "%Y-%-m-%d %H:%M:%S %Z"
|
||||||
value = timezone.localtime(value)
|
value = timezone.localtime(value)
|
||||||
return super(DateTimeTZField, self).to_representation(value)
|
return super(DateTimeTZField, self).to_representation(value)
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ from django.utils.decorators import method_decorator
|
|||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger("")
|
||||||
|
|
||||||
|
|
||||||
class ContentType(object):
|
class ContentType(object):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user