Add profile info
This commit is contained in:
parent
55a85689e9
commit
8d0045ec82
10 changed files with 353 additions and 157 deletions
|
@ -6,7 +6,7 @@ from reversion.admin import VersionAdmin
|
||||||
from django.contrib.auth.admin import UserAdmin as OldUserAdmin
|
from django.contrib.auth.admin import UserAdmin as OldUserAdmin
|
||||||
|
|
||||||
from django_ace import AceWidget
|
from django_ace import AceWidget
|
||||||
from judge.models import Profile
|
from judge.models import Profile, ProfileInfo
|
||||||
from judge.widgets import AdminPagedownWidget, AdminSelect2Widget
|
from judge.widgets import AdminPagedownWidget, AdminSelect2Widget
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,6 +54,13 @@ class TimezoneFilter(admin.SimpleListFilter):
|
||||||
return queryset.filter(timezone=self.value())
|
return queryset.filter(timezone=self.value())
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileInfoInline(admin.StackedInline):
|
||||||
|
model = ProfileInfo
|
||||||
|
can_delete = False
|
||||||
|
verbose_name_plural = "profile info"
|
||||||
|
fk_name = "profile"
|
||||||
|
|
||||||
|
|
||||||
class ProfileAdmin(VersionAdmin):
|
class ProfileAdmin(VersionAdmin):
|
||||||
fields = (
|
fields = (
|
||||||
"user",
|
"user",
|
||||||
|
@ -67,7 +74,6 @@ class ProfileAdmin(VersionAdmin):
|
||||||
"ip",
|
"ip",
|
||||||
"mute",
|
"mute",
|
||||||
"is_unlisted",
|
"is_unlisted",
|
||||||
"is_banned_problem_voting",
|
|
||||||
"notes",
|
"notes",
|
||||||
"is_totp_enabled",
|
"is_totp_enabled",
|
||||||
"current_contest",
|
"current_contest",
|
||||||
|
@ -90,6 +96,7 @@ class ProfileAdmin(VersionAdmin):
|
||||||
actions_on_top = True
|
actions_on_top = True
|
||||||
actions_on_bottom = True
|
actions_on_bottom = True
|
||||||
form = ProfileForm
|
form = ProfileForm
|
||||||
|
inlines = (ProfileInfoInline,)
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
return super(ProfileAdmin, self).get_queryset(request).select_related("user")
|
return super(ProfileAdmin, self).get_queryset(request).select_related("user")
|
||||||
|
|
|
@ -39,6 +39,7 @@ from judge.models import (
|
||||||
BlogPost,
|
BlogPost,
|
||||||
ContestProblem,
|
ContestProblem,
|
||||||
TestFormatterModel,
|
TestFormatterModel,
|
||||||
|
ProfileInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
from judge.widgets import (
|
from judge.widgets import (
|
||||||
|
@ -51,6 +52,7 @@ from judge.widgets import (
|
||||||
Select2MultipleWidget,
|
Select2MultipleWidget,
|
||||||
DateTimePickerWidget,
|
DateTimePickerWidget,
|
||||||
ImageWidget,
|
ImageWidget,
|
||||||
|
DatePickerWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,6 +71,17 @@ class UserForm(ModelForm):
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileInfoForm(ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = ProfileInfo
|
||||||
|
fields = ["tshirt_size", "date_of_birth", "address"]
|
||||||
|
widgets = {
|
||||||
|
"tshirt_size": Select2Widget(attrs={"style": "width:100%"}),
|
||||||
|
"date_of_birth": DatePickerWidget,
|
||||||
|
"address": forms.TextInput(attrs={"style": "width:100%"}),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ProfileForm(ModelForm):
|
class ProfileForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Profile
|
model = Profile
|
||||||
|
|
69
judge/migrations/0187_profile_info.py
Normal file
69
judge/migrations/0187_profile_info.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# Generated by Django 3.2.18 on 2024-04-27 03:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("judge", "0186_change_about_fields_max_len"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="profile",
|
||||||
|
name="is_banned_problem_voting",
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="ProfileInfo",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.AutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tshirt_size",
|
||||||
|
models.CharField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("S", "Small (S)"),
|
||||||
|
("M", "Medium (M)"),
|
||||||
|
("L", "Large (L)"),
|
||||||
|
("XL", "Extra Large (XL)"),
|
||||||
|
("XXL", "2 Extra Large (XXL)"),
|
||||||
|
],
|
||||||
|
max_length=5,
|
||||||
|
null=True,
|
||||||
|
verbose_name="t-shirt size",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"date_of_birth",
|
||||||
|
models.DateField(
|
||||||
|
blank=True, null=True, verbose_name="date of birth"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"address",
|
||||||
|
models.CharField(
|
||||||
|
blank=True, max_length=255, null=True, verbose_name="address"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"profile",
|
||||||
|
models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="info",
|
||||||
|
to="judge.profile",
|
||||||
|
verbose_name="profile associated",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
|
@ -43,6 +43,7 @@ from judge.models.profile import (
|
||||||
Profile,
|
Profile,
|
||||||
Friend,
|
Friend,
|
||||||
OrganizationProfile,
|
OrganizationProfile,
|
||||||
|
ProfileInfo,
|
||||||
)
|
)
|
||||||
from judge.models.runtime import Judge, Language, RuntimeVersion
|
from judge.models.runtime import Judge, Language, RuntimeVersion
|
||||||
from judge.models.submission import (
|
from judge.models.submission import (
|
||||||
|
|
|
@ -26,6 +26,15 @@ from judge.caching import cache_wrapper
|
||||||
__all__ = ["Organization", "Profile", "OrganizationRequest", "Friend"]
|
__all__ = ["Organization", "Profile", "OrganizationRequest", "Friend"]
|
||||||
|
|
||||||
|
|
||||||
|
TSHIRT_SIZES = (
|
||||||
|
("S", "Small (S)"),
|
||||||
|
("M", "Medium (M)"),
|
||||||
|
("L", "Large (L)"),
|
||||||
|
("XL", "Extra Large (XL)"),
|
||||||
|
("XXL", "2 Extra Large (XXL)"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EncryptedNullCharField(EncryptedCharField):
|
class EncryptedNullCharField(EncryptedCharField):
|
||||||
def get_prep_value(self, value):
|
def get_prep_value(self, value):
|
||||||
if not value:
|
if not value:
|
||||||
|
@ -213,11 +222,6 @@ class Profile(models.Model):
|
||||||
help_text=_("User will not be ranked."),
|
help_text=_("User will not be ranked."),
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
is_banned_problem_voting = models.BooleanField(
|
|
||||||
verbose_name=_("banned from voting"),
|
|
||||||
help_text=_("User will not be able to vote on problems' point values."),
|
|
||||||
default=False,
|
|
||||||
)
|
|
||||||
rating = models.IntegerField(null=True, default=None, db_index=True)
|
rating = models.IntegerField(null=True, default=None, db_index=True)
|
||||||
current_contest = models.OneToOneField(
|
current_contest = models.OneToOneField(
|
||||||
"ContestParticipation",
|
"ContestParticipation",
|
||||||
|
@ -422,6 +426,36 @@ class Profile(models.Model):
|
||||||
verbose_name_plural = _("user profiles")
|
verbose_name_plural = _("user profiles")
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileInfo(models.Model):
|
||||||
|
profile = models.OneToOneField(
|
||||||
|
Profile,
|
||||||
|
verbose_name=_("profile associated"),
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="info",
|
||||||
|
)
|
||||||
|
tshirt_size = models.CharField(
|
||||||
|
max_length=5,
|
||||||
|
choices=TSHIRT_SIZES,
|
||||||
|
verbose_name=_("t-shirt size"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
date_of_birth = models.DateField(
|
||||||
|
verbose_name=_("date of birth"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
address = models.CharField(
|
||||||
|
max_length=255,
|
||||||
|
verbose_name=_("address"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.profile.user.username}'s Info"
|
||||||
|
|
||||||
|
|
||||||
class OrganizationRequest(models.Model):
|
class OrganizationRequest(models.Model):
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
Profile,
|
Profile,
|
||||||
|
|
|
@ -35,8 +35,8 @@ from django.views.generic import DetailView, ListView, TemplateView
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from reversion import revisions
|
from reversion import revisions
|
||||||
|
|
||||||
from judge.forms import UserForm, ProfileForm
|
from judge.forms import UserForm, ProfileForm, ProfileInfoForm
|
||||||
from judge.models import Profile, Rating, Submission, Friend
|
from judge.models import Profile, Rating, Submission, Friend, ProfileInfo
|
||||||
from judge.performance_points import get_pp_breakdown
|
from judge.performance_points import get_pp_breakdown
|
||||||
from judge.ratings import rating_class, rating_progress
|
from judge.ratings import rating_class, rating_progress
|
||||||
from judge.tasks import import_users
|
from judge.tasks import import_users
|
||||||
|
@ -390,21 +390,25 @@ class UserPerformancePointsAjax(UserProblemsPage):
|
||||||
@login_required
|
@login_required
|
||||||
def edit_profile(request):
|
def edit_profile(request):
|
||||||
profile = request.profile
|
profile = request.profile
|
||||||
|
profile_info, created = ProfileInfo.objects.get_or_create(profile=profile)
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
form_user = UserForm(request.POST, instance=request.user)
|
form_user = UserForm(request.POST, instance=request.user)
|
||||||
form = ProfileForm(
|
form = ProfileForm(
|
||||||
request.POST, request.FILES, instance=profile, user=request.user
|
request.POST, request.FILES, instance=profile, user=request.user
|
||||||
)
|
)
|
||||||
|
form_info = ProfileInfoForm(request.POST, instance=profile_info)
|
||||||
if form_user.is_valid() and form.is_valid():
|
if form_user.is_valid() and form.is_valid():
|
||||||
with revisions.create_revision():
|
with revisions.create_revision():
|
||||||
form_user.save()
|
form_user.save()
|
||||||
form.save()
|
form.save()
|
||||||
|
form_info.save()
|
||||||
revisions.set_user(request.user)
|
revisions.set_user(request.user)
|
||||||
revisions.set_comment(_("Updated on site"))
|
revisions.set_comment(_("Updated on site"))
|
||||||
return HttpResponseRedirect(request.path)
|
return HttpResponseRedirect(request.path)
|
||||||
else:
|
else:
|
||||||
form_user = UserForm(instance=request.user)
|
form_user = UserForm(instance=request.user)
|
||||||
form = ProfileForm(instance=profile, user=request.user)
|
form = ProfileForm(instance=profile, user=request.user)
|
||||||
|
form_info = ProfileInfoForm(instance=profile_info)
|
||||||
|
|
||||||
tzmap = settings.TIMEZONE_MAP
|
tzmap = settings.TIMEZONE_MAP
|
||||||
|
|
||||||
|
@ -415,6 +419,7 @@ def edit_profile(request):
|
||||||
"require_staff_2fa": settings.DMOJ_REQUIRE_STAFF_2FA,
|
"require_staff_2fa": settings.DMOJ_REQUIRE_STAFF_2FA,
|
||||||
"form_user": form_user,
|
"form_user": form_user,
|
||||||
"form": form,
|
"form": form,
|
||||||
|
"form_info": form_info,
|
||||||
"title": _("Edit profile"),
|
"title": _("Edit profile"),
|
||||||
"profile": profile,
|
"profile": profile,
|
||||||
"TIMEZONE_MAP": tzmap or "http://momentjs.com/static/img/world.png",
|
"TIMEZONE_MAP": tzmap or "http://momentjs.com/static/img/world.png",
|
||||||
|
|
|
@ -25,3 +25,25 @@ class DateTimePickerWidget(forms.DateTimeInput):
|
||||||
attrs, {"type": self.input_type, "name": name, "value": value}
|
attrs, {"type": self.input_type, "name": name, "value": value}
|
||||||
)
|
)
|
||||||
return format_html("<input{}>", flatatt(final_attrs))
|
return format_html("<input{}>", flatatt(final_attrs))
|
||||||
|
|
||||||
|
|
||||||
|
class DatePickerWidget(forms.DateInput):
|
||||||
|
input_type = "date"
|
||||||
|
|
||||||
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
|
if value is None:
|
||||||
|
value = ""
|
||||||
|
elif isinstance(value, str):
|
||||||
|
# Attempt to parse the string back to date
|
||||||
|
parsed_date = parse_date(value)
|
||||||
|
if parsed_date is not None:
|
||||||
|
value = parsed_date.strftime("%Y-%m-%d")
|
||||||
|
else:
|
||||||
|
value = ""
|
||||||
|
else:
|
||||||
|
value = value.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
final_attrs = self.build_attrs(
|
||||||
|
attrs, {"type": self.input_type, "name": name, "value": value}
|
||||||
|
)
|
||||||
|
return format_html("<input{}>", flatatt(final_attrs))
|
||||||
|
|
|
@ -2,7 +2,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: lqdoj2\n"
|
"Project-Id-Version: lqdoj2\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-04-27 08:36+0700\n"
|
"POT-Creation-Date: 2024-04-27 10:48+0700\n"
|
||||||
"PO-Revision-Date: 2021-07-20 03:44\n"
|
"PO-Revision-Date: 2021-07-20 03:44\n"
|
||||||
"Last-Translator: Icyene\n"
|
"Last-Translator: Icyene\n"
|
||||||
"Language-Team: Vietnamese\n"
|
"Language-Team: Vietnamese\n"
|
||||||
|
@ -25,7 +25,7 @@ msgstr "xem lần cuối"
|
||||||
#: chat_box/models.py:54 chat_box/models.py:79 chat_box/models.py:95
|
#: chat_box/models.py:54 chat_box/models.py:79 chat_box/models.py:95
|
||||||
#: judge/admin/interface.py:150 judge/models/contest.py:673
|
#: judge/admin/interface.py:150 judge/models/contest.py:673
|
||||||
#: judge/models/contest.py:879 judge/models/course.py:129
|
#: judge/models/contest.py:879 judge/models/course.py:129
|
||||||
#: judge/models/profile.py:428 judge/models/profile.py:502
|
#: judge/models/profile.py:462 judge/models/profile.py:536
|
||||||
msgid "user"
|
msgid "user"
|
||||||
msgstr "người dùng"
|
msgstr "người dùng"
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ msgid "diff"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/admin/organization.py:61 judge/admin/problem.py:290
|
#: judge/admin/organization.py:61 judge/admin/problem.py:290
|
||||||
#: judge/admin/profile.py:115
|
#: judge/admin/profile.py:122
|
||||||
msgid "View on site"
|
msgid "View on site"
|
||||||
msgstr "Xem trên trang"
|
msgstr "Xem trên trang"
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ msgstr ""
|
||||||
msgid "timezone"
|
msgid "timezone"
|
||||||
msgstr "múi giờ"
|
msgstr "múi giờ"
|
||||||
|
|
||||||
#: judge/admin/profile.py:124 judge/admin/submission.py:327
|
#: judge/admin/profile.py:131 judge/admin/submission.py:327
|
||||||
#: templates/notification/list.html:9
|
#: templates/notification/list.html:9
|
||||||
#: templates/organization/requests/log.html:9
|
#: templates/organization/requests/log.html:9
|
||||||
#: templates/organization/requests/pending.html:19
|
#: templates/organization/requests/pending.html:19
|
||||||
|
@ -336,28 +336,28 @@ msgstr "múi giờ"
|
||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr "Thành viên"
|
msgstr "Thành viên"
|
||||||
|
|
||||||
#: judge/admin/profile.py:130 templates/registration/registration_form.html:40
|
#: judge/admin/profile.py:137 templates/registration/registration_form.html:40
|
||||||
#: templates/user/edit-profile.html:109 templates/user/import/table_csv.html:8
|
#: templates/user/edit-profile.html:123 templates/user/import/table_csv.html:8
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "Email"
|
msgstr "Email"
|
||||||
|
|
||||||
#: judge/admin/profile.py:136 judge/views/register.py:36
|
#: judge/admin/profile.py:143 judge/views/register.py:36
|
||||||
#: templates/registration/registration_form.html:68
|
#: templates/registration/registration_form.html:68
|
||||||
#: templates/user/edit-profile.html:133
|
#: templates/user/edit-profile.html:147
|
||||||
msgid "Timezone"
|
msgid "Timezone"
|
||||||
msgstr "Múi giờ"
|
msgstr "Múi giờ"
|
||||||
|
|
||||||
#: judge/admin/profile.py:142
|
#: judge/admin/profile.py:149
|
||||||
msgid "date joined"
|
msgid "date joined"
|
||||||
msgstr "ngày tham gia"
|
msgstr "ngày tham gia"
|
||||||
|
|
||||||
#: judge/admin/profile.py:152
|
#: judge/admin/profile.py:159
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%d user have scores recalculated."
|
msgid "%d user have scores recalculated."
|
||||||
msgid_plural "%d users have scores recalculated."
|
msgid_plural "%d users have scores recalculated."
|
||||||
msgstr[0] "%d người dùng đã được tính điểm lại."
|
msgstr[0] "%d người dùng đã được tính điểm lại."
|
||||||
|
|
||||||
#: judge/admin/profile.py:159
|
#: judge/admin/profile.py:166
|
||||||
msgid "Recalculate scores"
|
msgid "Recalculate scores"
|
||||||
msgstr "Tính điểm lại"
|
msgstr "Tính điểm lại"
|
||||||
|
|
||||||
|
@ -533,76 +533,76 @@ msgstr "Báo cáo lỗi"
|
||||||
msgid "Courses"
|
msgid "Courses"
|
||||||
msgstr "Khóa học"
|
msgstr "Khóa học"
|
||||||
|
|
||||||
#: judge/forms.py:107
|
#: judge/forms.py:124
|
||||||
msgid "File size exceeds the maximum allowed limit of 5MB."
|
msgid "File size exceeds the maximum allowed limit of 5MB."
|
||||||
msgstr "File tải lên không được quá 5MB."
|
msgstr "File tải lên không được quá 5MB."
|
||||||
|
|
||||||
#: judge/forms.py:138
|
#: judge/forms.py:155
|
||||||
msgid "Any judge"
|
msgid "Any judge"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/forms.py:338
|
#: judge/forms.py:355
|
||||||
msgid "Enter usernames separating by space"
|
msgid "Enter usernames separating by space"
|
||||||
msgstr "Nhập các tên đăng nhập, cách nhau bởi dấu cách"
|
msgstr "Nhập các tên đăng nhập, cách nhau bởi dấu cách"
|
||||||
|
|
||||||
#: judge/forms.py:339 judge/views/stats.py:166 templates/stats/site.html:27
|
#: judge/forms.py:356 judge/views/stats.py:166 templates/stats/site.html:27
|
||||||
msgid "New users"
|
msgid "New users"
|
||||||
msgstr "Thành viên mới"
|
msgstr "Thành viên mới"
|
||||||
|
|
||||||
#: judge/forms.py:356
|
#: judge/forms.py:373
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "These usernames don't exist: {usernames}"
|
msgid "These usernames don't exist: {usernames}"
|
||||||
msgstr "Các tên đăng nhập này không tồn tại: {usernames}"
|
msgstr "Các tên đăng nhập này không tồn tại: {usernames}"
|
||||||
|
|
||||||
#: judge/forms.py:416
|
#: judge/forms.py:433
|
||||||
msgid "Username/Email"
|
msgid "Username/Email"
|
||||||
msgstr "Tên đăng nhập / Email"
|
msgstr "Tên đăng nhập / Email"
|
||||||
|
|
||||||
#: judge/forms.py:418 judge/views/email.py:22
|
#: judge/forms.py:435 judge/views/email.py:22
|
||||||
#: templates/registration/registration_form.html:46
|
#: templates/registration/registration_form.html:46
|
||||||
#: templates/registration/registration_form.html:60
|
#: templates/registration/registration_form.html:60
|
||||||
#: templates/user/edit-profile.html:101 templates/user/import/table_csv.html:5
|
#: templates/user/edit-profile.html:115 templates/user/import/table_csv.html:5
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Mật khẩu"
|
msgstr "Mật khẩu"
|
||||||
|
|
||||||
#: judge/forms.py:444
|
#: judge/forms.py:461
|
||||||
msgid "Two Factor Authentication tokens must be 6 decimal digits."
|
msgid "Two Factor Authentication tokens must be 6 decimal digits."
|
||||||
msgstr "Two Factor Authentication phải chứa 6 chữ số."
|
msgstr "Two Factor Authentication phải chứa 6 chữ số."
|
||||||
|
|
||||||
#: judge/forms.py:457 templates/registration/totp_auth.html:32
|
#: judge/forms.py:474 templates/registration/totp_auth.html:32
|
||||||
msgid "Invalid Two Factor Authentication token."
|
msgid "Invalid Two Factor Authentication token."
|
||||||
msgstr "Token Two Factor Authentication không hợp lệ."
|
msgstr "Token Two Factor Authentication không hợp lệ."
|
||||||
|
|
||||||
#: judge/forms.py:464 judge/models/problem.py:133
|
#: judge/forms.py:481 judge/models/problem.py:133
|
||||||
msgid "Problem code must be ^[a-z0-9]+$"
|
msgid "Problem code must be ^[a-z0-9]+$"
|
||||||
msgstr "Mã bài phải có dạng ^[a-z0-9]+$"
|
msgstr "Mã bài phải có dạng ^[a-z0-9]+$"
|
||||||
|
|
||||||
#: judge/forms.py:471
|
#: judge/forms.py:488
|
||||||
msgid "Problem with code already exists."
|
msgid "Problem with code already exists."
|
||||||
msgstr "Mã bài đã tồn tại."
|
msgstr "Mã bài đã tồn tại."
|
||||||
|
|
||||||
#: judge/forms.py:478 judge/models/contest.py:96
|
#: judge/forms.py:495 judge/models/contest.py:96
|
||||||
msgid "Contest id must be ^[a-z0-9]+$"
|
msgid "Contest id must be ^[a-z0-9]+$"
|
||||||
msgstr "Mã kỳ thi phải có dạng ^[a-z0-9]+$"
|
msgstr "Mã kỳ thi phải có dạng ^[a-z0-9]+$"
|
||||||
|
|
||||||
#: judge/forms.py:485 templates/contest/clone.html:47
|
#: judge/forms.py:502 templates/contest/clone.html:47
|
||||||
#: templates/problem/search-form.html:39
|
#: templates/problem/search-form.html:39
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Nhóm"
|
msgstr "Nhóm"
|
||||||
|
|
||||||
#: judge/forms.py:493
|
#: judge/forms.py:510
|
||||||
msgid "Contest with key already exists."
|
msgid "Contest with key already exists."
|
||||||
msgstr "Mã kỳ thi đã tồn tại."
|
msgstr "Mã kỳ thi đã tồn tại."
|
||||||
|
|
||||||
#: judge/forms.py:501
|
#: judge/forms.py:518
|
||||||
msgid "Group doesn't exist."
|
msgid "Group doesn't exist."
|
||||||
msgstr "Nhóm không tồn tại."
|
msgstr "Nhóm không tồn tại."
|
||||||
|
|
||||||
#: judge/forms.py:503
|
#: judge/forms.py:520
|
||||||
msgid "You don't have permission in this group."
|
msgid "You don't have permission in this group."
|
||||||
msgstr "Bạn không có quyền trong nhóm này."
|
msgstr "Bạn không có quyền trong nhóm này."
|
||||||
|
|
||||||
#: judge/forms.py:553
|
#: judge/forms.py:570
|
||||||
msgid "This problem is duplicated."
|
msgid "This problem is duplicated."
|
||||||
msgstr "Bài này bị lặp"
|
msgstr "Bài này bị lặp"
|
||||||
|
|
||||||
|
@ -777,12 +777,12 @@ msgid "These users will be able to view the contest, but not edit it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Những người dùng này có thể thấy kỳ thi nhưng không có quyền chỉnh sửa."
|
"Những người dùng này có thể thấy kỳ thi nhưng không có quyền chỉnh sửa."
|
||||||
|
|
||||||
#: judge/models/contest.py:126 judge/models/runtime.py:219
|
#: judge/models/contest.py:126 judge/models/runtime.py:217
|
||||||
msgid "description"
|
msgid "description"
|
||||||
msgstr "mô tả"
|
msgstr "mô tả"
|
||||||
|
|
||||||
#: judge/models/contest.py:128 judge/models/problem.py:597
|
#: judge/models/contest.py:128 judge/models/problem.py:597
|
||||||
#: judge/models/runtime.py:224
|
#: judge/models/runtime.py:222
|
||||||
msgid "problems"
|
msgid "problems"
|
||||||
msgstr "bài tập"
|
msgstr "bài tập"
|
||||||
|
|
||||||
|
@ -932,7 +932,7 @@ msgstr "riêng tư với các tổ chức"
|
||||||
|
|
||||||
#: judge/models/contest.py:239 judge/models/course.py:33
|
#: judge/models/contest.py:239 judge/models/course.py:33
|
||||||
#: judge/models/interface.py:93 judge/models/problem.py:281
|
#: judge/models/interface.py:93 judge/models/problem.py:281
|
||||||
#: judge/models/profile.py:159
|
#: judge/models/profile.py:168
|
||||||
msgid "organizations"
|
msgid "organizations"
|
||||||
msgstr "tổ chức"
|
msgstr "tổ chức"
|
||||||
|
|
||||||
|
@ -944,7 +944,7 @@ msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ th
|
||||||
msgid "OpenGraph image"
|
msgid "OpenGraph image"
|
||||||
msgstr "Hình ảnh OpenGraph"
|
msgstr "Hình ảnh OpenGraph"
|
||||||
|
|
||||||
#: judge/models/contest.py:246 judge/models/profile.py:99
|
#: judge/models/contest.py:246 judge/models/profile.py:108
|
||||||
msgid "Logo override image"
|
msgid "Logo override image"
|
||||||
msgstr "Hình ảnh ghi đè logo"
|
msgstr "Hình ảnh ghi đè logo"
|
||||||
|
|
||||||
|
@ -965,7 +965,7 @@ msgstr "tổng kết kỳ thi"
|
||||||
msgid "Plain-text, shown in meta description tag, e.g. for social media."
|
msgid "Plain-text, shown in meta description tag, e.g. for social media."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/contest.py:269 judge/models/profile.py:94
|
#: judge/models/contest.py:269 judge/models/profile.py:103
|
||||||
msgid "access code"
|
msgid "access code"
|
||||||
msgstr "mật khẩu truy cập"
|
msgstr "mật khẩu truy cập"
|
||||||
|
|
||||||
|
@ -1318,7 +1318,7 @@ msgstr "url khóa học"
|
||||||
msgid "Course name shown in URL"
|
msgid "Course name shown in URL"
|
||||||
msgstr "Tên được hiển thị trong đường dẫn"
|
msgstr "Tên được hiển thị trong đường dẫn"
|
||||||
|
|
||||||
#: judge/models/course.py:42 judge/models/profile.py:50
|
#: judge/models/course.py:42 judge/models/profile.py:59
|
||||||
msgid "Only alphanumeric and hyphens"
|
msgid "Only alphanumeric and hyphens"
|
||||||
msgstr "Chỉ chứa chữ cái và dấu gạch ngang (-)"
|
msgstr "Chỉ chứa chữ cái và dấu gạch ngang (-)"
|
||||||
|
|
||||||
|
@ -1535,7 +1535,7 @@ msgstr "đường dẫn"
|
||||||
msgid "full name"
|
msgid "full name"
|
||||||
msgstr "tên đầy đủ"
|
msgstr "tên đầy đủ"
|
||||||
|
|
||||||
#: judge/models/problem.py:88 judge/models/profile.py:55
|
#: judge/models/problem.py:88 judge/models/profile.py:64
|
||||||
#: judge/models/runtime.py:35
|
#: judge/models/runtime.py:35
|
||||||
msgid "short name"
|
msgid "short name"
|
||||||
msgstr "tên ngắn"
|
msgstr "tên ngắn"
|
||||||
|
@ -1705,7 +1705,7 @@ msgid "pdf statement"
|
||||||
msgstr "Đề bài bằng file pdf"
|
msgstr "Đề bài bằng file pdf"
|
||||||
|
|
||||||
#: judge/models/problem.py:608 judge/models/problem.py:629
|
#: judge/models/problem.py:608 judge/models/problem.py:629
|
||||||
#: judge/models/problem.py:660 judge/models/runtime.py:161
|
#: judge/models/problem.py:660 judge/models/runtime.py:159
|
||||||
msgid "language"
|
msgid "language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1956,202 +1956,212 @@ msgstr "điểm"
|
||||||
msgid "case is pretest?"
|
msgid "case is pretest?"
|
||||||
msgstr "test là pretest?"
|
msgstr "test là pretest?"
|
||||||
|
|
||||||
#: judge/models/profile.py:43
|
#: judge/models/profile.py:52
|
||||||
msgid "organization title"
|
msgid "organization title"
|
||||||
msgstr "tiêu đề tổ chức"
|
msgstr "tiêu đề tổ chức"
|
||||||
|
|
||||||
#: judge/models/profile.py:46
|
#: judge/models/profile.py:55
|
||||||
msgid "organization slug"
|
msgid "organization slug"
|
||||||
msgstr "tên ngắn đường dẫn"
|
msgstr "tên ngắn đường dẫn"
|
||||||
|
|
||||||
#: judge/models/profile.py:47
|
#: judge/models/profile.py:56
|
||||||
msgid "Organization name shown in URL"
|
msgid "Organization name shown in URL"
|
||||||
msgstr "Tên được hiển thị trong đường dẫn"
|
msgstr "Tên được hiển thị trong đường dẫn"
|
||||||
|
|
||||||
#: judge/models/profile.py:56
|
#: judge/models/profile.py:65
|
||||||
msgid "Displayed beside user name during contests"
|
msgid "Displayed beside user name during contests"
|
||||||
msgstr "Hiển thị bên cạnh tên người dùng trong kỳ thi"
|
msgstr "Hiển thị bên cạnh tên người dùng trong kỳ thi"
|
||||||
|
|
||||||
#: judge/models/profile.py:59
|
#: judge/models/profile.py:68
|
||||||
msgid "organization description"
|
msgid "organization description"
|
||||||
msgstr "mô tả tổ chức"
|
msgstr "mô tả tổ chức"
|
||||||
|
|
||||||
#: judge/models/profile.py:63
|
#: judge/models/profile.py:72
|
||||||
msgid "registrant"
|
msgid "registrant"
|
||||||
msgstr "người tạo"
|
msgstr "người tạo"
|
||||||
|
|
||||||
#: judge/models/profile.py:66
|
#: judge/models/profile.py:75
|
||||||
msgid "User who registered this organization"
|
msgid "User who registered this organization"
|
||||||
msgstr "Người tạo tổ chức"
|
msgstr "Người tạo tổ chức"
|
||||||
|
|
||||||
#: judge/models/profile.py:70
|
#: judge/models/profile.py:79
|
||||||
msgid "administrators"
|
msgid "administrators"
|
||||||
msgstr "người quản lý"
|
msgstr "người quản lý"
|
||||||
|
|
||||||
#: judge/models/profile.py:72
|
#: judge/models/profile.py:81
|
||||||
msgid "Those who can edit this organization"
|
msgid "Those who can edit this organization"
|
||||||
msgstr "Những người có thể chỉnh sửa tổ chức"
|
msgstr "Những người có thể chỉnh sửa tổ chức"
|
||||||
|
|
||||||
#: judge/models/profile.py:75
|
#: judge/models/profile.py:84
|
||||||
msgid "creation date"
|
msgid "creation date"
|
||||||
msgstr "ngày tạo"
|
msgstr "ngày tạo"
|
||||||
|
|
||||||
#: judge/models/profile.py:78
|
#: judge/models/profile.py:87
|
||||||
msgid "is open organization?"
|
msgid "is open organization?"
|
||||||
msgstr "tổ chức mở?"
|
msgstr "tổ chức mở?"
|
||||||
|
|
||||||
#: judge/models/profile.py:79
|
#: judge/models/profile.py:88
|
||||||
msgid "Allow joining organization"
|
msgid "Allow joining organization"
|
||||||
msgstr "Cho phép mọi người tham gia tổ chức"
|
msgstr "Cho phép mọi người tham gia tổ chức"
|
||||||
|
|
||||||
#: judge/models/profile.py:83
|
#: judge/models/profile.py:92
|
||||||
msgid "maximum size"
|
msgid "maximum size"
|
||||||
msgstr "số lượng thành viên tối đa"
|
msgstr "số lượng thành viên tối đa"
|
||||||
|
|
||||||
#: judge/models/profile.py:87
|
#: judge/models/profile.py:96
|
||||||
msgid ""
|
msgid ""
|
||||||
"Maximum amount of users in this organization, only applicable to private "
|
"Maximum amount of users in this organization, only applicable to private "
|
||||||
"organizations"
|
"organizations"
|
||||||
msgstr "Số người tối đa trong tổ chức, chỉ áp dụng với tổ chức riêng tư"
|
msgstr "Số người tối đa trong tổ chức, chỉ áp dụng với tổ chức riêng tư"
|
||||||
|
|
||||||
#: judge/models/profile.py:93
|
#: judge/models/profile.py:102
|
||||||
msgid "Student access code"
|
msgid "Student access code"
|
||||||
msgstr "Mã truy cập cho học sinh"
|
msgstr "Mã truy cập cho học sinh"
|
||||||
|
|
||||||
#: judge/models/profile.py:104
|
#: judge/models/profile.py:113
|
||||||
msgid ""
|
msgid ""
|
||||||
"This image will replace the default site logo for users viewing the "
|
"This image will replace the default site logo for users viewing the "
|
||||||
"organization."
|
"organization."
|
||||||
msgstr "Ảnh này sẽ thay thế logo mặc định khi ở trong tổ chức."
|
msgstr "Ảnh này sẽ thay thế logo mặc định khi ở trong tổ chức."
|
||||||
|
|
||||||
#: judge/models/profile.py:158 judge/models/profile.py:190
|
#: judge/models/profile.py:167 judge/models/profile.py:199
|
||||||
#: judge/models/profile.py:434 judge/models/profile.py:509
|
#: judge/models/profile.py:468 judge/models/profile.py:543
|
||||||
msgid "organization"
|
msgid "organization"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:165
|
#: judge/models/profile.py:174
|
||||||
msgid "user associated"
|
msgid "user associated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:168
|
#: judge/models/profile.py:177
|
||||||
msgid "self-description"
|
msgid "self-description"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:172
|
#: judge/models/profile.py:181
|
||||||
msgid "location"
|
msgid "location"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:178
|
#: judge/models/profile.py:187
|
||||||
msgid "preferred language"
|
msgid "preferred language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:186
|
#: judge/models/profile.py:195
|
||||||
msgid "last access time"
|
msgid "last access time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:187
|
#: judge/models/profile.py:196
|
||||||
msgid "last IP"
|
msgid "last IP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:198
|
#: judge/models/profile.py:207
|
||||||
msgid "display rank"
|
msgid "display rank"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:207
|
#: judge/models/profile.py:216
|
||||||
msgid "comment mute"
|
msgid "comment mute"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:208
|
#: judge/models/profile.py:217
|
||||||
msgid "Some users are at their best when silent."
|
msgid "Some users are at their best when silent."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:212
|
#: judge/models/profile.py:221
|
||||||
msgid "unlisted user"
|
msgid "unlisted user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:213
|
#: judge/models/profile.py:222
|
||||||
msgid "User will not be ranked."
|
msgid "User will not be ranked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:217
|
#: judge/models/profile.py:228
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Banned from joining"
|
|
||||||
msgid "banned from voting"
|
|
||||||
msgstr "Bị cấm tham gia"
|
|
||||||
|
|
||||||
#: judge/models/profile.py:218
|
|
||||||
msgid "User will not be able to vote on problems' point values."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: judge/models/profile.py:224
|
|
||||||
msgid "current contest"
|
msgid "current contest"
|
||||||
msgstr "kỳ thi hiện tại"
|
msgstr "kỳ thi hiện tại"
|
||||||
|
|
||||||
#: judge/models/profile.py:231
|
#: judge/models/profile.py:235
|
||||||
msgid "2FA enabled"
|
msgid "2FA enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:233
|
#: judge/models/profile.py:237
|
||||||
msgid "check to enable TOTP-based two factor authentication"
|
msgid "check to enable TOTP-based two factor authentication"
|
||||||
msgstr "đánh dấu để sử dụng TOTP-based two factor authentication"
|
msgstr "đánh dấu để sử dụng TOTP-based two factor authentication"
|
||||||
|
|
||||||
#: judge/models/profile.py:239
|
#: judge/models/profile.py:243
|
||||||
msgid "TOTP key"
|
msgid "TOTP key"
|
||||||
msgstr "mã TOTP"
|
msgstr "mã TOTP"
|
||||||
|
|
||||||
#: judge/models/profile.py:240
|
#: judge/models/profile.py:244
|
||||||
msgid "32 character base32-encoded key for TOTP"
|
msgid "32 character base32-encoded key for TOTP"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:242
|
#: judge/models/profile.py:246
|
||||||
msgid "TOTP key must be empty or base32"
|
msgid "TOTP key must be empty or base32"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/profile.py:246
|
#: judge/models/profile.py:250
|
||||||
msgid "internal notes"
|
msgid "internal notes"
|
||||||
msgstr "ghi chú nội bộ"
|
msgstr "ghi chú nội bộ"
|
||||||
|
|
||||||
#: judge/models/profile.py:249
|
#: judge/models/profile.py:253
|
||||||
msgid "Notes for administrators regarding this user."
|
msgid "Notes for administrators regarding this user."
|
||||||
msgstr "Ghi chú riêng cho quản trị viên."
|
msgstr "Ghi chú riêng cho quản trị viên."
|
||||||
|
|
||||||
#: judge/models/profile.py:254
|
#: judge/models/profile.py:258
|
||||||
msgid "Custom background"
|
msgid "Custom background"
|
||||||
msgstr "Background tự chọn"
|
msgstr "Background tự chọn"
|
||||||
|
|
||||||
#: judge/models/profile.py:257
|
#: judge/models/profile.py:261
|
||||||
msgid "CSS custom background properties: url(\"image_url\"), color, etc"
|
msgid "CSS custom background properties: url(\"image_url\"), color, etc"
|
||||||
msgstr "CSS background tự chọn. Ví dụ: url(\"image_url\"), white, ..."
|
msgstr "CSS background tự chọn. Ví dụ: url(\"image_url\"), white, ..."
|
||||||
|
|
||||||
#: judge/models/profile.py:421
|
#: judge/models/profile.py:425
|
||||||
msgid "user profile"
|
msgid "user profile"
|
||||||
msgstr "thông tin người dùng"
|
msgstr "thông tin người dùng"
|
||||||
|
|
||||||
#: judge/models/profile.py:422
|
#: judge/models/profile.py:426
|
||||||
msgid "user profiles"
|
msgid "user profiles"
|
||||||
msgstr "thông tin người dùng"
|
msgstr "thông tin người dùng"
|
||||||
|
|
||||||
#: judge/models/profile.py:438
|
#: judge/models/profile.py:432
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "associated page"
|
||||||
|
msgid "profile associated"
|
||||||
|
msgstr "trang tương ứng"
|
||||||
|
|
||||||
|
#: judge/models/profile.py:439
|
||||||
|
msgid "t-shirt size"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: judge/models/profile.py:444
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "date of publishing"
|
||||||
|
msgid "date of birth"
|
||||||
|
msgstr "Ngày công bố"
|
||||||
|
|
||||||
|
#: judge/models/profile.py:450
|
||||||
|
msgid "address"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: judge/models/profile.py:472
|
||||||
msgid "request time"
|
msgid "request time"
|
||||||
msgstr "thời gian đăng ký"
|
msgstr "thời gian đăng ký"
|
||||||
|
|
||||||
#: judge/models/profile.py:441
|
#: judge/models/profile.py:475
|
||||||
msgid "state"
|
msgid "state"
|
||||||
msgstr "trạng thái"
|
msgstr "trạng thái"
|
||||||
|
|
||||||
#: judge/models/profile.py:448
|
#: judge/models/profile.py:482
|
||||||
msgid "reason"
|
msgid "reason"
|
||||||
msgstr "lý do"
|
msgstr "lý do"
|
||||||
|
|
||||||
#: judge/models/profile.py:451
|
#: judge/models/profile.py:485
|
||||||
msgid "organization join request"
|
msgid "organization join request"
|
||||||
msgstr "đơn đăng ký tham gia"
|
msgstr "đơn đăng ký tham gia"
|
||||||
|
|
||||||
#: judge/models/profile.py:452
|
#: judge/models/profile.py:486
|
||||||
msgid "organization join requests"
|
msgid "organization join requests"
|
||||||
msgstr "đơn đăng ký tham gia"
|
msgstr "đơn đăng ký tham gia"
|
||||||
|
|
||||||
#: judge/models/profile.py:514
|
#: judge/models/profile.py:548
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "last seen"
|
#| msgid "last seen"
|
||||||
msgid "last visit"
|
msgid "last visit"
|
||||||
|
@ -2244,81 +2254,81 @@ msgstr ""
|
||||||
msgid "The extension of source files, e.g., \"py\" or \"cpp\"."
|
msgid "The extension of source files, e.g., \"py\" or \"cpp\"."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:162
|
#: judge/models/runtime.py:160
|
||||||
msgid "languages"
|
msgid "languages"
|
||||||
msgstr "ngôn ngữ"
|
msgstr "ngôn ngữ"
|
||||||
|
|
||||||
#: judge/models/runtime.py:176
|
#: judge/models/runtime.py:174
|
||||||
msgid "language to which this runtime belongs"
|
msgid "language to which this runtime belongs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:180
|
#: judge/models/runtime.py:178
|
||||||
msgid "judge on which this runtime exists"
|
msgid "judge on which this runtime exists"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:182
|
#: judge/models/runtime.py:180
|
||||||
msgid "runtime name"
|
msgid "runtime name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:184
|
#: judge/models/runtime.py:182
|
||||||
msgid "runtime version"
|
msgid "runtime version"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:187
|
#: judge/models/runtime.py:185
|
||||||
msgid "order in which to display this runtime"
|
msgid "order in which to display this runtime"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/models/runtime.py:193
|
#: judge/models/runtime.py:191
|
||||||
msgid "Server name, hostname-style"
|
msgid "Server name, hostname-style"
|
||||||
msgstr "Tên web"
|
msgstr "Tên web"
|
||||||
|
|
||||||
#: judge/models/runtime.py:196
|
#: judge/models/runtime.py:194
|
||||||
msgid "time of creation"
|
msgid "time of creation"
|
||||||
msgstr "ngày tạo"
|
msgstr "ngày tạo"
|
||||||
|
|
||||||
#: judge/models/runtime.py:200
|
#: judge/models/runtime.py:198
|
||||||
msgid "A key to authenticate this judge"
|
msgid "A key to authenticate this judge"
|
||||||
msgstr "Chìa khóa xác thực"
|
msgstr "Chìa khóa xác thực"
|
||||||
|
|
||||||
#: judge/models/runtime.py:201
|
#: judge/models/runtime.py:199
|
||||||
msgid "authentication key"
|
msgid "authentication key"
|
||||||
msgstr "mã xác thực"
|
msgstr "mã xác thực"
|
||||||
|
|
||||||
#: judge/models/runtime.py:204
|
#: judge/models/runtime.py:202
|
||||||
msgid "block judge"
|
msgid "block judge"
|
||||||
msgstr "chặn máy chấm"
|
msgstr "chặn máy chấm"
|
||||||
|
|
||||||
#: judge/models/runtime.py:207
|
#: judge/models/runtime.py:205
|
||||||
msgid ""
|
msgid ""
|
||||||
"Whether this judge should be blocked from connecting, even if its key is "
|
"Whether this judge should be blocked from connecting, even if its key is "
|
||||||
"correct."
|
"correct."
|
||||||
msgstr "Quyết định có chặn máy chấm, ngay cả khi mã xác thực đúng."
|
msgstr "Quyết định có chặn máy chấm, ngay cả khi mã xác thực đúng."
|
||||||
|
|
||||||
#: judge/models/runtime.py:211
|
#: judge/models/runtime.py:209
|
||||||
msgid "judge online status"
|
msgid "judge online status"
|
||||||
msgstr "trạng thái online của máy chấm"
|
msgstr "trạng thái online của máy chấm"
|
||||||
|
|
||||||
#: judge/models/runtime.py:212
|
#: judge/models/runtime.py:210
|
||||||
msgid "judge start time"
|
msgid "judge start time"
|
||||||
msgstr "thời gian khởi đầu máy chấm"
|
msgstr "thời gian khởi đầu máy chấm"
|
||||||
|
|
||||||
#: judge/models/runtime.py:213
|
#: judge/models/runtime.py:211
|
||||||
msgid "response time"
|
msgid "response time"
|
||||||
msgstr "thời gian trả lời"
|
msgstr "thời gian trả lời"
|
||||||
|
|
||||||
#: judge/models/runtime.py:215
|
#: judge/models/runtime.py:213
|
||||||
msgid "system load"
|
msgid "system load"
|
||||||
msgstr "lưu lượng xử lý"
|
msgstr "lưu lượng xử lý"
|
||||||
|
|
||||||
#: judge/models/runtime.py:217
|
#: judge/models/runtime.py:215
|
||||||
msgid "Load for the last minute, divided by processors to be fair."
|
msgid "Load for the last minute, divided by processors to be fair."
|
||||||
msgstr "Lưu lượng được chia đều."
|
msgstr "Lưu lượng được chia đều."
|
||||||
|
|
||||||
#: judge/models/runtime.py:227 judge/models/runtime.py:269
|
#: judge/models/runtime.py:225 judge/models/runtime.py:267
|
||||||
msgid "judges"
|
msgid "judges"
|
||||||
msgstr "máy chấm"
|
msgstr "máy chấm"
|
||||||
|
|
||||||
#: judge/models/runtime.py:268
|
#: judge/models/runtime.py:266
|
||||||
msgid "judge"
|
msgid "judge"
|
||||||
msgstr "máy chấm"
|
msgstr "máy chấm"
|
||||||
|
|
||||||
|
@ -2965,7 +2975,7 @@ msgstr "Thay đổi Email"
|
||||||
msgid "Change Email"
|
msgid "Change Email"
|
||||||
msgstr "Thay đổi Email"
|
msgstr "Thay đổi Email"
|
||||||
|
|
||||||
#: judge/views/email.py:83 templates/user/edit-profile.html:113
|
#: judge/views/email.py:83 templates/user/edit-profile.html:127
|
||||||
msgid "Change email"
|
msgid "Change email"
|
||||||
msgstr "Thay đổi email"
|
msgstr "Thay đổi email"
|
||||||
|
|
||||||
|
@ -3021,7 +3031,7 @@ msgstr "Runtimes"
|
||||||
msgid "Markdown Editor"
|
msgid "Markdown Editor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: judge/views/notification.py:29
|
#: judge/views/notification.py:32
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Notifications (%d unseen)"
|
msgid "Notifications (%d unseen)"
|
||||||
msgstr "Thông báo (%d chưa xem)"
|
msgstr "Thông báo (%d chưa xem)"
|
||||||
|
@ -3373,7 +3383,7 @@ msgstr "Các bài nộp tốt nhất cho <a href=\"{1}\">{0}</a>"
|
||||||
msgid "Username"
|
msgid "Username"
|
||||||
msgstr "Tên đăng nhập"
|
msgstr "Tên đăng nhập"
|
||||||
|
|
||||||
#: judge/views/register.py:42 templates/user/edit-profile.html:137
|
#: judge/views/register.py:42 templates/user/edit-profile.html:151
|
||||||
msgid "Preferred language"
|
msgid "Preferred language"
|
||||||
msgstr "Ngôn ngữ ưa thích"
|
msgstr "Ngôn ngữ ưa thích"
|
||||||
|
|
||||||
|
@ -3451,50 +3461,50 @@ msgstr "Bài nộp của %(user)s cho bài %(problem)s"
|
||||||
msgid "All submissions"
|
msgid "All submissions"
|
||||||
msgstr "Tất cả bài nộp"
|
msgstr "Tất cả bài nộp"
|
||||||
|
|
||||||
#: judge/views/submission.py:546 judge/views/submission.py:551
|
#: judge/views/submission.py:548 judge/views/submission.py:553
|
||||||
msgid "All my submissions"
|
msgid "All my submissions"
|
||||||
msgstr "Tất cả bài nộp của tôi"
|
msgstr "Tất cả bài nộp của tôi"
|
||||||
|
|
||||||
#: judge/views/submission.py:547
|
#: judge/views/submission.py:549
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "All submissions by %s"
|
msgid "All submissions by %s"
|
||||||
msgstr "Tất cả bài nộp của %s"
|
msgstr "Tất cả bài nộp của %s"
|
||||||
|
|
||||||
#: judge/views/submission.py:553
|
#: judge/views/submission.py:555
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "All submissions by <a href=\"{1}\">{0}</a>"
|
msgid "All submissions by <a href=\"{1}\">{0}</a>"
|
||||||
msgstr "Tất cả bài nộp của <a href=\"{1}\">{0}</a>"
|
msgstr "Tất cả bài nộp của <a href=\"{1}\">{0}</a>"
|
||||||
|
|
||||||
#: judge/views/submission.py:574
|
#: judge/views/submission.py:576
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "All submissions"
|
#| msgid "All submissions"
|
||||||
msgid "All friend submissions"
|
msgid "All friend submissions"
|
||||||
msgstr "Tất cả bài nộp"
|
msgstr "Tất cả bài nộp"
|
||||||
|
|
||||||
#: judge/views/submission.py:603
|
#: judge/views/submission.py:605
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "All submissions for %s"
|
msgid "All submissions for %s"
|
||||||
msgstr "Tất cả bài nộp cho %s"
|
msgstr "Tất cả bài nộp cho %s"
|
||||||
|
|
||||||
#: judge/views/submission.py:631
|
#: judge/views/submission.py:633
|
||||||
msgid "Must pass a problem"
|
msgid "Must pass a problem"
|
||||||
msgstr "Phải làm được một bài"
|
msgstr "Phải làm được một bài"
|
||||||
|
|
||||||
#: judge/views/submission.py:689
|
#: judge/views/submission.py:691
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "My submissions for %(problem)s"
|
msgid "My submissions for %(problem)s"
|
||||||
msgstr "Bài nộp của tôi cho %(problem)s"
|
msgstr "Bài nộp của tôi cho %(problem)s"
|
||||||
|
|
||||||
#: judge/views/submission.py:690
|
#: judge/views/submission.py:692
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(user)s's submissions for %(problem)s"
|
msgid "%(user)s's submissions for %(problem)s"
|
||||||
msgstr "Các bài nộp của %(user)s cho %(problem)s"
|
msgstr "Các bài nộp của %(user)s cho %(problem)s"
|
||||||
|
|
||||||
#: judge/views/submission.py:832
|
#: judge/views/submission.py:834
|
||||||
msgid "Must pass a contest"
|
msgid "Must pass a contest"
|
||||||
msgstr "Phải qua một kỳ thi"
|
msgstr "Phải qua một kỳ thi"
|
||||||
|
|
||||||
#: judge/views/submission.py:862
|
#: judge/views/submission.py:864
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<a href=\"{1}\">{0}</a>'s submissions for <a href=\"{3}\">{2}</a> in <a href="
|
"<a href=\"{1}\">{0}</a>'s submissions for <a href=\"{3}\">{2}</a> in <a href="
|
||||||
|
@ -3503,7 +3513,7 @@ msgstr ""
|
||||||
"Các bài nộp của <a href=\"{1}\">{0}</a> cho <a href=\"{3}\">{2}</a> trong <a "
|
"Các bài nộp của <a href=\"{1}\">{0}</a> cho <a href=\"{3}\">{2}</a> trong <a "
|
||||||
"href=\"{5}\">{4}</a>"
|
"href=\"{5}\">{4}</a>"
|
||||||
|
|
||||||
#: judge/views/submission.py:874
|
#: judge/views/submission.py:876
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"<a href=\"{1}\">{0}</a>'s submissions for problem {2} in <a href=\"{4}\">{3}"
|
"<a href=\"{1}\">{0}</a>'s submissions for problem {2} in <a href=\"{4}\">{3}"
|
||||||
|
@ -3512,7 +3522,7 @@ msgstr ""
|
||||||
"Các bài nộp của <a href=\"{1}\">{0}</a> cho bài {2} trong <a href=\"{4}\">{3}"
|
"Các bài nộp của <a href=\"{1}\">{0}</a> cho bài {2} trong <a href=\"{4}\">{3}"
|
||||||
"</a>"
|
"</a>"
|
||||||
|
|
||||||
#: judge/views/submission.py:1008
|
#: judge/views/submission.py:1010
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "You do not have the permission to rejudge submissions."
|
#| msgid "You do not have the permission to rejudge submissions."
|
||||||
msgid "You don't have permission to access."
|
msgid "You don't have permission to access."
|
||||||
|
@ -3606,22 +3616,22 @@ msgstr "j M, Y"
|
||||||
msgid "M j, Y, G:i"
|
msgid "M j, Y, G:i"
|
||||||
msgstr "j M, Y, G:i"
|
msgstr "j M, Y, G:i"
|
||||||
|
|
||||||
#: judge/views/user.py:403
|
#: judge/views/user.py:406
|
||||||
msgid "Updated on site"
|
msgid "Updated on site"
|
||||||
msgstr "Được cập nhật trên web"
|
msgstr "Được cập nhật trên web"
|
||||||
|
|
||||||
#: judge/views/user.py:418 templates/admin/auth/user/change_form.html:14
|
#: judge/views/user.py:423 templates/admin/auth/user/change_form.html:14
|
||||||
#: templates/admin/auth/user/change_form.html:17 templates/base.html:204
|
#: templates/admin/auth/user/change_form.html:17 templates/base.html:204
|
||||||
#: templates/user/user-tabs.html:12
|
#: templates/user/user-tabs.html:12
|
||||||
msgid "Edit profile"
|
msgid "Edit profile"
|
||||||
msgstr "Chỉnh sửa thông tin"
|
msgstr "Chỉnh sửa thông tin"
|
||||||
|
|
||||||
#: judge/views/user.py:428 templates/user/user-left-sidebar.html:2
|
#: judge/views/user.py:433 templates/user/user-left-sidebar.html:2
|
||||||
#: templates/user/user-list-tabs.html:4
|
#: templates/user/user-list-tabs.html:4
|
||||||
msgid "Leaderboard"
|
msgid "Leaderboard"
|
||||||
msgstr "Xếp hạng"
|
msgstr "Xếp hạng"
|
||||||
|
|
||||||
#: judge/views/user.py:528
|
#: judge/views/user.py:533
|
||||||
msgid "Import Users"
|
msgid "Import Users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4346,11 +4356,11 @@ msgstr "Khôi phục kết quả"
|
||||||
msgid "Disqualify"
|
msgid "Disqualify"
|
||||||
msgstr "Hủy kết quả"
|
msgstr "Hủy kết quả"
|
||||||
|
|
||||||
#: templates/contest/ranking-table.html:59 templates/user/edit-profile.html:93
|
#: templates/contest/ranking-table.html:59
|
||||||
msgid "Fullname"
|
msgid "Fullname"
|
||||||
msgstr "Tên đầy đủ"
|
msgstr "Tên đầy đủ"
|
||||||
|
|
||||||
#: templates/contest/ranking-table.html:60 templates/user/edit-profile.html:97
|
#: templates/contest/ranking-table.html:60 templates/user/edit-profile.html:99
|
||||||
#: templates/user/import/table_csv.html:7
|
#: templates/user/import/table_csv.html:7
|
||||||
msgid "School"
|
msgid "School"
|
||||||
msgstr "Trường"
|
msgstr "Trường"
|
||||||
|
@ -5841,47 +5851,63 @@ msgstr "Top Rating"
|
||||||
msgid "Top Score"
|
msgid "Top Score"
|
||||||
msgstr "Top Score"
|
msgstr "Top Score"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:104
|
#: templates/user/edit-profile.html:95
|
||||||
|
msgid "Full name"
|
||||||
|
msgstr "Họ tên"
|
||||||
|
|
||||||
|
#: templates/user/edit-profile.html:103
|
||||||
|
msgid "Date of birth"
|
||||||
|
msgstr "Ngày sinh"
|
||||||
|
|
||||||
|
#: templates/user/edit-profile.html:107
|
||||||
|
msgid "Address"
|
||||||
|
msgstr "Địa chỉ"
|
||||||
|
|
||||||
|
#: templates/user/edit-profile.html:111
|
||||||
|
msgid "T-Shirt size"
|
||||||
|
msgstr "Kích cỡ áo"
|
||||||
|
|
||||||
|
#: templates/user/edit-profile.html:118
|
||||||
msgid "Change your password"
|
msgid "Change your password"
|
||||||
msgstr "Đổi mật khẩu"
|
msgstr "Đổi mật khẩu"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:118
|
#: templates/user/edit-profile.html:132
|
||||||
msgid "Avatar"
|
msgid "Avatar"
|
||||||
msgstr "Ảnh đại diện"
|
msgstr "Ảnh đại diện"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:124
|
#: templates/user/edit-profile.html:138
|
||||||
msgid "Self-description"
|
msgid "Self-description"
|
||||||
msgstr "Tự giới thiệu"
|
msgstr "Tự giới thiệu"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:132
|
#: templates/user/edit-profile.html:146
|
||||||
msgid "Select your closest major city"
|
msgid "Select your closest major city"
|
||||||
msgstr "Chọn thành phố gần nhất"
|
msgstr "Chọn thành phố gần nhất"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:141
|
#: templates/user/edit-profile.html:155
|
||||||
msgid "Editor theme"
|
msgid "Editor theme"
|
||||||
msgstr "Giao diện cho code editor"
|
msgstr "Giao diện cho code editor"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:151
|
#: templates/user/edit-profile.html:165
|
||||||
msgid "Two Factor Authentication is enabled."
|
msgid "Two Factor Authentication is enabled."
|
||||||
msgstr "Two Factor Authentication đã được kích hoạt."
|
msgstr "Two Factor Authentication đã được kích hoạt."
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:155
|
#: templates/user/edit-profile.html:169
|
||||||
msgid "Disable"
|
msgid "Disable"
|
||||||
msgstr "Tắt"
|
msgstr "Tắt"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:158
|
#: templates/user/edit-profile.html:172
|
||||||
msgid "Two Factor Authentication is disabled."
|
msgid "Two Factor Authentication is disabled."
|
||||||
msgstr "Two Factor Authentication chưa kích hoạt."
|
msgstr "Two Factor Authentication chưa kích hoạt."
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:159
|
#: templates/user/edit-profile.html:173
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
msgstr "Bật"
|
msgstr "Bật"
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:163
|
#: templates/user/edit-profile.html:177
|
||||||
msgid "CSS background"
|
msgid "CSS background"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/user/edit-profile.html:167
|
#: templates/user/edit-profile.html:181
|
||||||
msgid "Update profile"
|
msgid "Update profile"
|
||||||
msgstr "Cập nhật thông tin"
|
msgstr "Cập nhật thông tin"
|
||||||
|
|
||||||
|
@ -6093,6 +6119,11 @@ msgstr "Thông tin"
|
||||||
msgid "Check all"
|
msgid "Check all"
|
||||||
msgstr "Chọn tất cả"
|
msgstr "Chọn tất cả"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
#~| msgid "Banned from joining"
|
||||||
|
#~ msgid "banned from voting"
|
||||||
|
#~ msgstr "Bị cấm tham gia"
|
||||||
|
|
||||||
#~ msgid "Already in contest"
|
#~ msgid "Already in contest"
|
||||||
#~ msgstr "Đã ở trong kỳ thi"
|
#~ msgstr "Đã ở trong kỳ thi"
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
&[type=text], &[type=password], &[type=email], &[type=number], &[type=datetime-local] {
|
&[type=text], &[type=password], &[type=email], &[type=number], &[type=datetime-local], &[type=date] {
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
color: #555;
|
color: #555;
|
||||||
background: #FFF none;
|
background: #FFF none;
|
||||||
|
|
|
@ -77,11 +77,13 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div id="center-float">
|
<div id="center-float">
|
||||||
<form id="edit-form" action="" method="post" class="form-area" enctype="multipart/form-data">
|
<form id="edit-form" action="" method="post" class="form-area" enctype="multipart/form-data">
|
||||||
{% if form.errors or form_user.errors %}
|
{% if form.errors or form_user.errors or form_info.errors %}
|
||||||
<div class="alert alert-danger alert-dismissable">
|
<div class="alert alert-danger alert-dismissable">
|
||||||
<a href="#" class="close">x</a>
|
<a href="#" class="close">x</a>
|
||||||
{{ form.errors }}
|
{{ form.errors }}
|
||||||
<br>
|
<br>
|
||||||
|
{{ form_info.errors }}
|
||||||
|
<br>
|
||||||
{{ form_user.errors }}
|
{{ form_user.errors }}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -90,13 +92,25 @@
|
||||||
|
|
||||||
<table class="block-header grayed main-info">
|
<table class="block-header grayed main-info">
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ _('Fullname') }}: </td>
|
<td> {{ _('Full name') }}: </td>
|
||||||
<td> {{ form_user.first_name }} </td>
|
<td> {{ form_user.first_name }} </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ _('School') }}: </td>
|
<td> {{ _('School') }}: </td>
|
||||||
<td> {{ form_user.last_name }} </td>
|
<td> {{ form_user.last_name }} </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> {{ _('Date of birth') }}: </td>
|
||||||
|
<td> {{ form_info.date_of_birth }} </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> {{ _('Address') }}: </td>
|
||||||
|
<td> {{ form_info.address }} </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td> {{ _('T-Shirt size') }}: </td>
|
||||||
|
<td> {{ form_info.tshirt_size }} </td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ _('Password') }}: </td>
|
<td> {{ _('Password') }}: </td>
|
||||||
<td>
|
<td>
|
||||||
|
|
Loading…
Reference in a new issue