Reformat using black

This commit is contained in:
cuom1999 2022-05-14 12:57:27 -05:00
parent efee4ad081
commit a87fb49918
221 changed files with 19127 additions and 7310 deletions

View file

@ -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()

View file

@ -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()

View file

@ -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"]))

View file

@ -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)
)

View file

@ -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()

View file

@ -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()

View file

@ -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)

View file

@ -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")

View file

@ -5,4 +5,4 @@ from judge.bridge.daemon import judge_daemon
class Command(BaseCommand):
def handle(self, *args, **options):
judge_daemon()
judge_daemon()

View file

@ -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()))