87 lines
2.9 KiB
Python
87 lines
2.9 KiB
Python
from celery import shared_task
|
|
from django.conf import settings
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
from django.utils.translation import gettext as _
|
|
from moss import MOSS
|
|
|
|
from judge.models import Contest, ContestMoss, ContestParticipation, Submission
|
|
from judge.utils.celery import Progress
|
|
|
|
__all__ = ("rescore_contest", "run_moss")
|
|
|
|
|
|
@shared_task(bind=True)
|
|
def rescore_contest(self, contest_key):
|
|
contest = Contest.objects.get(key=contest_key)
|
|
participations = contest.users
|
|
|
|
rescored = 0
|
|
with Progress(
|
|
self, participations.count(), stage=_("Recalculating contest scores")
|
|
) as p:
|
|
for participation in participations.iterator():
|
|
participation.recompute_results()
|
|
rescored += 1
|
|
if rescored % 10 == 0:
|
|
p.done = rescored
|
|
return rescored
|
|
|
|
|
|
@shared_task(bind=True)
|
|
def run_moss(self, contest_key):
|
|
moss_api_key = settings.MOSS_API_KEY
|
|
if moss_api_key is None:
|
|
raise ImproperlyConfigured("No MOSS API Key supplied")
|
|
|
|
contest = Contest.objects.get(key=contest_key)
|
|
ContestMoss.objects.filter(contest=contest).delete()
|
|
|
|
length = len(ContestMoss.LANG_MAPPING) * contest.problems.count()
|
|
moss_results = []
|
|
|
|
with Progress(self, length, stage=_("Running MOSS")) as p:
|
|
for problem in contest.problems.all():
|
|
for dmoj_lang, moss_lang in ContestMoss.LANG_MAPPING:
|
|
result = ContestMoss(
|
|
contest=contest, problem=problem, language=dmoj_lang
|
|
)
|
|
|
|
subs = (
|
|
Submission.objects.filter(
|
|
contest__participation__virtual__in=(
|
|
ContestParticipation.LIVE,
|
|
ContestParticipation.SPECTATE,
|
|
),
|
|
contest_object=contest,
|
|
problem=problem,
|
|
language__common_name=dmoj_lang,
|
|
)
|
|
.order_by("-points")
|
|
.values_list("user__user__username", "source__source")
|
|
)
|
|
|
|
if subs.exists():
|
|
moss_call = MOSS(
|
|
moss_api_key,
|
|
language=moss_lang,
|
|
matching_file_limit=100,
|
|
comment="%s - %s" % (contest.key, problem.code),
|
|
)
|
|
|
|
users = set()
|
|
|
|
for username, source in subs:
|
|
if username in users:
|
|
continue
|
|
users.add(username)
|
|
moss_call.add_file_from_memory(username, source.encode("utf-8"))
|
|
|
|
result.url = moss_call.process()
|
|
result.submission_count = len(users)
|
|
|
|
moss_results.append(result)
|
|
p.did(1)
|
|
|
|
ContestMoss.objects.bulk_create(moss_results)
|
|
|
|
return len(moss_results)
|