NDOJ/judge/management/commands/makedmojmessages.py
2022-05-30 17:19:46 -05:00

187 lines
6.4 KiB
Python

import glob
import io
import os
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 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.",
)
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")
# Need to ensure that the i18n framework is enabled
if settings.configured:
settings.USE_I18N = True
else:
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"]
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])
)
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"))]
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 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))
)
all_locales = list(map(os.path.basename, locale_dirs))
# Account for excluded locales
if process_all:
locales = all_locales
else:
locales = locale or all_locales
locales = set(locales) - set(exclude)
if locales:
check_programs("msguniq", "msgmerge", "msgattrib")
check_programs("xgettext")
try:
potfiles = self.build_potfiles()
# Build po files for each selected locale
for locale in locales:
if self.verbosity > 0:
self.stdout.write("processing locale %s\n" % locale)
for potfile in potfiles:
self.write_po_file(potfile, locale)
finally:
if not self.keep_pot:
self.remove_potfiles()
def find_files(self, root):
return []
def _emit_message(self, potfile, string):
potfile.write(
"""
msgid "%s"
msgstr ""
"""
% 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:
potfile.write(
"""
msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8\\n"
""")
if self.verbosity > 1:
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):
if self.verbosity > 2:
self.stdout.write('processing problem type name "%s"\n' % name)
self._emit_message(potfile, name)