codestyle

This commit is contained in:
Egor Matveev 2021-12-02 18:24:51 +03:00
parent 255a364c34
commit d2d427fd6e
25 changed files with 168 additions and 378 deletions

View File

@ -1,275 +0,0 @@
from os import listdir, mkdir
from os.path import basename, isdir
from shutil import rmtree, copyfile
from threading import Thread
from xml.dom.minidom import parse
from Main.models import *
from .main import solution_path
def start_new(host):
in_queue = list(Solution.objects.filter(result="IN QUEUE"))
if in_queue:
sol = in_queue[0]
for s in in_queue:
dif = (
s.task.block.priority * 10
+ s.task.priority
- sol.task.block.priority * 10
- sol.task.priority
)
if dif > 0:
sol = s
elif dif == 0 and s.id < sol.id:
sol = s
Tester(sol, host).test()
def is_project(path):
return any([x.endswith(".csproj") for x in listdir(path)])
def get_node_value(element):
return element[0].firstChild.nodeValue
def nunit_path(working_dir):
return "..{}".format(sep) * len(
working_dir.split(sep)
) + "nunit_console{}nunit3-console.exe".format(sep)
class Tester:
def __init__(self, solution, host):
self.solution = solution
self.host = host
self.working_dir = ""
self.files = []
# функция компиляции
def build(self, path):
# решение для UNIX
# shell('msbuild ' + path + ' /p:Configuration=Debug')
# решение для Windows
cmd = "dotnet build {} -o {}\\bin\\Debug".format(path, path)
with self.solution.log_fs as fs:
shell(cmd, fs)
def build_and_copy(self, path, working_dir):
if exists(join(path, "bin", "Debug")):
rmtree(join(path, "bin", "Debug"))
self.build(path)
name = basename(path)
if not exists(join(path, "bin", "Debug")) or not any(
x.endswith(".exe") for x in listdir(join(path, "bin", "Debug"))
):
return False
self.files.append(basename(path))
for file in listdir(join(path, "bin", "Debug")):
if exists(join(path, "bin", "Debug", file)):
new_file = join(working_dir, basename(file))
try:
copyfile(join(path, "bin", "Debug", file), new_file)
except:
pass
else:
return False
return True
def push(self):
solution = self.solution
if solution.result == "SOLUTION ERROR":
return
solution.result = "IN QUEUE"
solution.save()
from Main.models import System
if len(Solution.objects.filter(result="TESTING")) < int(
System.objects.get(key="queue_size").value
):
self.test()
def delete_everything(self):
ssp = solution_path(self.solution.path())
sln_path = join(ssp, ".idea")
if exists(sln_path):
rmtree(sln_path)
sln_path = join(ssp, ".vs")
if exists(sln_path):
rmtree(sln_path)
sln_path = ssp
for p in listdir(sln_path):
if isdir(join(sln_path, p)):
if exists(join(sln_path, p, "bin")):
rmtree(join(sln_path, p, "bin"))
if exists(join(sln_path, p, "obj")):
rmtree(join(sln_path, p, "obj"))
if exists(self.working_dir):
rmtree(self.working_dir)
if exists(join(self.solution.path(), "solution.zip")):
remove(join(self.solution.path(), "solution.zip"))
if exists(join(self.solution.path(), "__MACOSX")):
rmtree(join(self.solution.path(), "__MACOSX"))
if exists(join(sln_path, ".DS_Store")):
remove(join(sln_path, ".DS_Store"))
if exists(join(sln_path, "test_folder")):
rmtree(join(sln_path, "test_folder"))
def nunit_testing(self):
solution = self.solution
with self.solution.log_fs as fs:
fs.write(b"Building image\n")
shell(
"docker build -t solution_{} {}".format(self.solution.id, self.working_dir)
)
with self.solution.log_fs as fs:
fs.write(b"Image built successfully\n")
def execute():
with self.solution.log_fs as fs:
shell(
"docker run --name solution_container_{} solution_{}".format(
self.solution.id, self.solution.id
),
output=fs,
)
solution.write_log("Running container")
t = Thread(target=execute)
t.start()
t.join(self.solution.task.time_limit / 1000)
solution.write_log("Running finished")
with self.solution.log_fs as fs:
shell(
"docker cp solution_container_{}:/app/TestResults.xml {}".format(
self.solution.id, self.working_dir
),
fs,
)
with self.solution.log_fs as fs:
shell(
"docker rm --force solution_container_{}".format(self.solution.id), fs
)
with self.solution.log_fs as fs:
shell("docker image rm solution_{}".format(self.solution.id), fs)
if not exists(join(self.working_dir, "TestResults.xml")):
self.solution.set_result("Time limit")
solution.write_log("Result file not found in container")
return
solution.write_log("Result file found in container")
try:
doc = parse(join(self.working_dir, "TestResults.xml"))
res = (
get_node_value(doc.getElementsByTagName("Passed"))
+ "/"
+ get_node_value(doc.getElementsByTagName("Total"))
)
self.solution.details = ""
for el in doc.getElementsByTagName("Result"):
self.solution.details += (
"<h5><b>"
+ get_node_value(el.getElementsByTagName("MethodName"))
+ "</b></h5>"
)
r = get_node_value(el.getElementsByTagName("Successful"))
if r == "true":
self.solution.details += '<div style="color: green;">Passed</div>'
else:
self.solution.details += '<div style="color: red;">Failed</div>'
mes = get_node_value(el.getElementsByTagName("Message"))
self.solution.details += "<pre>{}</pre>".format(mes)
except:
solution.write_log("Unknown error")
res = "TEST ERROR"
self.solution.set_result(res)
def test(self):
solution = self.solution
solution.result = "TESTING"
solution.save()
try:
if not exists(self.solution.task.tests_path()):
with self.solution.log_fs as fs:
fs.write(b"No test file found\n")
solution.set_result("TEST ERROR")
solution.save()
self.delete_everything()
start_new(self.host)
return
sln_path = solution_path(join(MEDIA_ROOT, "solutions", str(solution.id)))
if sln_path == "":
solution.set_result("TEST ERROR")
solution.save()
self.delete_everything()
start_new(self.host)
return
working_dir = join(sln_path, "test_folder")
if exists(working_dir):
try:
rmtree(working_dir)
except:
remove(working_dir)
mkdir(working_dir)
with self.solution.log_fs as fs:
fs.write(b"Testing directory created\n")
for project in listdir(sln_path):
solution.write_log("Checking if {} is project".format(project))
prj = project
project = join(sln_path, project)
if (
isdir(project)
and is_project(project)
and basename(project) != "TestsProject"
):
if not self.build_and_copy(project, working_dir):
solution.set_result("Compilation error")
solution.write_log("Failed to compile project {}".format(prj))
solution.save()
self.delete_everything()
start_new(self.host)
return
dll_path = solution.task.tests_path()
solution.write_log("Copying test file to working directory")
copyfile(dll_path, join(working_dir, str(solution.task.id) + ".cs"))
solution.write_log("Test file copied")
for file in listdir("SprintTest"):
try:
copyfile(join("SprintTest", file), join(working_dir, file))
except:
pass
self.working_dir = working_dir
build_tests_cmd = "csc -out:{} -t:library /r:{} /r:{} /r:{} ".format(
join(self.working_dir, "tests.dll"),
join(self.working_dir, "SprintTest.dll"),
join(working_dir, "System.Runtime.dll"),
join(working_dir, "System.Reflection.dll"),
)
for file in self.files:
build_tests_cmd += "/r:{}.dll ".format(join(self.working_dir, file))
build_tests_cmd += self.solution.task.tests_path()
if exists(join(self.working_dir, "tests.dll")):
remove(join(self.working_dir, "tests.dll"))
solution.write_log("Building tests file started")
with self.solution.log_fs as fs:
shell(build_tests_cmd, fs)
with self.solution.log_fs as fs:
fs.write(b"Building tests file finished\n")
if exists(join(self.working_dir, "tests.dll")):
with self.solution.log_fs as fs:
fs.write(b"Got .dll tests file\n")
for file in ExtraFile.objects.filter(task=self.solution.task):
copyfile(file.path, join(working_dir, file.filename))
self.nunit_testing()
else:
solution.set_result("TEST ERROR")
solution.write_log("Failed to compile tests")
except:
solution.set_result("TEST ERROR")
raise
with self.solution.log_fs as fs:
fs.write(b"Unknown error\n")
solution.save()
self.delete_everything()
start_new(self.host)

View File

@ -10,14 +10,19 @@ bot = telebot.TeleBot("1994460106:AAGrGsCZjF6DVG_T-zycELuVfxnWw8x7UyU")
@bot.message_handler(commands=["start"]) @bot.message_handler(commands=["start"])
def do_action(message: Message): def do_action(message: Message):
bot.send_message(message.chat.id, "Привет! Я тут чтобы помогать!\n/register - зарегистрироваться в сервисе\nБольше команд нет:(") bot.send_message(
message.chat.id,
"Привет! Я тут чтобы помогать!\n/register - зарегистрироваться в сервисе\nБольше команд нет:(",
)
@bot.message_handler(commands=["register"]) @bot.message_handler(commands=["register"])
def register(message: Message): def register(message: Message):
username = message.from_user.username username = message.from_user.username
if username == "" or message.from_user.username is None: if username == "" or message.from_user.username is None:
bot.send_message(message.chat.id, "Добавть имя пользователя к своему телеграм аккаунту") bot.send_message(
message.chat.id, "Добавть имя пользователя к своему телеграм аккаунту"
)
return return
ui = UserInfo.objects.filter(telegram_chat_id=message.chat.id).first() ui = UserInfo.objects.filter(telegram_chat_id=message.chat.id).first()
if ui: if ui:
@ -27,21 +32,30 @@ def register(message: Message):
ui = UserInfo.objects.create(user=user, telegram_chat_id=message.chat.id) ui = UserInfo.objects.create(user=user, telegram_chat_id=message.chat.id)
name = message.from_user.first_name name = message.from_user.first_name
surname = message.from_user.last_name surname = message.from_user.last_name
if surname is None or surname == '' or name is None or name == '': if surname is None or surname == "" or name is None or name == "":
bot.send_message(message.chat.id, 'Приветствую в Sprint! Сейчас я помогу тебе создать аккаунт.\nДля начала отправь мне свою фамилию') bot.send_message(
message.chat.id,
"Приветствую в Sprint! Сейчас я помогу тебе создать аккаунт.\nДля начала отправь мне свою фамилию",
)
else: else:
ui.surname = surname ui.surname = surname
ui.name = name ui.name = name
ui.verified = True ui.verified = True
ui.save() ui.save()
bot.send_message(message.chat.id, f"Регистрация завершена! Теперь можешь ты можешь войти в сервис под именем пользователя: {user.username}") bot.send_message(
message.chat.id,
f"Регистрация завершена! Теперь можешь ты можешь войти в сервис под именем пользователя: {user.username}",
)
@bot.message_handler(content_types=["text"]) @bot.message_handler(content_types=["text"])
def do_action(message: Message): def do_action(message: Message):
user = User.objects.filter(userinfo__telegram_chat_id=message.chat.id).first() user = User.objects.filter(userinfo__telegram_chat_id=message.chat.id).first()
if not user: if not user:
bot.send_message(message.chat.id, "Зарегистрируйся в сервисе, чтобы взаимодействовать со мной") bot.send_message(
message.chat.id,
"Зарегистрируйся в сервисе, чтобы взаимодействовать со мной",
)
return return
if user.userinfo.surname is None: if user.userinfo.surname is None:
user.userinfo.surname = message.text user.userinfo.surname = message.text
@ -51,15 +65,18 @@ def do_action(message: Message):
user.userinfo.name = message.text user.userinfo.name = message.text
user.userinfo.verified = True user.userinfo.verified = True
user.userinfo.save() user.userinfo.save()
bot.send_message(message.chat.id, f"Регистрация завершена! Теперь можешь ты можешь войти в сервис под именем пользователя: {user.username}") bot.send_message(
message.chat.id,
f"Регистрация завершена! Теперь можешь ты можешь войти в сервис под именем пользователя: {user.username}",
)
else: else:
bot.send_message(message.chat.id, "Я пока больше ничего не умею") bot.send_message(message.chat.id, "Я пока больше ничего не умею")
class Command(BaseCommand): class Command(BaseCommand):
help = 'starts bot' help = "starts bot"
def handle(self, *args, **options): def handle(self, *args, **options):
print('bot is starting') print("bot is starting")
bot.polling() bot.polling()
print('bot failed') print("bot failed")

View File

@ -9,29 +9,31 @@ from SprintLib.testers import *
class Command(BaseCommand): class Command(BaseCommand):
help = 'Tests solution' help = "Tests solution"
def handle(self, *args, **options): def handle(self, *args, **options):
print("Enter worker") print("Enter worker")
connection = pika.BlockingConnection(pika.ConnectionParameters(host=settings.RABBIT_HOST)) connection = pika.BlockingConnection(
pika.ConnectionParameters(host=settings.RABBIT_HOST)
)
channel = connection.channel() channel = connection.channel()
channel.queue_declare(queue='test') channel.queue_declare(queue="test")
def callback(ch, method, properties, body): def callback(ch, method, properties, body):
try: try:
id = int(str(body, encoding='utf-8')) id = int(str(body, encoding="utf-8"))
print(f"Received id {id}") print(f"Received id {id}")
while True: while True:
try: try:
solution = Solution.objects.get(id=id) solution = Solution.objects.get(id=id)
break break
except: except:
sleep(.5) sleep(0.5)
eval(solution.language.work_name + 'Tester')(solution).execute() eval(solution.language.work_name + "Tester")(solution).execute()
except Exception as e: except Exception as e:
print(e) print(e)
solution.result = 'TE' solution.result = "TE"
solution.save() solution.save()
channel.basic_consume(queue='test', on_message_callback=callback, auto_ack=True) channel.basic_consume(queue="test", on_message_callback=callback, auto_ack=True)
channel.start_consuming() channel.start_consuming()

View File

@ -3,7 +3,7 @@ from FileStorage.root import runserver
class Command(BaseCommand): class Command(BaseCommand):
help = 'starts FileStorage' help = "starts FileStorage"
def handle(self, *args, **options): def handle(self, *args, **options):
runserver() runserver()

View File

@ -25,9 +25,11 @@ class ExtraFile(FileStorageMixin, models.Model):
def delete(self, using=None, keep_parents=False): def delete(self, using=None, keep_parents=False):
self.remove_from_fs() self.remove_from_fs()
if self.is_test and self.filename.endswith('.a'): if self.is_test and self.filename.endswith(".a"):
try: try:
ef = ExtraFile.objects.get(task=self.task, filename=self.filename.rstrip('.a'), is_test=True) ef = ExtraFile.objects.get(
task=self.task, filename=self.filename.rstrip(".a"), is_test=True
)
ef.is_sample = False ef.is_sample = False
ef.save() ef.save()
except ObjectDoesNotExist: except ObjectDoesNotExist:
@ -36,4 +38,6 @@ class ExtraFile(FileStorageMixin, models.Model):
@property @property
def answer(self): def answer(self):
return ExtraFile.objects.get(task=self.task, is_test=True, filename=self.filename + '.a') return ExtraFile.objects.get(
task=self.task, is_test=True, filename=self.filename + ".a"
)

View File

@ -23,4 +23,4 @@ class Set(models.Model):
@property @property
def tasks(self): def tasks(self):
return Task.objects.filter(settasks__set=self).order_by('settasks__name') return Task.objects.filter(settasks__set=self).order_by("settasks__name")

View File

@ -36,23 +36,20 @@ class Solution(models.Model):
text = file.text text = file.text
except: except:
continue continue
entity = { entity = {"filename": file.path, "text": text}
'filename': file.path, end = file.path.split(".")[-1]
'text': text
}
end = file.path.split('.')[-1]
language = None language = None
for l in languages: for l in languages:
if l.file_type == end: if l.file_type == end:
language = l language = l
break break
if language is None: if language is None:
highlight = 'nohighlight' highlight = "nohighlight"
else: else:
highlight = 'language-' + language.highlight highlight = "language-" + language.highlight
entity['highlight'] = highlight entity["highlight"] = highlight
data.append(entity) data.append(entity)
data.sort(key=lambda x: x['filename']) data.sort(key=lambda x: x["filename"])
return data return data
@property @property
@ -67,5 +64,9 @@ class Solution(models.Model):
def volume_directory(self): def volume_directory(self):
return "/sprint-data/worker/" + str(self.id) return "/sprint-data/worker/" + str(self.id)
def exec_command(self, command, working_directory='app', timeout=None): def exec_command(self, command, working_directory="app", timeout=None):
return call(f'docker exec -i solution_{self.id} sh -c "cd {working_directory} && {command}"', shell=True, timeout=timeout) return call(
f'docker exec -i solution_{self.id} sh -c "cd {working_directory} && {command}"',
shell=True,
timeout=timeout,
)

View File

@ -6,4 +6,4 @@ from Main.models.mixins import FileStorageMixin
class SolutionFile(FileStorageMixin, models.Model): class SolutionFile(FileStorageMixin, models.Model):
path = models.TextField() path = models.TextField()
fs_id = models.IntegerField() fs_id = models.IntegerField()
solution = models.ForeignKey('Solution', on_delete=models.CASCADE) solution = models.ForeignKey("Solution", on_delete=models.CASCADE)

View File

@ -29,12 +29,9 @@ class Task(models.Model):
@property @property
def samples(self): def samples(self):
data = [] data = []
for test in self.tests.order_by('test_number'): for test in self.tests.order_by("test_number"):
if test.is_sample and test.readable: if test.is_sample and test.readable:
data.append({ data.append({"input": test.text, "output": test.answer.text})
'input': test.text,
'output': test.answer.text
})
count = 1 count = 1
for entity in data: for entity in data:
entity["num"] = count entity["num"] = count
@ -43,6 +40,7 @@ class Task(models.Model):
def delete(self, using=None, keep_parents=False): def delete(self, using=None, keep_parents=False):
from Main.models.progress import Progress from Main.models.progress import Progress
for progress in Progress.objects.filter(task=self): for progress in Progress.objects.filter(task=self):
progress.user.userinfo.rating -= progress.score progress.user.userinfo.rating -= progress.score
progress.user.userinfo.save() progress.user.userinfo.save()

View File

@ -6,7 +6,7 @@ from django.utils import timezone
def create_token(): def create_token():
symbols = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890' symbols = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
return "".join([choice(symbols) for _ in range(30)]) return "".join([choice(symbols) for _ in range(30)])

View File

@ -29,13 +29,17 @@ class AccountView(BaseView):
def post_set_language(self): def post_set_language(self):
lang_id = int(self.request.POST["language"]) lang_id = int(self.request.POST["language"])
self.request.user.userinfo.favourite_language_id = lang_id if lang_id != -1 else None self.request.user.userinfo.favourite_language_id = (
lang_id if lang_id != -1 else None
)
self.request.user.userinfo.save() self.request.user.userinfo.save()
return "/account" return "/account"
def post_notifications(self): def post_notifications(self):
for attr in dir(self.request.user.userinfo): for attr in dir(self.request.user.userinfo):
if attr.startswith('notification'): if attr.startswith("notification"):
setattr(self.request.user.userinfo, attr, attr in self.request.POST.keys()) setattr(
self.request.user.userinfo, attr, attr in self.request.POST.keys()
)
self.request.user.userinfo.save() self.request.user.userinfo.save()
return '/account' return "/account"

View File

@ -6,5 +6,8 @@ from SprintLib.utils import get_bytes
class ImageView(BaseView): class ImageView(BaseView):
endpoint = "image" endpoint = "image"
def get(self): def get(self):
return HttpResponse(get_bytes(int(self.request.GET['id'])), content_type="image/jpg") return HttpResponse(
get_bytes(int(self.request.GET["id"])), content_type="image/jpg"
)

View File

@ -8,22 +8,31 @@ from random import randrange
class SendCodeView(BaseView): class SendCodeView(BaseView):
endpoint = "send_code" endpoint = "send_code"
def post_create(self): def post_create(self):
username = self.request.POST["username"] username = self.request.POST["username"]
user = User.objects.filter(username=username).first() user = User.objects.filter(username=username).first()
if not user: if not user:
return {"success": False, "message": "Пользователя с таким именем не существует"} return {
"success": False,
"message": "Пользователя с таким именем не существует",
}
code = randrange(10000, 100000) code = randrange(10000, 100000)
user.userinfo.code = code user.userinfo.code = code
user.userinfo.save() user.userinfo.save()
bot.send_message(user.userinfo.telegram_chat_id, "Код для входа в сервис: " + str(code)) bot.send_message(
user.userinfo.telegram_chat_id, "Код для входа в сервис: " + str(code)
)
return {"success": True, "message": "Код отправлен"} return {"success": True, "message": "Код отправлен"}
def post_check(self): def post_check(self):
username = self.request.POST["username"] username = self.request.POST["username"]
user = User.objects.filter(username=username).first() user = User.objects.filter(username=username).first()
if not user: if not user:
return {"success": False, "message": "Пользователя с таким именем не существует"} return {
"success": False,
"message": "Пользователя с таким именем не существует",
}
code = int(self.request.POST["code"]) code = int(self.request.POST["code"])
if code == user.userinfo.code: if code == user.userinfo.code:
user.userinfo.code = None user.userinfo.code = None

View File

@ -3,5 +3,5 @@ from SprintLib.BaseView import BaseView
class SetSettingsView(BaseView): class SetSettingsView(BaseView):
required_login = True required_login = True
view_file = 'set_settings.html' view_file = "set_settings.html"
endpoint = "admin/set" endpoint = "admin/set"

View File

@ -2,7 +2,7 @@ from SprintLib.BaseView import BaseView, AccessError
class SolutionView(BaseView): class SolutionView(BaseView):
view_file = 'solution.html' view_file = "solution.html"
required_login = True required_login = True
endpoint = "solution" endpoint = "solution"

View File

@ -6,17 +6,20 @@ from SprintLib.BaseView import BaseView
class SolutionsTableView(BaseView): class SolutionsTableView(BaseView):
view_file = 'solutions_table.html' view_file = "solutions_table.html"
required_login = True required_login = True
endpoint = "solutions_table" endpoint = "solutions_table"
def get(self): def get(self):
self.context['solutions'] = Solution.objects.filter( self.context["solutions"] = Solution.objects.filter(
user=self.request.user, task=self.entities.task user=self.request.user, task=self.entities.task
).order_by("-time_sent") ).order_by("-time_sent")
if 'render' in self.request.GET.keys(): if "render" in self.request.GET.keys():
return return
for sol in self.context['solutions']: for sol in self.context["solutions"]:
if sol.result == CONSTS['testing_status'] or sol.result == CONSTS['in_queue_status']: if (
sol.result == CONSTS["testing_status"]
or sol.result == CONSTS["in_queue_status"]
):
return return
return HttpResponse('done') return HttpResponse("done")

View File

@ -5,14 +5,14 @@ from SprintLib.BaseView import BaseView
class TaskRuntimeView(BaseView): class TaskRuntimeView(BaseView):
view_file = 'task_runtime.html' view_file = "task_runtime.html"
required_login = True required_login = True
endpoint = "task_runtime" endpoint = "task_runtime"
def get(self): def get(self):
progress = Progress.objects.get(task=self.entities.task, user=self.request.user) progress = Progress.objects.get(task=self.entities.task, user=self.request.user)
self.context['progress'] = progress self.context["progress"] = progress
if 'render' in self.request.GET.keys(): if "render" in self.request.GET.keys():
return return
if progress.finished: if progress.finished:
return HttpResponse('done') return HttpResponse("done")

View File

@ -13,47 +13,49 @@ class TaskSettingsView(BaseView):
def pre_handle(self): def pre_handle(self):
if self.entities.task not in self.request.user.userinfo.available_tasks: if self.entities.task not in self.request.user.userinfo.available_tasks:
raise AccessError() raise AccessError()
if self.request.method == 'POST': if self.request.method == "POST":
for progress in Progress.objects.filter(task=self.entities.task, finished=False): for progress in Progress.objects.filter(
task=self.entities.task, finished=False
):
progress.start_time = timezone.now() progress.start_time = timezone.now()
progress.save() progress.save()
def get(self): def get(self):
self.context['error_message'] = self.request.GET.get('error_message', '') self.context["error_message"] = self.request.GET.get("error_message", "")
def post(self): def post(self):
for key, value in self.request.POST.items(): for key, value in self.request.POST.items():
setattr(self.entities.task, key, value.strip()) setattr(self.entities.task, key, value.strip())
self.entities.task.public = 'public' in self.request.POST self.entities.task.public = "public" in self.request.POST
self.entities.task.save() self.entities.task.save()
return f"/admin/task?task_id={self.entities.task.id}" return f"/admin/task?task_id={self.entities.task.id}"
def _upload(self, is_test): def _upload(self, is_test):
filename = self.request.FILES['file'].name filename = self.request.FILES["file"].name
ef, created = None, None ef, created = None, None
if is_test: if is_test:
name = filename.strip('.a') name = filename.strip(".a")
if not name.isnumeric(): if not name.isnumeric():
return f'/admin/task?task_id={self.entities.task.id}&error_message=Формат файла не соответствует тесту' return f"/admin/task?task_id={self.entities.task.id}&error_message=Формат файла не соответствует тесту"
ef, created = ExtraFile.objects.get_or_create(task=self.entities.task, is_test=True, filename=filename) ef, created = ExtraFile.objects.get_or_create(
task=self.entities.task, is_test=True, filename=filename
)
if not created: if not created:
ef.is_sample = False ef.is_sample = False
ef.save() ef.save()
return f'/admin/task?task_id={self.entities.task.id}' return f"/admin/task?task_id={self.entities.task.id}"
if ef is None or created is None: if ef is None or created is None:
ef, created = ExtraFile.objects.get_or_create( ef, created = ExtraFile.objects.get_or_create(
task=self.entities.task, task=self.entities.task, filename=filename, is_test=is_test
filename=filename,
is_test=is_test
) )
ef.write(self.request.FILES['file'].read()) ef.write(self.request.FILES["file"].read())
try: try:
var = ef.text var = ef.text
ef.readable = True ef.readable = True
except UnicodeDecodeError: except UnicodeDecodeError:
ef.readable = False ef.readable = False
ef.save() ef.save()
return '/admin/task?task_id=' + str(self.entities.task.id) return "/admin/task?task_id=" + str(self.entities.task.id)
def post_file_upload(self): def post_file_upload(self):
return self._upload(False) return self._upload(False)
@ -62,21 +64,23 @@ class TaskSettingsView(BaseView):
return self._upload(True) return self._upload(True)
def post_delete_file(self): def post_delete_file(self):
ef = ExtraFile.objects.get(id=self.request.POST['id']) ef = ExtraFile.objects.get(id=self.request.POST["id"])
ef.delete() ef.delete()
return HttpResponse("ok") return HttpResponse("ok")
def _create(self, is_test): def _create(self, is_test):
name = self.request.POST['newfile_name'] name = self.request.POST["newfile_name"]
ef, created = ExtraFile.objects.get_or_create(filename=name, task=self.entities.task) ef, created = ExtraFile.objects.get_or_create(
filename=name, task=self.entities.task
)
if not created: if not created:
return f'/admin/task?task_id={self.entities.task.id}&error_message=Файл с таким именем уже существует' return f"/admin/task?task_id={self.entities.task.id}&error_message=Файл с таким именем уже существует"
ef.write(b"") ef.write(b"")
ef.is_test = is_test ef.is_test = is_test
ef.readable = True ef.readable = True
ef.save() ef.save()
return f'/admin/task?task_id={self.entities.task.id}' return f"/admin/task?task_id={self.entities.task.id}"
def post_create_file(self): def post_create_file(self):
return self._create(False) return self._create(False)
@ -85,9 +89,9 @@ class TaskSettingsView(BaseView):
return self._create(True) return self._create(True)
def post_save_test(self): def post_save_test(self):
ef = ExtraFile.objects.get(id=self.request.POST['test_id']) ef = ExtraFile.objects.get(id=self.request.POST["test_id"])
ef.remove_from_fs() ef.remove_from_fs()
ef.write(self.request.POST['text'].encode('utf-8')) ef.write(self.request.POST["text"].encode("utf-8"))
ef.is_sample = 'is_sample' in self.request.POST.keys() ef.is_sample = "is_sample" in self.request.POST.keys()
ef.save() ef.save()
return f'/admin/task?task_id={self.entities.task.id}' return f"/admin/task?task_id={self.entities.task.id}"

View File

@ -44,7 +44,7 @@ class TaskView(BaseView):
return "task?task_id=" + str(self.entities.task.id) return "task?task_id=" + str(self.entities.task.id)
filename = self.request.FILES["file"].name filename = self.request.FILES["file"].name
if filename.endswith(".zip"): if filename.endswith(".zip"):
archive = ZipFile(io.BytesIO(self.request.FILES['file'].read())) archive = ZipFile(io.BytesIO(self.request.FILES["file"].read()))
for file in archive.infolist(): for file in archive.infolist():
if file.is_dir(): if file.is_dir():
continue continue
@ -55,7 +55,7 @@ class TaskView(BaseView):
fs_id=fs_id, fs_id=fs_id,
) )
else: else:
fs_id = write_bytes(self.request.FILES['file'].read()) fs_id = write_bytes(self.request.FILES["file"].read())
SolutionFile.objects.create( SolutionFile.objects.create(
path=filename, path=filename,
solution=self.solution, solution=self.solution,

View File

@ -50,7 +50,7 @@ languages = [
file_type="java", file_type="java",
logo_url="https://upload.wikimedia.org/wikipedia/ru/thumb/3/39/Java_logo.svg/1200px-Java_logo.svg.png", logo_url="https://upload.wikimedia.org/wikipedia/ru/thumb/3/39/Java_logo.svg/1200px-Java_logo.svg.png",
image="openjdk", image="openjdk",
highlight="java" highlight="java",
), ),
Language( Language(
id=4, id=4,
@ -59,6 +59,6 @@ languages = [
file_type="cs", file_type="cs",
logo_url="https://cdn.worldvectorlogo.com/logos/c--4.svg", logo_url="https://cdn.worldvectorlogo.com/logos/c--4.svg",
image="mono", image="mono",
highlight="csharp" highlight="csharp",
) ),
] ]

View File

@ -9,4 +9,8 @@ def send_testing(solution_id):
) as connection: ) as connection:
channel = connection.channel() channel = connection.channel()
channel.queue_declare(queue="test") channel.queue_declare(queue="test")
channel.basic_publish(exchange="", routing_key="test", body=bytes(str(solution_id), encoding='utf-8')) channel.basic_publish(
exchange="",
routing_key="test",
body=bytes(str(solution_id), encoding="utf-8"),
)

View File

@ -63,12 +63,16 @@ class BaseTester:
mkdir("solutions") mkdir("solutions")
mkdir("solutions/" + str(self.solution.id)) mkdir("solutions/" + str(self.solution.id))
for file in SolutionFile.objects.filter(solution=self.solution): for file in SolutionFile.objects.filter(solution=self.solution):
dirs = file.path.split('/') dirs = file.path.split("/")
for i in range(len(dirs) - 1): for i in range(len(dirs) - 1):
name = join(str("solutions/" + self.solution.id), '/'.join(dirs[:i + 1])) name = join(
str("solutions/" + self.solution.id), "/".join(dirs[: i + 1])
)
if not exists(name): if not exists(name):
mkdir(name) mkdir(name)
with open(join("solutions/" + str(self.solution.id), file.path), 'wb') as fs: with open(
join("solutions/" + str(self.solution.id), file.path), "wb"
) as fs:
fs.write(get_bytes(file.fs_id)) fs.write(get_bytes(file.fs_id))
self.solution.result = CONSTS["testing_status"] self.solution.result = CONSTS["testing_status"]
self.solution.save() self.solution.save()
@ -77,7 +81,9 @@ class BaseTester:
call(docker_command, shell=True) call(docker_command, shell=True)
print("Container created") print("Container created")
for file in ExtraFile.objects.filter(task=self.solution.task): for file in ExtraFile.objects.filter(task=self.solution.task):
with open(join("solutions/" + str(self.solution.id), file.filename), 'wb') as fs: with open(
join("solutions/" + str(self.solution.id), file.filename), "wb"
) as fs:
fs.write(get_bytes(file.fs_id)) fs.write(get_bytes(file.fs_id))
print("Files copied") print("Files copied")
try: try:

View File

@ -7,13 +7,17 @@ class JavaTester(BaseTester):
_executable = None _executable = None
def before_test(self): def before_test(self):
files = [file for file in listdir(self.solution.testing_directory) if file.endswith('.java')] files = [
file
for file in listdir(self.solution.testing_directory)
if file.endswith(".java")
]
code = self.solution.exec_command(f"javac {' '.join(files)}") code = self.solution.exec_command(f"javac {' '.join(files)}")
if code != 0: if code != 0:
raise TestException('CE') raise TestException("CE")
for file in listdir(self.solution.testing_directory): for file in listdir(self.solution.testing_directory):
if file.endswith('.class'): if file.endswith(".class"):
self._executable = file.rstrip('.class') self._executable = file.rstrip(".class")
break break
if self._executable is None: if self._executable is None:
raise TestException("TE") raise TestException("TE")

View File

@ -5,10 +5,16 @@ from SprintLib.testers.BaseTester import BaseTester, TestException
class KotlinTester(BaseTester): class KotlinTester(BaseTester):
def before_test(self): def before_test(self):
files = [file for file in listdir(self.solution.testing_directory) if file.endswith('.kt')] files = [
code = self.solution.exec_command(f'kotlinc {" ".join(files)} -include-runtime -d solution.jar') file
for file in listdir(self.solution.testing_directory)
if file.endswith(".kt")
]
code = self.solution.exec_command(
f'kotlinc {" ".join(files)} -include-runtime -d solution.jar'
)
if code != 0: if code != 0:
raise TestException('CE') raise TestException("CE")
@property @property
def command(self): def command(self):

View File

@ -6,7 +6,7 @@ from Sprint import settings
def write_bytes(data): def write_bytes(data):
url = settings.FS_HOST + ":" + str(settings.FS_PORT) + "/upload_file" url = settings.FS_HOST + ":" + str(settings.FS_PORT) + "/upload_file"
print(url) print(url)
return post(url, data=data).json()['id'] return post(url, data=data).json()["id"]
def get_bytes(num): def get_bytes(num):