186 lines
6.8 KiB
Python
186 lines
6.8 KiB
Python
from django.shortcuts import render
|
|
from django.http import HttpResponse, HttpResponseRedirect
|
|
from django.contrib.auth import authenticate, login, logout
|
|
from django.template.defaultfilters import register
|
|
from .forms import UploadFileForm
|
|
from .models import *
|
|
import os
|
|
from subprocess import Popen, PIPE, STDOUT, call
|
|
import shutil
|
|
from django.conf import settings
|
|
import time
|
|
|
|
@register.filter(name='dict_key')
|
|
def dict_key(d, k):
|
|
return d[k]
|
|
|
|
def Index(request):
|
|
if request.user.is_authenticated:
|
|
user = User.objects.get(id = request.user.id)
|
|
else:
|
|
return HttpResponseRedirect('login/')
|
|
|
|
if request.method == 'POST':
|
|
p_id = request.POST.get('problem')
|
|
problem = Problems.objects.get(id=p_id)
|
|
resolved = Resolvs.objects.filter(Problem=problem, Status=1, User=user).last()
|
|
if not problem or resolved:
|
|
return HttpResponseRedirect('/')
|
|
|
|
file = Resolvs(
|
|
SrcFile = request.FILES['resolve'],
|
|
User = user,
|
|
Problem = problem,
|
|
)
|
|
file.save()
|
|
file_ext =file.SrcFile.path[file.SrcFile.path.rindex('.')+1:]
|
|
if file_ext in ['py','cpp']:
|
|
#Запускаю проверку решения на корректность
|
|
tests = Tests.objects.filter(Problem=problem)
|
|
rt_dir = os.path.join(settings.TEMP_DIR,str(user.id))
|
|
if not os.path.exists(rt_dir):
|
|
os.mkdir(rt_dir)
|
|
shutil.copy(file.SrcFile.path, rt_dir+'/resolv.'+file_ext)
|
|
status = 1
|
|
message = ''
|
|
dt = 0
|
|
test_num = 0
|
|
for t in tests:
|
|
test_num += 1
|
|
stdout_data = ''
|
|
stderr_data = ''
|
|
|
|
with open(rt_dir+'/INPUT.TXT','w') as f:
|
|
f.write(t.Input)
|
|
#Запускаем отдельный процесс для проверки задачи
|
|
try:
|
|
startt = time.time()
|
|
if file_ext == 'py':
|
|
proc = Popen(['python',f'{rt_dir}\\resolv.py'], stdout=PIPE, stdin=PIPE, stderr=PIPE, text=True)
|
|
print(t.Input,f'{rt_dir}\\resolv.py')
|
|
stdout_data, stderr_data = proc.communicate(input=t.Input, timeout=20)
|
|
print(stdout_data, stderr_data)
|
|
elif file_ext == 'cpp':
|
|
if test_num == 1:
|
|
proc = call(f"g++ {rt_dir}/resolv.cpp",
|
|
cwd=rt_dir,
|
|
timeout=20,
|
|
shell=True)
|
|
proc = call(f"{rt_dir}/a.out",
|
|
cwd=rt_dir,
|
|
timeout=problem.TimeLimit,
|
|
shell=True)
|
|
endt = time.time()
|
|
tm = endt - startt
|
|
dt = tm if dt < tm else dt
|
|
except Exception as e:
|
|
print(e)
|
|
status = 3
|
|
message = f"Выбили по таймауту"
|
|
break
|
|
#Проверяем корректность решения
|
|
if os.path.exists(rt_dir+'/OUTPUT.TXT'):
|
|
with open(rt_dir+'/OUTPUT.TXT','r') as f:
|
|
st = f.read()
|
|
if st != t.Output:
|
|
status = 3
|
|
message=f'Решение не верно. Тест {test_num}.'
|
|
break
|
|
else:
|
|
if stdout_data.strip() != t.Output:
|
|
status = 3
|
|
message=f'Решение не верно. Тест {test_num}.'
|
|
break
|
|
else:
|
|
status = 9
|
|
message = "Неизвесный формат файла"
|
|
|
|
#Записываем результат в БД
|
|
file.Status = status
|
|
file.Message = message
|
|
file.Time = dt
|
|
file.save()
|
|
|
|
problems = Problems.objects.all()
|
|
dr = {}
|
|
dmessage = {}
|
|
link = {}
|
|
for p in problems:
|
|
resolv = Resolvs.objects.filter(User=user, Problem=p).last()
|
|
if resolv:
|
|
if resolv.Status == 1:
|
|
dr[p.id] = 1
|
|
dmessage[p.id] = ''
|
|
link[p.id] = resolv.SrcFile.url
|
|
else:
|
|
dr[p.id] = 0
|
|
dmessage[p.id] = resolv.Message
|
|
else:
|
|
dr[p.id] = 0
|
|
dmessage[p.id] = ''
|
|
return render(request,'index.html',{'problems':problems,
|
|
'user':user,
|
|
'resolved':dr,
|
|
'message':dmessage,
|
|
'link':link,})
|
|
def Details(request,p_id):
|
|
if request.user.is_authenticated:
|
|
user = User.objects.get(id = request.user.id)
|
|
else:
|
|
return HttpResponseRedirect('login/')
|
|
problem = Problems.objects.get(id=p_id)
|
|
resolvs = Resolvs.objects.filter(Problem=problem, Status=1)
|
|
res = []
|
|
usrs = {}
|
|
ext = {}
|
|
for r in resolvs:
|
|
res.append(r.id)
|
|
usrs[r.id] = r.User.username
|
|
ext[r.id] = os.path.splitext(r.SrcFile.name)[1][1:].upper()
|
|
return render(request,'details.html',{
|
|
'problem':problem,
|
|
'user':user,
|
|
'resolvs':res,
|
|
'u_list':usrs,
|
|
'ext':ext,
|
|
})
|
|
|
|
|
|
def Login(request):
|
|
if request.method == 'POST':
|
|
username = request.POST.get('login')
|
|
pwd = request.POST.get('password')
|
|
user = authenticate(request,username=username, password=pwd)
|
|
if user is not None:
|
|
login(request, user)
|
|
request.session['username'] = username
|
|
request.session.save()
|
|
return HttpResponseRedirect('/')
|
|
return render(request, 'login.html')
|
|
|
|
def Logout(request):
|
|
logout(request)
|
|
return HttpResponseRedirect('/')
|
|
|
|
def Registration(request):
|
|
if request.method == 'POST':
|
|
name = request.POST.get('name')
|
|
pwd = request.POST.get('password')
|
|
email = request.POST.get('email')
|
|
user = User.objects.filter(username = name).first()
|
|
if user:
|
|
print('Имя занято')
|
|
return render(request,'register.html')
|
|
user = User.objects.filter(email = email).first()
|
|
if user:
|
|
print('Email уже есть')
|
|
return render(request,'register.html')
|
|
user = User.objects.create_user(
|
|
name,
|
|
email,
|
|
pwd,
|
|
is_staff = True
|
|
)
|
|
return HttpResponseRedirect('/')
|
|
return render(request,'register.html')
|