2020-01-21 06:35:58 +00:00
|
|
|
from django.conf import settings
|
|
|
|
from django.core.management.base import BaseCommand
|
|
|
|
from moss import *
|
|
|
|
|
|
|
|
from judge.models import Contest, ContestParticipation, Submission
|
|
|
|
|
|
|
|
|
|
|
|
class Command(BaseCommand):
|
2022-05-14 17:57:27 +00:00
|
|
|
help = "Checks for duplicate code using MOSS"
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
LANG_MAPPING = {
|
2022-05-14 17:57:27 +00:00
|
|
|
("C++", MOSS_LANG_CC),
|
|
|
|
("C", MOSS_LANG_C),
|
|
|
|
("Java", MOSS_LANG_JAVA),
|
|
|
|
("Python", MOSS_LANG_PYTHON),
|
|
|
|
("Pascal", MOSS_LANG_PASCAL),
|
2020-01-21 06:35:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def add_arguments(self, parser):
|
2022-05-14 17:57:27 +00:00
|
|
|
parser.add_argument("contest", help="the id of the contest")
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def handle(self, *args, **options):
|
|
|
|
moss_api_key = settings.MOSS_API_KEY
|
|
|
|
if moss_api_key is None:
|
2022-05-14 17:57:27 +00:00
|
|
|
print("No MOSS API Key supplied")
|
2020-01-21 06:35:58 +00:00
|
|
|
return
|
2022-05-14 17:57:27 +00:00
|
|
|
contest = options["contest"]
|
2020-01-21 06:35:58 +00:00
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
for problem in Contest.objects.get(key=contest).problems.order_by("code"):
|
|
|
|
print("========== %s / %s ==========" % (problem.code, problem.name))
|
2020-01-21 06:35:58 +00:00
|
|
|
for dmoj_lang, moss_lang in self.LANG_MAPPING:
|
2022-05-14 17:57:27 +00:00
|
|
|
print("%s: " % dmoj_lang, end=" ")
|
2020-01-21 06:35:58 +00:00
|
|
|
subs = Submission.objects.filter(
|
2022-05-14 17:57:27 +00:00
|
|
|
contest__participation__virtual__in=(
|
|
|
|
ContestParticipation.LIVE,
|
|
|
|
ContestParticipation.SPECTATE,
|
|
|
|
),
|
2020-01-21 06:35:58 +00:00
|
|
|
contest__participation__contest__key=contest,
|
2022-05-14 17:57:27 +00:00
|
|
|
result="AC",
|
|
|
|
problem__id=problem.id,
|
2020-01-21 06:35:58 +00:00
|
|
|
language__common_name=dmoj_lang,
|
2022-05-14 17:57:27 +00:00
|
|
|
).values_list("user__user__username", "source__source")
|
2020-01-21 06:35:58 +00:00
|
|
|
if not subs:
|
2022-05-14 17:57:27 +00:00
|
|
|
print("<no submissions>")
|
2020-01-21 06:35:58 +00:00
|
|
|
continue
|
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
moss_call = MOSS(
|
|
|
|
moss_api_key,
|
|
|
|
language=moss_lang,
|
|
|
|
matching_file_limit=100,
|
|
|
|
comment="%s - %s" % (contest, problem.code),
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
users = set()
|
|
|
|
|
|
|
|
for username, source in subs:
|
|
|
|
if username in users:
|
|
|
|
continue
|
|
|
|
users.add(username)
|
2022-05-14 17:57:27 +00:00
|
|
|
moss_call.add_file_from_memory(username, source.encode("utf-8"))
|
2020-01-21 06:35:58 +00:00
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
print("(%d): %s" % (subs.count(), moss_call.process()))
|