Reformat using black
This commit is contained in:
parent
efee4ad081
commit
a87fb49918
221 changed files with 19127 additions and 7310 deletions
|
@ -4,15 +4,14 @@ from judge.models import Judge
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'create a judge'
|
||||
help = "create a judge"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('name', help='the name of the judge')
|
||||
parser.add_argument('auth_key', help='authentication key for the judge')
|
||||
parser.add_argument("name", help="the name of the judge")
|
||||
parser.add_argument("auth_key", help="authentication key for the judge")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
judge = Judge()
|
||||
judge.name = options['name']
|
||||
judge.auth_key = options['auth_key']
|
||||
judge.name = options["name"]
|
||||
judge.auth_key = options["auth_key"]
|
||||
judge.save()
|
||||
|
||||
|
|
|
@ -6,27 +6,39 @@ from judge.models import Language, Profile
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'creates a user'
|
||||
help = "creates a user"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('name', help='username')
|
||||
parser.add_argument('email', help='email, not necessary to be resolvable')
|
||||
parser.add_argument('password', help='password for the user')
|
||||
parser.add_argument('language', nargs='?', default=settings.DEFAULT_USER_LANGUAGE,
|
||||
help='default language ID for user')
|
||||
parser.add_argument("name", help="username")
|
||||
parser.add_argument("email", help="email, not necessary to be resolvable")
|
||||
parser.add_argument("password", help="password for the user")
|
||||
parser.add_argument(
|
||||
"language",
|
||||
nargs="?",
|
||||
default=settings.DEFAULT_USER_LANGUAGE,
|
||||
help="default language ID for user",
|
||||
)
|
||||
|
||||
parser.add_argument('--superuser', action='store_true', default=False,
|
||||
help="if specified, creates user with superuser privileges")
|
||||
parser.add_argument('--staff', action='store_true', default=False,
|
||||
help="if specified, creates user with staff privileges")
|
||||
parser.add_argument(
|
||||
"--superuser",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="if specified, creates user with superuser privileges",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--staff",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="if specified, creates user with staff privileges",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
usr = User(username=options['name'], email=options['email'], is_active=True)
|
||||
usr.set_password(options['password'])
|
||||
usr.is_superuser = options['superuser']
|
||||
usr.is_staff = options['staff']
|
||||
usr = User(username=options["name"], email=options["email"], is_active=True)
|
||||
usr.set_password(options["password"])
|
||||
usr.is_superuser = options["superuser"]
|
||||
usr.is_staff = options["staff"]
|
||||
usr.save()
|
||||
|
||||
profile = Profile(user=usr)
|
||||
profile.language = Language.objects.get(key=options['language'])
|
||||
profile.language = Language.objects.get(key=options["language"])
|
||||
profile.save()
|
||||
|
|
|
@ -4,13 +4,13 @@ from judge.utils.camo import client as camo_client
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'obtains the camo url for the specified url'
|
||||
help = "obtains the camo url for the specified url"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('url', help='url to use camo on')
|
||||
parser.add_argument("url", help="url to use camo on")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if camo_client is None:
|
||||
raise CommandError('Camo not available')
|
||||
raise CommandError("Camo not available")
|
||||
|
||||
print(camo_client.image_url(options['url']))
|
||||
print(camo_client.image_url(options["url"]))
|
||||
|
|
|
@ -4,24 +4,30 @@ from judge.models import Language, LanguageLimit
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'allows the problems that allow <source> to be submitted in <target>'
|
||||
help = "allows the problems that allow <source> to be submitted in <target>"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('source', help='language to copy from')
|
||||
parser.add_argument('target', help='language to copy to')
|
||||
parser.add_argument("source", help="language to copy from")
|
||||
parser.add_argument("target", help="language to copy to")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
source = Language.objects.get(key=options['source'])
|
||||
source = Language.objects.get(key=options["source"])
|
||||
except Language.DoesNotExist:
|
||||
raise CommandError('Invalid source language: %s' % options['source'])
|
||||
raise CommandError("Invalid source language: %s" % options["source"])
|
||||
|
||||
try:
|
||||
target = Language.objects.get(key=options['target'])
|
||||
target = Language.objects.get(key=options["target"])
|
||||
except Language.DoesNotExist:
|
||||
raise CommandError('Invalid target language: %s' % options['target'])
|
||||
raise CommandError("Invalid target language: %s" % options["target"])
|
||||
|
||||
target.problem_set.set(source.problem_set.all())
|
||||
LanguageLimit.objects.bulk_create(LanguageLimit(problem=ll.problem, language=target, time_limit=ll.time_limit,
|
||||
memory_limit=ll.memory_limit)
|
||||
for ll in LanguageLimit.objects.filter(language=source))
|
||||
LanguageLimit.objects.bulk_create(
|
||||
LanguageLimit(
|
||||
problem=ll.problem,
|
||||
language=target,
|
||||
time_limit=ll.time_limit,
|
||||
memory_limit=ll.memory_limit,
|
||||
)
|
||||
for ll in LanguageLimit.objects.filter(language=source)
|
||||
)
|
||||
|
|
|
@ -4,20 +4,20 @@ from judge.models import Problem, ProblemGroup, ProblemType
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'create an empty problem'
|
||||
help = "create an empty problem"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('code', help='problem code')
|
||||
parser.add_argument('name', help='problem title')
|
||||
parser.add_argument('body', help='problem description')
|
||||
parser.add_argument('type', help='problem type')
|
||||
parser.add_argument('group', help='problem group')
|
||||
parser.add_argument("code", help="problem code")
|
||||
parser.add_argument("name", help="problem title")
|
||||
parser.add_argument("body", help="problem description")
|
||||
parser.add_argument("type", help="problem type")
|
||||
parser.add_argument("group", help="problem group")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
problem = Problem()
|
||||
problem.code = options['code']
|
||||
problem.name = options['name']
|
||||
problem.description = options['body']
|
||||
problem.group = ProblemGroup.objects.get(name=options['group'])
|
||||
problem.types = [ProblemType.objects.get(name=options['type'])]
|
||||
problem.code = options["code"]
|
||||
problem.name = options["name"]
|
||||
problem.description = options["body"]
|
||||
problem.group = ProblemGroup.objects.get(name=options["group"])
|
||||
problem.types = [ProblemType.objects.get(name=options["type"])]
|
||||
problem.save()
|
||||
|
|
|
@ -7,43 +7,47 @@ from django.conf import settings
|
|||
|
||||
|
||||
def gen_submissions():
|
||||
headers = ['uid', 'pid']
|
||||
with open(os.path.join(settings.ML_DATA_PATH, 'submissions.csv'), 'w') as csvfile:
|
||||
headers = ["uid", "pid"]
|
||||
with open(os.path.join(settings.ML_DATA_PATH, "submissions.csv"), "w") as csvfile:
|
||||
f = csv.writer(csvfile)
|
||||
f.writerow(headers)
|
||||
|
||||
|
||||
last_pid = defaultdict(int)
|
||||
for u in Profile.objects.all():
|
||||
used = set()
|
||||
print('Processing user', u.id)
|
||||
for s in Submission.objects.filter(user=u).order_by('-date'):
|
||||
print("Processing user", u.id)
|
||||
for s in Submission.objects.filter(user=u).order_by("-date"):
|
||||
if s.problem.id not in used:
|
||||
used.add(s.problem.id)
|
||||
f.writerow([u.id, s.problem.id])
|
||||
|
||||
|
||||
def gen_users():
|
||||
headers = ['uid', 'username', 'rating', 'points']
|
||||
with open(os.path.join(settings.ML_DATA_PATH, 'profiles.csv'), 'w') as csvfile:
|
||||
headers = ["uid", "username", "rating", "points"]
|
||||
with open(os.path.join(settings.ML_DATA_PATH, "profiles.csv"), "w") as csvfile:
|
||||
f = csv.writer(csvfile)
|
||||
f.writerow(headers)
|
||||
|
||||
|
||||
for u in Profile.objects.all():
|
||||
f.writerow([u.id, u.username, u.rating, u.performance_points])
|
||||
|
||||
|
||||
def gen_problems():
|
||||
headers = ['pid', 'code', 'name', 'points', 'url']
|
||||
with open(os.path.join(settings.ML_DATA_PATH, 'problems.csv'), 'w') as csvfile:
|
||||
headers = ["pid", "code", "name", "points", "url"]
|
||||
with open(os.path.join(settings.ML_DATA_PATH, "problems.csv"), "w") as csvfile:
|
||||
f = csv.writer(csvfile)
|
||||
f.writerow(headers)
|
||||
|
||||
|
||||
for p in Problem.objects.all():
|
||||
f.writerow([p.id, p.code, p.name, p.points, 'lqdoj.edu.vn/problem/' + p.code])
|
||||
f.writerow(
|
||||
[p.id, p.code, p.name, p.points, "lqdoj.edu.vn/problem/" + p.code]
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'generate data for ML'
|
||||
help = "generate data for ML"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
gen_users()
|
||||
gen_problems()
|
||||
gen_submissions()
|
||||
gen_submissions()
|
||||
|
|
|
@ -5,33 +5,69 @@ import sys
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.management import CommandError
|
||||
from django.core.management.commands.makemessages import Command as MakeMessagesCommand, check_programs
|
||||
from django.core.management.commands.makemessages import (
|
||||
Command as MakeMessagesCommand,
|
||||
check_programs,
|
||||
)
|
||||
|
||||
from judge.models import NavigationBar, ProblemType
|
||||
|
||||
|
||||
class Command(MakeMessagesCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--locale', '-l', default=[], dest='locale', action='append',
|
||||
help='Creates or updates the message files for the given locale(s) (e.g. pt_BR). '
|
||||
'Can be used multiple times.')
|
||||
parser.add_argument('--exclude', '-x', default=[], dest='exclude', action='append',
|
||||
help='Locales to exclude. Default is none. Can be used multiple times.')
|
||||
parser.add_argument('--all', '-a', action='store_true', dest='all',
|
||||
default=False, help='Updates the message files for all existing locales.')
|
||||
parser.add_argument('--no-wrap', action='store_true', dest='no_wrap',
|
||||
default=False, help="Don't break long message lines into several lines.")
|
||||
parser.add_argument('--no-obsolete', action='store_true', dest='no_obsolete',
|
||||
default=False, help="Remove obsolete message strings.")
|
||||
parser.add_argument('--keep-pot', action='store_true', dest='keep_pot',
|
||||
default=False, help="Keep .pot file after making messages. Useful when debugging.")
|
||||
parser.add_argument(
|
||||
"--locale",
|
||||
"-l",
|
||||
default=[],
|
||||
dest="locale",
|
||||
action="append",
|
||||
help="Creates or updates the message files for the given locale(s) (e.g. pt_BR). "
|
||||
"Can be used multiple times.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--exclude",
|
||||
"-x",
|
||||
default=[],
|
||||
dest="exclude",
|
||||
action="append",
|
||||
help="Locales to exclude. Default is none. Can be used multiple times.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--all",
|
||||
"-a",
|
||||
action="store_true",
|
||||
dest="all",
|
||||
default=False,
|
||||
help="Updates the message files for all existing locales.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-wrap",
|
||||
action="store_true",
|
||||
dest="no_wrap",
|
||||
default=False,
|
||||
help="Don't break long message lines into several lines.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-obsolete",
|
||||
action="store_true",
|
||||
dest="no_obsolete",
|
||||
default=False,
|
||||
help="Remove obsolete message strings.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--keep-pot",
|
||||
action="store_true",
|
||||
dest="keep_pot",
|
||||
default=False,
|
||||
help="Keep .pot file after making messages. Useful when debugging.",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
locale = options.get('locale')
|
||||
exclude = options.get('exclude')
|
||||
self.domain = 'dmoj-user'
|
||||
self.verbosity = options.get('verbosity')
|
||||
process_all = options.get('all')
|
||||
locale = options.get("locale")
|
||||
exclude = options.get("exclude")
|
||||
self.domain = "dmoj-user"
|
||||
self.verbosity = options.get("verbosity")
|
||||
process_all = options.get("all")
|
||||
|
||||
# Need to ensure that the i18n framework is enabled
|
||||
if settings.configured:
|
||||
|
@ -40,43 +76,47 @@ class Command(MakeMessagesCommand):
|
|||
settings.configure(USE_I18N=True)
|
||||
|
||||
# Avoid messing with mutable class variables
|
||||
if options.get('no_wrap'):
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ['--no-wrap']
|
||||
self.msguniq_options = self.msguniq_options[:] + ['--no-wrap']
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ['--no-wrap']
|
||||
self.xgettext_options = self.xgettext_options[:] + ['--no-wrap']
|
||||
if options.get('no_location'):
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ['--no-location']
|
||||
self.msguniq_options = self.msguniq_options[:] + ['--no-location']
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ['--no-location']
|
||||
self.xgettext_options = self.xgettext_options[:] + ['--no-location']
|
||||
if options.get("no_wrap"):
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ["--no-wrap"]
|
||||
self.msguniq_options = self.msguniq_options[:] + ["--no-wrap"]
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ["--no-wrap"]
|
||||
self.xgettext_options = self.xgettext_options[:] + ["--no-wrap"]
|
||||
if options.get("no_location"):
|
||||
self.msgmerge_options = self.msgmerge_options[:] + ["--no-location"]
|
||||
self.msguniq_options = self.msguniq_options[:] + ["--no-location"]
|
||||
self.msgattrib_options = self.msgattrib_options[:] + ["--no-location"]
|
||||
self.xgettext_options = self.xgettext_options[:] + ["--no-location"]
|
||||
|
||||
self.no_obsolete = options.get('no_obsolete')
|
||||
self.keep_pot = options.get('keep_pot')
|
||||
self.no_obsolete = options.get("no_obsolete")
|
||||
self.keep_pot = options.get("keep_pot")
|
||||
|
||||
if locale is None and not exclude and not process_all:
|
||||
raise CommandError("Type '%s help %s' for usage information." % (
|
||||
os.path.basename(sys.argv[0]), sys.argv[1]))
|
||||
raise CommandError(
|
||||
"Type '%s help %s' for usage information."
|
||||
% (os.path.basename(sys.argv[0]), sys.argv[1])
|
||||
)
|
||||
|
||||
self.invoked_for_django = False
|
||||
self.locale_paths = []
|
||||
self.default_locale_path = None
|
||||
if os.path.isdir(os.path.join('conf', 'locale')):
|
||||
self.locale_paths = [os.path.abspath(os.path.join('conf', 'locale'))]
|
||||
if os.path.isdir(os.path.join("conf", "locale")):
|
||||
self.locale_paths = [os.path.abspath(os.path.join("conf", "locale"))]
|
||||
self.default_locale_path = self.locale_paths[0]
|
||||
self.invoked_for_django = True
|
||||
else:
|
||||
self.locale_paths.extend(settings.LOCALE_PATHS)
|
||||
# Allow to run makemessages inside an app dir
|
||||
if os.path.isdir('locale'):
|
||||
self.locale_paths.append(os.path.abspath('locale'))
|
||||
if os.path.isdir("locale"):
|
||||
self.locale_paths.append(os.path.abspath("locale"))
|
||||
if self.locale_paths:
|
||||
self.default_locale_path = self.locale_paths[0]
|
||||
if not os.path.exists(self.default_locale_path):
|
||||
os.makedirs(self.default_locale_path)
|
||||
|
||||
# Build locale list
|
||||
locale_dirs = list(filter(os.path.isdir, glob.glob('%s/*' % self.default_locale_path)))
|
||||
locale_dirs = list(
|
||||
filter(os.path.isdir, glob.glob("%s/*" % self.default_locale_path))
|
||||
)
|
||||
all_locales = list(map(os.path.basename, locale_dirs))
|
||||
|
||||
# Account for excluded locales
|
||||
|
@ -87,9 +127,9 @@ class Command(MakeMessagesCommand):
|
|||
locales = set(locales) - set(exclude)
|
||||
|
||||
if locales:
|
||||
check_programs('msguniq', 'msgmerge', 'msgattrib')
|
||||
check_programs("msguniq", "msgmerge", "msgattrib")
|
||||
|
||||
check_programs('xgettext')
|
||||
check_programs("xgettext")
|
||||
|
||||
try:
|
||||
potfiles = self.build_potfiles()
|
||||
|
@ -108,23 +148,33 @@ class Command(MakeMessagesCommand):
|
|||
return []
|
||||
|
||||
def _emit_message(self, potfile, string):
|
||||
potfile.write('''
|
||||
potfile.write(
|
||||
"""
|
||||
msgid "%s"
|
||||
msgstr ""
|
||||
''' % string.replace('\\', r'\\').replace('\t', '\\t').replace('\n', '\\n').replace('"', '\\"'))
|
||||
"""
|
||||
% string.replace("\\", r"\\")
|
||||
.replace("\t", "\\t")
|
||||
.replace("\n", "\\n")
|
||||
.replace('"', '\\"')
|
||||
)
|
||||
|
||||
def process_files(self, file_list):
|
||||
with io.open(os.path.join(self.default_locale_path, 'dmoj-user.pot'), 'w', encoding='utf-8') as potfile:
|
||||
with io.open(
|
||||
os.path.join(self.default_locale_path, "dmoj-user.pot"),
|
||||
"w",
|
||||
encoding="utf-8",
|
||||
) as potfile:
|
||||
if self.verbosity > 1:
|
||||
self.stdout.write('processing navigation bar')
|
||||
for label in NavigationBar.objects.values_list('label', flat=True):
|
||||
self.stdout.write("processing navigation bar")
|
||||
for label in NavigationBar.objects.values_list("label", flat=True):
|
||||
if self.verbosity > 2:
|
||||
self.stdout.write('processing navigation item label "%s"\n' % label)
|
||||
self._emit_message(potfile, label)
|
||||
|
||||
if self.verbosity > 1:
|
||||
self.stdout.write('processing problem types')
|
||||
for name in ProblemType.objects.values_list('full_name', flat=True):
|
||||
self.stdout.write("processing problem types")
|
||||
for name in ProblemType.objects.values_list("full_name", flat=True):
|
||||
if self.verbosity > 2:
|
||||
self.stdout.write('processing problem type name "%s"\n' % name)
|
||||
self._emit_message(potfile, name)
|
||||
|
|
|
@ -8,52 +8,98 @@ from django.template.loader import get_template
|
|||
from django.utils import translation
|
||||
|
||||
from judge.models import Problem, ProblemTranslation
|
||||
from judge.pdf_problems import DefaultPdfMaker, PhantomJSPdfMaker, PuppeteerPDFRender, SeleniumPDFRender, \
|
||||
SlimerJSPdfMaker
|
||||
from judge.pdf_problems import (
|
||||
DefaultPdfMaker,
|
||||
PhantomJSPdfMaker,
|
||||
PuppeteerPDFRender,
|
||||
SeleniumPDFRender,
|
||||
SlimerJSPdfMaker,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'renders a PDF file of a problem'
|
||||
help = "renders a PDF file of a problem"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('code', help='code of problem to render')
|
||||
parser.add_argument('directory', nargs='?', help='directory to store temporaries')
|
||||
parser.add_argument('-l', '--language', default=settings.LANGUAGE_CODE,
|
||||
help='language to render PDF in')
|
||||
parser.add_argument('-p', '--phantomjs', action='store_const', const=PhantomJSPdfMaker,
|
||||
default=DefaultPdfMaker, dest='engine')
|
||||
parser.add_argument('-s', '--slimerjs', action='store_const', const=SlimerJSPdfMaker, dest='engine')
|
||||
parser.add_argument('-c', '--chrome', '--puppeteer', action='store_const',
|
||||
const=PuppeteerPDFRender, dest='engine')
|
||||
parser.add_argument('-S', '--selenium', action='store_const', const=SeleniumPDFRender, dest='engine')
|
||||
parser.add_argument("code", help="code of problem to render")
|
||||
parser.add_argument(
|
||||
"directory", nargs="?", help="directory to store temporaries"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l",
|
||||
"--language",
|
||||
default=settings.LANGUAGE_CODE,
|
||||
help="language to render PDF in",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--phantomjs",
|
||||
action="store_const",
|
||||
const=PhantomJSPdfMaker,
|
||||
default=DefaultPdfMaker,
|
||||
dest="engine",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--slimerjs",
|
||||
action="store_const",
|
||||
const=SlimerJSPdfMaker,
|
||||
dest="engine",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--chrome",
|
||||
"--puppeteer",
|
||||
action="store_const",
|
||||
const=PuppeteerPDFRender,
|
||||
dest="engine",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-S",
|
||||
"--selenium",
|
||||
action="store_const",
|
||||
const=SeleniumPDFRender,
|
||||
dest="engine",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
problem = Problem.objects.get(code=options['code'])
|
||||
problem = Problem.objects.get(code=options["code"])
|
||||
except Problem.DoesNotExist:
|
||||
print('Bad problem code')
|
||||
print("Bad problem code")
|
||||
return
|
||||
|
||||
try:
|
||||
trans = problem.translations.get(language=options['language'])
|
||||
trans = problem.translations.get(language=options["language"])
|
||||
except ProblemTranslation.DoesNotExist:
|
||||
trans = None
|
||||
|
||||
directory = options['directory']
|
||||
with options['engine'](directory, clean_up=directory is None) as maker, \
|
||||
translation.override(options['language']):
|
||||
directory = options["directory"]
|
||||
with options["engine"](
|
||||
directory, clean_up=directory is None
|
||||
) as maker, translation.override(options["language"]):
|
||||
problem_name = problem.name if trans is None else trans.name
|
||||
maker.html = get_template('problem/raw.html').render({
|
||||
'problem': problem,
|
||||
'problem_name': problem_name,
|
||||
'description': problem.description if trans is None else trans.description,
|
||||
'url': '',
|
||||
'math_engine': maker.math_engine,
|
||||
}).replace('"//', '"https://').replace("'//", "'https://")
|
||||
maker.html = (
|
||||
get_template("problem/raw.html")
|
||||
.render(
|
||||
{
|
||||
"problem": problem,
|
||||
"problem_name": problem_name,
|
||||
"description": problem.description
|
||||
if trans is None
|
||||
else trans.description,
|
||||
"url": "",
|
||||
"math_engine": maker.math_engine,
|
||||
}
|
||||
)
|
||||
.replace('"//', '"https://')
|
||||
.replace("'//", "'https://")
|
||||
)
|
||||
maker.title = problem_name
|
||||
for file in ('style.css', 'pygment-github.css', 'mathjax_config.js'):
|
||||
for file in ("style.css", "pygment-github.css", "mathjax_config.js"):
|
||||
maker.load(file, os.path.join(settings.DMOJ_RESOURCES, file))
|
||||
maker.make(debug=True)
|
||||
if not maker.success:
|
||||
print(maker.log, file=sys.stderr)
|
||||
elif directory is None:
|
||||
shutil.move(maker.pdffile, problem.code + '.pdf')
|
||||
shutil.move(maker.pdffile, problem.code + ".pdf")
|
||||
|
|
|
@ -5,4 +5,4 @@ from judge.bridge.daemon import judge_daemon
|
|||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
judge_daemon()
|
||||
judge_daemon()
|
||||
|
|
|
@ -6,42 +6,50 @@ from judge.models import Contest, ContestParticipation, Submission
|
|||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Checks for duplicate code using MOSS'
|
||||
help = "Checks for duplicate code using MOSS"
|
||||
|
||||
LANG_MAPPING = {
|
||||
('C++', MOSS_LANG_CC),
|
||||
('C', MOSS_LANG_C),
|
||||
('Java', MOSS_LANG_JAVA),
|
||||
('Python', MOSS_LANG_PYTHON),
|
||||
('Pascal', MOSS_LANG_PASCAL),
|
||||
("C++", MOSS_LANG_CC),
|
||||
("C", MOSS_LANG_C),
|
||||
("Java", MOSS_LANG_JAVA),
|
||||
("Python", MOSS_LANG_PYTHON),
|
||||
("Pascal", MOSS_LANG_PASCAL),
|
||||
}
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('contest', help='the id of the contest')
|
||||
parser.add_argument("contest", help="the id of the contest")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
moss_api_key = settings.MOSS_API_KEY
|
||||
if moss_api_key is None:
|
||||
print('No MOSS API Key supplied')
|
||||
print("No MOSS API Key supplied")
|
||||
return
|
||||
contest = options['contest']
|
||||
contest = options["contest"]
|
||||
|
||||
for problem in Contest.objects.get(key=contest).problems.order_by('code'):
|
||||
print('========== %s / %s ==========' % (problem.code, problem.name))
|
||||
for problem in Contest.objects.get(key=contest).problems.order_by("code"):
|
||||
print("========== %s / %s ==========" % (problem.code, problem.name))
|
||||
for dmoj_lang, moss_lang in self.LANG_MAPPING:
|
||||
print("%s: " % dmoj_lang, end=' ')
|
||||
print("%s: " % dmoj_lang, end=" ")
|
||||
subs = Submission.objects.filter(
|
||||
contest__participation__virtual__in=(ContestParticipation.LIVE, ContestParticipation.SPECTATE),
|
||||
contest__participation__virtual__in=(
|
||||
ContestParticipation.LIVE,
|
||||
ContestParticipation.SPECTATE,
|
||||
),
|
||||
contest__participation__contest__key=contest,
|
||||
result='AC', problem__id=problem.id,
|
||||
result="AC",
|
||||
problem__id=problem.id,
|
||||
language__common_name=dmoj_lang,
|
||||
).values_list('user__user__username', 'source__source')
|
||||
).values_list("user__user__username", "source__source")
|
||||
if not subs:
|
||||
print('<no submissions>')
|
||||
print("<no submissions>")
|
||||
continue
|
||||
|
||||
moss_call = MOSS(moss_api_key, language=moss_lang, matching_file_limit=100,
|
||||
comment='%s - %s' % (contest, problem.code))
|
||||
moss_call = MOSS(
|
||||
moss_api_key,
|
||||
language=moss_lang,
|
||||
matching_file_limit=100,
|
||||
comment="%s - %s" % (contest, problem.code),
|
||||
)
|
||||
|
||||
users = set()
|
||||
|
||||
|
@ -49,6 +57,6 @@ class Command(BaseCommand):
|
|||
if username in users:
|
||||
continue
|
||||
users.add(username)
|
||||
moss_call.add_file_from_memory(username, source.encode('utf-8'))
|
||||
moss_call.add_file_from_memory(username, source.encode("utf-8"))
|
||||
|
||||
print('(%d): %s' % (subs.count(), moss_call.process()))
|
||||
print("(%d): %s" % (subs.count(), moss_call.process()))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue