From c809d0de479e5c3f556fd650c727644104113b63 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Mon, 10 Aug 2015 12:25:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=8A=E4=BC=A0=E5=92=8C?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E5=8C=85=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 4 +++ problem/views.py | 66 ++++++++++++++++++++++++++++++++++++++++++++++ utils/shortcuts.py | 9 +++++++ 3 files changed, 79 insertions(+) diff --git a/oj/urls.py b/oj/urls.py index 45d4b80f..bcfb2110 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -9,6 +9,8 @@ from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterA from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView from group.views import GroupAdminAPIView from admin.views import AdminTemplateView +from problem.views import TestCaseUploadAPIView + urlpatterns = [ url(r'^install/$', "install.views.install"), @@ -34,4 +36,6 @@ urlpatterns = [ 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/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"), ] diff --git a/problem/views.py b/problem/views.py index 58fb9e6d..bf5927e4 100644 --- a/problem/views.py +++ b/problem/views.py @@ -1,7 +1,73 @@ # coding=utf-8 +import zipfile +import re from django.shortcuts import render +from django.views.decorators.csrf import csrf_exempt + +from rest_framework.views import APIView + +from utils.shortcuts import rand_str, error_response, success_response def problem_page(request, problem_id): # todo return render(request, "oj/problem/problem.html") + + +class TestCaseUploadAPIView(APIView): + + def _is_legal_test_case_file_name(self, file_name): + # 正整数开头的 .in 或者.out 结尾的 + regex = r"^[1-9]\d*\.(in|out)$" + return re.compile(regex).match(file_name) is not None + + @csrf_exempt + def post(self, request): + f = request.FILES["file"] + + tmp_zip = "tmp/" + rand_str() + ".zip" + with open(tmp_zip) as test_case_zip: + for chunk in f: + test_case_zip.write(chunk) + + test_case_file = zipfile.ZipFile(tmp_zip, 'r') + name_list = test_case_file.namelist() + + l = [] + + # 如果文件是直接打包的,那么name_list 就是["1.in", "1.out"]这样的 + # 如果文件还有一层文件夹test_case,那么name_list就是["test_case/", "test_case/1.in", "test_case/1.out"] + # 现在暂时只支持第一种,先判断一下是什么格式的 + + # 第一种格式的 + if "1.in" in name_list and "1.out" in name_list: + for file_name in name_list: + if self._is_legal_test_case_file_name(file_name): + name = file_name.spit(".") + # 有了.in 判断对应的.out 在不在 + if name[1] == "in": + if (name[0] + ".out") in name_list: + l.append(file_name) + else: + return error_response(u"测试用例文件不完整,缺少" + name[0] + ".out") + else: + # 有了.out 判断对应的 .in 在不在 + if (name[0] + ".in") in name_list: + l.append(file_name) + else: + return error_response(u"测试用例文件不完整,缺少" + name[0] + ".in") + + problem_test_dir = rand_str() + test_case_dir = "test_case/" + problem_test_dir + "/" + + # 得到了合法的测试用例文件列表 然后去解压缩 + for name in l: + f = open(test_case_dir + name, "w+b") + f.write(test_case_file.read(name)) + f.close() + + return success_response(problem_test_dir) + + else: + return error_response(u"测试用例压缩文件格式错误,请保证测试用例文件在根目录下直接压缩") + diff --git a/utils/shortcuts.py b/utils/shortcuts.py index 44610a9f..a2543461 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -1,4 +1,8 @@ # coding=utf-8 +import hashlib +import time +import random + from django.core.paginator import Paginator from rest_framework.response import Response @@ -87,3 +91,8 @@ def paginate(request, query_set, object_serializer): pass return success_response(data) + + +def rand_str(length=32): + string = hashlib.md5(str(time.time()) + str(random.randrange(1, 9999999900))).hexdigest() + return string[0:length] \ No newline at end of file