增加上传和解析测试用例压缩包的接口

This commit is contained in:
virusdefender 2015-08-10 12:25:35 +08:00
parent 09b59d6e43
commit c809d0de47
3 changed files with 79 additions and 0 deletions

View File

@ -9,6 +9,8 @@ from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterA
from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView from announcement.views import AnnouncementAPIView, AnnouncementAdminAPIView
from group.views import GroupAdminAPIView from group.views import GroupAdminAPIView
from admin.views import AdminTemplateView from admin.views import AdminTemplateView
from problem.views import TestCaseUploadAPIView
urlpatterns = [ urlpatterns = [
url(r'^install/$', "install.views.install"), 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'^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/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/$', GroupAdminAPIView.as_view(), name="group_admin_api"),
url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"),
] ]

View File

@ -1,7 +1,73 @@
# coding=utf-8 # coding=utf-8
import zipfile
import re
from django.shortcuts import render 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): def problem_page(request, problem_id):
# todo # todo
return render(request, "oj/problem/problem.html") 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"测试用例压缩文件格式错误,请保证测试用例文件在根目录下直接压缩")

View File

@ -1,4 +1,8 @@
# coding=utf-8 # coding=utf-8
import hashlib
import time
import random
from django.core.paginator import Paginator from django.core.paginator import Paginator
from rest_framework.response import Response from rest_framework.response import Response
@ -87,3 +91,8 @@ def paginate(request, query_set, object_serializer):
pass pass
return success_response(data) 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]