from cached_property import cached_property from django.contrib.postgres.fields import ArrayField from django.db import models from django.contrib.auth.models import User from django.db.models import JSONField from Main.models.dump import Dump from Main.models.extrafile import ExtraFile class Task(models.Model): name = models.TextField() public = models.BooleanField(default=False) legend = models.TextField(default="") input_format = models.TextField(default="") output_format = models.TextField(default="") specifications = models.TextField(default="") time_limit = models.IntegerField(default=10000) memory_limit = models.IntegerField(default=524288) time_estimation = models.IntegerField(default=5) creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) editors = ArrayField(models.TextField(), default=list) allow_sharing = models.BooleanField(default=False) changes = JSONField(default=list) _extrafiles = None def __str__(self): return self.name @property def dumps(self): return Dump.objects.filter(task=self).order_by("-timestamp") @property def files(self): return ExtraFile.objects.filter(task=self, is_test=False) @property def tests(self): for file in sorted(self.extrafiles, key=lambda x: x.filename): if file.filename.isnumeric() or file.filename.endswith('.a') and file.filename[:-2].isnumeric(): yield file @property def extrafiles(self): if self._extrafiles is not None: return self._extrafiles return ExtraFile.objects.filter(task=self) @extrafiles.setter def extrafiles(self, value): self._extrafiles = value @property def dockerfiles(self): for file in self.extrafiles: if file.filename.startswith('Dockerfile_'): yield file @cached_property def checkerfile(self): for file in self.extrafiles: if file.filename == 'extrafile.py': return file return None @property def tests_count(self): return len(list(self.tests)) // 2 @property def samples(self): data = [] for test in self.tests: 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)