checkpoint

This commit is contained in:
Egor Matveev
2021-09-05 15:28:24 +03:00
parent 1307c16ec1
commit 807c52bf2b
30 changed files with 394 additions and 26 deletions

View File

@@ -8,3 +8,4 @@ from Main.models.settask import SetTask
from Main.models.solution import Solution
from Main.models.language import Language
from Main.models.extrafile import ExtraFile
from Main.models.progress import Progress

View File

@@ -1,27 +1,50 @@
from os import remove
from os.path import join, exists
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from Sprint.settings import DATA_ROOT
class ExtraFile(models.Model):
task = models.ForeignKey('Task', on_delete=models.CASCADE)
task = models.ForeignKey("Task", on_delete=models.CASCADE)
filename = models.TextField()
is_test = models.BooleanField(null=True)
is_sample = models.BooleanField(null=True)
readable = models.BooleanField(null=True)
test_number = models.IntegerField(null=True)
@property
def path(self):
return join(DATA_ROOT, 'extra_files', str(self.id))
return join(DATA_ROOT, "extra_files", str(self.id))
@property
def can_be_sample(self):
return (
self.is_test
and not self.filename.endswith(".a")
and len(
ExtraFile.objects.filter(task=self.task, filename=self.filename + ".a")
)
)
@property
def text(self):
return open(self.path, 'r').read()
return open(self.path, "r").read()
def delete(self, using=None, keep_parents=False):
if exists(self.path):
remove(self.path)
if self.is_test and self.filename.endswith('.a'):
try:
ef = ExtraFile.objects.get(task=self.task, filename=self.filename.rstrip('.a'), is_test=True)
ef.is_sample = False
ef.save()
except ObjectDoesNotExist:
pass
super().delete(using=using, keep_parents=keep_parents)
@property
def answer(self):
return ExtraFile.objects.get(task=self.task, is_test=True, filename=self.filename + '.a')

View File

@@ -7,6 +7,7 @@ class Language(models.Model):
file_type = models.TextField(null=True)
logo = models.ImageField(upload_to="logos", null=True)
image = models.TextField(default='ubuntu')
highlight = models.TextField(default='plaintext')
opened = models.BooleanField(default=False)
def __str__(self):

35
Main/models/progress.py Normal file
View File

@@ -0,0 +1,35 @@
from datetime import timedelta
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
from Main.models import Task
class Progress(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
task = models.ForeignKey(Task, on_delete=models.CASCADE)
start_time = models.DateTimeField(default=timezone.now)
finished_time = models.DateTimeField(null=True)
score = models.IntegerField(default=0)
finished = models.BooleanField(default=False)
@property
def time(self):
if not self.finished:
self.finished_time = timezone.now()
return self.finished_time - self.start_time
def increment_rating(self):
if self.task.creator == self.user:
return
delta = timedelta(minutes=self.task.time_estimation)
self.score = int(delta / self.time * 100)
self.save()
self.user.userinfo.rating += self.score
self.user.userinfo.save()
@staticmethod
def by_solution(solution):
return Progress.objects.get(task=solution.task, user=solution.user)

View File

@@ -1,8 +1,20 @@
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
class Set(models.Model):
name = models.TextField()
public = models.BooleanField(default=False)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
opened = models.BooleanField(default=False)
start_time = models.DateTimeField(default=timezone.now)
end_time = models.DateTimeField(default=timezone.now)
@property
def available(self):
return (
self.opened
and (self.start_time is None or timezone.now() >= self.start_time)
and (self.end_time is None or timezone.now() <= self.end_time)
)

View File

@@ -1,9 +1,10 @@
from os import mkdir
from os import mkdir, walk
from os.path import join, exists
from shutil import rmtree
from subprocess import call
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.utils import timezone
@@ -24,6 +25,30 @@ class Solution(models.Model):
rmtree(self.directory)
super().delete(using=using, keep_parents=keep_parents)
@property
def files(self):
data = []
for path, _, files in walk(self.directory):
if path.startswith(self.testing_directory):
continue
for file in files:
try:
entity = {
'filename': file,
'text': open(join(path, file), 'r').read()
}
end = file.split('.')[-1]
try:
highlight = 'language-' + Language.objects.get(file_type=end).highlight
except ObjectDoesNotExist:
highlight = 'nohighlight'
entity['highlight'] = highlight
data.append(entity)
except:
continue
data.sort(key=lambda x: x['filename'])
return data
def create_dirs(self):
mkdir(self.directory)
mkdir(self.testing_directory)

View File

@@ -12,6 +12,7 @@ class Task(models.Model):
output_format = models.TextField(default="")
specifications = models.TextField(default="")
time_limit = models.IntegerField(default=10000)
time_estimation = models.IntegerField(default=5)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
def __str__(self):
@@ -24,3 +25,25 @@ class Task(models.Model):
@property
def tests(self):
return ExtraFile.objects.filter(task=self, is_test=True)
@property
def samples(self):
data = []
for test in self.tests.order_by('test_number'):
if test.is_sample and test.readable:
data.append({
'input': test.text,
'output': test.answer.text
})
count = 1
for entity in data:
entity["num"] = count
count += 1
return data
def delete(self, using=None, keep_parents=False):
from Main.models.progress import Progress
for progress in Progress.objects.filter(task=self):
progress.user.userinfo.rating -= progress.score
progress.user.userinfo.save()
super().delete(using=using, keep_parents=keep_parents)

View File

@@ -17,6 +17,8 @@ class UserInfo(models.Model):
profile_picture = models.ImageField(upload_to="profile_pictures", null=True)
rating = models.IntegerField(default=0)
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
telegram_chat_id = models.TextField(default="")
notification_solution_result = models.BooleanField(default=False)
def _append_task(self, task, tasks):
if task.creator == self.user or task.public: