Reformat using black
This commit is contained in:
parent
efee4ad081
commit
a87fb49918
221 changed files with 19127 additions and 7310 deletions
|
@ -14,92 +14,130 @@ from judge.models.profile import Profile
|
|||
from judge.models.runtime import Language
|
||||
from judge.utils.unicode import utf8bytes
|
||||
|
||||
__all__ = ['SUBMISSION_RESULT', 'Submission', 'SubmissionSource', 'SubmissionTestCase']
|
||||
__all__ = ["SUBMISSION_RESULT", "Submission", "SubmissionSource", "SubmissionTestCase"]
|
||||
|
||||
SUBMISSION_RESULT = (
|
||||
('AC', _('Accepted')),
|
||||
('WA', _('Wrong Answer')),
|
||||
('TLE', _('Time Limit Exceeded')),
|
||||
('MLE', _('Memory Limit Exceeded')),
|
||||
('OLE', _('Output Limit Exceeded')),
|
||||
('IR', _('Invalid Return')),
|
||||
('RTE', _('Runtime Error')),
|
||||
('CE', _('Compile Error')),
|
||||
('IE', _('Internal Error')),
|
||||
('SC', _('Short circuit')),
|
||||
('AB', _('Aborted')),
|
||||
("AC", _("Accepted")),
|
||||
("WA", _("Wrong Answer")),
|
||||
("TLE", _("Time Limit Exceeded")),
|
||||
("MLE", _("Memory Limit Exceeded")),
|
||||
("OLE", _("Output Limit Exceeded")),
|
||||
("IR", _("Invalid Return")),
|
||||
("RTE", _("Runtime Error")),
|
||||
("CE", _("Compile Error")),
|
||||
("IE", _("Internal Error")),
|
||||
("SC", _("Short circuit")),
|
||||
("AB", _("Aborted")),
|
||||
)
|
||||
|
||||
|
||||
class Submission(models.Model):
|
||||
STATUS = (
|
||||
('QU', _('Queued')),
|
||||
('P', _('Processing')),
|
||||
('G', _('Grading')),
|
||||
('D', _('Completed')),
|
||||
('IE', _('Internal Error')),
|
||||
('CE', _('Compile Error')),
|
||||
('AB', _('Aborted')),
|
||||
("QU", _("Queued")),
|
||||
("P", _("Processing")),
|
||||
("G", _("Grading")),
|
||||
("D", _("Completed")),
|
||||
("IE", _("Internal Error")),
|
||||
("CE", _("Compile Error")),
|
||||
("AB", _("Aborted")),
|
||||
)
|
||||
IN_PROGRESS_GRADING_STATUS = ('QU', 'P', 'G')
|
||||
IN_PROGRESS_GRADING_STATUS = ("QU", "P", "G")
|
||||
RESULT = SUBMISSION_RESULT
|
||||
USER_DISPLAY_CODES = {
|
||||
'AC': _('Accepted'),
|
||||
'WA': _('Wrong Answer'),
|
||||
'SC': "Short Circuited",
|
||||
'TLE': _('Time Limit Exceeded'),
|
||||
'MLE': _('Memory Limit Exceeded'),
|
||||
'OLE': _('Output Limit Exceeded'),
|
||||
'IR': _('Invalid Return'),
|
||||
'RTE': _('Runtime Error'),
|
||||
'CE': _('Compile Error'),
|
||||
'IE': _('Internal Error (judging server error)'),
|
||||
'QU': _('Queued'),
|
||||
'P': _('Processing'),
|
||||
'G': _('Grading'),
|
||||
'D': _('Completed'),
|
||||
'AB': _('Aborted'),
|
||||
"AC": _("Accepted"),
|
||||
"WA": _("Wrong Answer"),
|
||||
"SC": "Short Circuited",
|
||||
"TLE": _("Time Limit Exceeded"),
|
||||
"MLE": _("Memory Limit Exceeded"),
|
||||
"OLE": _("Output Limit Exceeded"),
|
||||
"IR": _("Invalid Return"),
|
||||
"RTE": _("Runtime Error"),
|
||||
"CE": _("Compile Error"),
|
||||
"IE": _("Internal Error (judging server error)"),
|
||||
"QU": _("Queued"),
|
||||
"P": _("Processing"),
|
||||
"G": _("Grading"),
|
||||
"D": _("Completed"),
|
||||
"AB": _("Aborted"),
|
||||
}
|
||||
|
||||
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
|
||||
problem = models.ForeignKey(Problem, on_delete=models.CASCADE)
|
||||
date = models.DateTimeField(verbose_name=_('submission time'), auto_now_add=True, db_index=True)
|
||||
time = models.FloatField(verbose_name=_('execution time'), null=True, db_index=True)
|
||||
memory = models.FloatField(verbose_name=_('memory usage'), null=True)
|
||||
points = models.FloatField(verbose_name=_('points granted'), null=True, db_index=True)
|
||||
language = models.ForeignKey(Language, verbose_name=_('submission language'), on_delete=models.CASCADE)
|
||||
status = models.CharField(verbose_name=_('status'), max_length=2, choices=STATUS, default='QU', db_index=True)
|
||||
result = models.CharField(verbose_name=_('result'), max_length=3, choices=SUBMISSION_RESULT,
|
||||
default=None, null=True, blank=True, db_index=True)
|
||||
error = models.TextField(verbose_name=_('compile errors'), null=True, blank=True)
|
||||
date = models.DateTimeField(
|
||||
verbose_name=_("submission time"), auto_now_add=True, db_index=True
|
||||
)
|
||||
time = models.FloatField(verbose_name=_("execution time"), null=True, db_index=True)
|
||||
memory = models.FloatField(verbose_name=_("memory usage"), null=True)
|
||||
points = models.FloatField(
|
||||
verbose_name=_("points granted"), null=True, db_index=True
|
||||
)
|
||||
language = models.ForeignKey(
|
||||
Language, verbose_name=_("submission language"), on_delete=models.CASCADE
|
||||
)
|
||||
status = models.CharField(
|
||||
verbose_name=_("status"),
|
||||
max_length=2,
|
||||
choices=STATUS,
|
||||
default="QU",
|
||||
db_index=True,
|
||||
)
|
||||
result = models.CharField(
|
||||
verbose_name=_("result"),
|
||||
max_length=3,
|
||||
choices=SUBMISSION_RESULT,
|
||||
default=None,
|
||||
null=True,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
)
|
||||
error = models.TextField(verbose_name=_("compile errors"), null=True, blank=True)
|
||||
current_testcase = models.IntegerField(default=0)
|
||||
batch = models.BooleanField(verbose_name=_('batched cases'), default=False)
|
||||
case_points = models.FloatField(verbose_name=_('test case points'), default=0)
|
||||
case_total = models.FloatField(verbose_name=_('test case total points'), default=0)
|
||||
judged_on = models.ForeignKey('Judge', verbose_name=_('judged on'), null=True, blank=True,
|
||||
on_delete=models.SET_NULL)
|
||||
judged_date = models.DateTimeField(verbose_name=_('submission judge time'), default=None, null=True)
|
||||
was_rejudged = models.BooleanField(verbose_name=_('was rejudged by admin'), default=False)
|
||||
is_pretested = models.BooleanField(verbose_name=_('was ran on pretests only'), default=False)
|
||||
contest_object = models.ForeignKey('Contest', verbose_name=_('contest'), null=True, blank=True,
|
||||
on_delete=models.SET_NULL, related_name='+')
|
||||
batch = models.BooleanField(verbose_name=_("batched cases"), default=False)
|
||||
case_points = models.FloatField(verbose_name=_("test case points"), default=0)
|
||||
case_total = models.FloatField(verbose_name=_("test case total points"), default=0)
|
||||
judged_on = models.ForeignKey(
|
||||
"Judge",
|
||||
verbose_name=_("judged on"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
judged_date = models.DateTimeField(
|
||||
verbose_name=_("submission judge time"), default=None, null=True
|
||||
)
|
||||
was_rejudged = models.BooleanField(
|
||||
verbose_name=_("was rejudged by admin"), default=False
|
||||
)
|
||||
is_pretested = models.BooleanField(
|
||||
verbose_name=_("was ran on pretests only"), default=False
|
||||
)
|
||||
contest_object = models.ForeignKey(
|
||||
"Contest",
|
||||
verbose_name=_("contest"),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="+",
|
||||
)
|
||||
|
||||
objects = TranslatedProblemForeignKeyQuerySet.as_manager()
|
||||
|
||||
@classmethod
|
||||
def result_class_from_code(cls, result, case_points, case_total):
|
||||
if result == 'AC':
|
||||
if result == "AC":
|
||||
if case_points == case_total:
|
||||
return 'AC'
|
||||
return '_AC'
|
||||
return "AC"
|
||||
return "_AC"
|
||||
return result
|
||||
|
||||
@property
|
||||
def result_class(self):
|
||||
# This exists to save all these conditionals from being executed (slowly) in each row.jade template
|
||||
if self.status in ('IE', 'CE'):
|
||||
if self.status in ("IE", "CE"):
|
||||
return self.status
|
||||
return Submission.result_class_from_code(self.result, self.case_points, self.case_total)
|
||||
return Submission.result_class_from_code(
|
||||
self.result, self.case_points, self.case_total
|
||||
)
|
||||
|
||||
@property
|
||||
def memory_bytes(self):
|
||||
|
@ -111,12 +149,11 @@ class Submission(models.Model):
|
|||
|
||||
@property
|
||||
def long_status(self):
|
||||
return Submission.USER_DISPLAY_CODES.get(self.short_status, '')
|
||||
return Submission.USER_DISPLAY_CODES.get(self.short_status, "")
|
||||
|
||||
def judge(self, *args, **kwargs):
|
||||
judge_submission(self, *args, **kwargs)
|
||||
|
||||
|
||||
judge.alters_data = True
|
||||
|
||||
def abort(self):
|
||||
|
@ -131,8 +168,12 @@ class Submission(models.Model):
|
|||
return
|
||||
|
||||
contest_problem = contest.problem
|
||||
contest.points = round(self.case_points / self.case_total * contest_problem.points
|
||||
if self.case_total > 0 else 0, 3)
|
||||
contest.points = round(
|
||||
self.case_points / self.case_total * contest_problem.points
|
||||
if self.case_total > 0
|
||||
else 0,
|
||||
3,
|
||||
)
|
||||
if not contest_problem.partial and contest.points != contest_problem.points:
|
||||
contest.points = 0
|
||||
contest.save()
|
||||
|
@ -142,18 +183,22 @@ class Submission(models.Model):
|
|||
|
||||
@property
|
||||
def is_graded(self):
|
||||
return self.status not in ('QU', 'P', 'G')
|
||||
return self.status not in ("QU", "P", "G")
|
||||
|
||||
@cached_property
|
||||
def contest_key(self):
|
||||
if hasattr(self, 'contest'):
|
||||
if hasattr(self, "contest"):
|
||||
return self.contest_object.key
|
||||
|
||||
def __str__(self):
|
||||
return 'Submission %d of %s by %s' % (self.id, self.problem, self.user.user.username)
|
||||
return "Submission %d of %s by %s" % (
|
||||
self.id,
|
||||
self.problem,
|
||||
self.user.user.username,
|
||||
)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('submission_status', args=(self.id,))
|
||||
return reverse("submission_status", args=(self.id,))
|
||||
|
||||
@cached_property
|
||||
def contest_or_none(self):
|
||||
|
@ -164,8 +209,14 @@ class Submission(models.Model):
|
|||
|
||||
@classmethod
|
||||
def get_id_secret(cls, sub_id):
|
||||
return (hmac.new(utf8bytes(settings.EVENT_DAEMON_SUBMISSION_KEY), b'%d' % sub_id, hashlib.sha512)
|
||||
.hexdigest()[:16] + '%08x' % sub_id)
|
||||
return (
|
||||
hmac.new(
|
||||
utf8bytes(settings.EVENT_DAEMON_SUBMISSION_KEY),
|
||||
b"%d" % sub_id,
|
||||
hashlib.sha512,
|
||||
).hexdigest()[:16]
|
||||
+ "%08x" % sub_id
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def id_secret(self):
|
||||
|
@ -173,47 +224,61 @@ class Submission(models.Model):
|
|||
|
||||
class Meta:
|
||||
permissions = (
|
||||
('abort_any_submission', 'Abort any submission'),
|
||||
('rejudge_submission', 'Rejudge the submission'),
|
||||
('rejudge_submission_lot', 'Rejudge a lot of submissions'),
|
||||
('spam_submission', 'Submit without limit'),
|
||||
('view_all_submission', 'View all submission'),
|
||||
('resubmit_other', "Resubmit others' submission"),
|
||||
("abort_any_submission", "Abort any submission"),
|
||||
("rejudge_submission", "Rejudge the submission"),
|
||||
("rejudge_submission_lot", "Rejudge a lot of submissions"),
|
||||
("spam_submission", "Submit without limit"),
|
||||
("view_all_submission", "View all submission"),
|
||||
("resubmit_other", "Resubmit others' submission"),
|
||||
)
|
||||
verbose_name = _('submission')
|
||||
verbose_name_plural = _('submissions')
|
||||
verbose_name = _("submission")
|
||||
verbose_name_plural = _("submissions")
|
||||
|
||||
|
||||
class SubmissionSource(models.Model):
|
||||
submission = models.OneToOneField(Submission, on_delete=models.CASCADE, verbose_name=_('associated submission'),
|
||||
related_name='source')
|
||||
source = models.TextField(verbose_name=_('source code'), max_length=65536)
|
||||
submission = models.OneToOneField(
|
||||
Submission,
|
||||
on_delete=models.CASCADE,
|
||||
verbose_name=_("associated submission"),
|
||||
related_name="source",
|
||||
)
|
||||
source = models.TextField(verbose_name=_("source code"), max_length=65536)
|
||||
|
||||
def __str__(self):
|
||||
return 'Source of %s' % self.submission
|
||||
return "Source of %s" % self.submission
|
||||
|
||||
|
||||
class SubmissionTestCase(models.Model):
|
||||
RESULT = SUBMISSION_RESULT
|
||||
|
||||
submission = models.ForeignKey(Submission, verbose_name=_('associated submission'),
|
||||
related_name='test_cases', on_delete=models.CASCADE)
|
||||
case = models.IntegerField(verbose_name=_('test case ID'))
|
||||
status = models.CharField(max_length=3, verbose_name=_('status flag'), choices=SUBMISSION_RESULT)
|
||||
time = models.FloatField(verbose_name=_('execution time'), null=True)
|
||||
memory = models.FloatField(verbose_name=_('memory usage'), null=True)
|
||||
points = models.FloatField(verbose_name=_('points granted'), null=True)
|
||||
total = models.FloatField(verbose_name=_('points possible'), null=True)
|
||||
batch = models.IntegerField(verbose_name=_('batch number'), null=True)
|
||||
feedback = models.CharField(max_length=50, verbose_name=_('judging feedback'), blank=True)
|
||||
extended_feedback = models.TextField(verbose_name=_('extended judging feedback'), blank=True)
|
||||
output = models.TextField(verbose_name=_('program output'), blank=True)
|
||||
submission = models.ForeignKey(
|
||||
Submission,
|
||||
verbose_name=_("associated submission"),
|
||||
related_name="test_cases",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
case = models.IntegerField(verbose_name=_("test case ID"))
|
||||
status = models.CharField(
|
||||
max_length=3, verbose_name=_("status flag"), choices=SUBMISSION_RESULT
|
||||
)
|
||||
time = models.FloatField(verbose_name=_("execution time"), null=True)
|
||||
memory = models.FloatField(verbose_name=_("memory usage"), null=True)
|
||||
points = models.FloatField(verbose_name=_("points granted"), null=True)
|
||||
total = models.FloatField(verbose_name=_("points possible"), null=True)
|
||||
batch = models.IntegerField(verbose_name=_("batch number"), null=True)
|
||||
feedback = models.CharField(
|
||||
max_length=50, verbose_name=_("judging feedback"), blank=True
|
||||
)
|
||||
extended_feedback = models.TextField(
|
||||
verbose_name=_("extended judging feedback"), blank=True
|
||||
)
|
||||
output = models.TextField(verbose_name=_("program output"), blank=True)
|
||||
|
||||
@property
|
||||
def long_status(self):
|
||||
return Submission.USER_DISPLAY_CODES.get(self.status, '')
|
||||
return Submission.USER_DISPLAY_CODES.get(self.status, "")
|
||||
|
||||
class Meta:
|
||||
unique_together = ('submission', 'case')
|
||||
verbose_name = _('submission test case')
|
||||
verbose_name_plural = _('submission test cases')
|
||||
unique_together = ("submission", "case")
|
||||
verbose_name = _("submission test case")
|
||||
verbose_name_plural = _("submission test cases")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue