Merge pull request #16 from LQDJudge/master

Merge from master
This commit is contained in:
Phuoc Dinh Le 2022-02-26 20:11:42 -06:00 committed by GitHub
commit 127284e812
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 303 additions and 145 deletions

View file

@ -375,7 +375,8 @@ def get_or_create_room(request):
# TODO: each user can only create <= 300 rooms # TODO: each user can only create <= 300 rooms
room = get_room(other_user, user) room = get_room(other_user, user)
for u in [other_user, user]: for u in [other_user, user]:
user_room, _ = UserRoom.objects.get_or_create(user=u, room=room) user_room, created = UserRoom.objects.get_or_create(user=u, room=room)
if created:
user_room.last_seen = timezone.now() user_room.last_seen = timezone.now()
user_room.save() user_room.save()

View file

@ -1,4 +1,4 @@
from chat_box.views import * import chat_box.views as chat
from django.conf import settings from django.conf import settings
from django.conf.urls import include, url from django.conf.urls import include, url
@ -280,6 +280,7 @@ urlpatterns = [
url(r'^mailgun/mail_activate/$', mailgun.MailgunActivationView.as_view(), name='mailgun_activate'), url(r'^mailgun/mail_activate/$', mailgun.MailgunActivationView.as_view(), name='mailgun_activate'),
url(r'^widgets/', include([ url(r'^widgets/', include([
url(r'^contest_mode$', contests.update_contest_mode, name='contest_mode_ajax'),
url(r'^rejudge$', widgets.rejudge_submission, name='submission_rejudge'), url(r'^rejudge$', widgets.rejudge_submission, name='submission_rejudge'),
url(r'^single_submission$', submission.single_submission_query, name='submission_single_query'), url(r'^single_submission$', submission.single_submission_query, name='submission_single_query'),
url(r'^submission_testcases$', submission.SubmissionTestCaseQuery.as_view(), name='submission_testcases_query'), url(r'^submission_testcases$', submission.SubmissionTestCaseQuery.as_view(), name='submission_testcases_query'),
@ -376,16 +377,16 @@ urlpatterns = [
url(r'^custom_checker_sample/', about.custom_checker_sample, name='custom_checker_sample'), url(r'^custom_checker_sample/', about.custom_checker_sample, name='custom_checker_sample'),
url(r'^chat/', include([ url(r'^chat/', include([
url(r'^(?P<room_id>\d*)$', login_required(ChatView.as_view()), name='chat'), url(r'^(?P<room_id>\d*)$', login_required(chat.ChatView.as_view()), name='chat'),
url(r'^delete/$', delete_message, name='delete_chat_message'), url(r'^delete/$', chat.delete_message, name='delete_chat_message'),
url(r'^post/$', post_message, name='post_chat_message'), url(r'^post/$', chat.post_message, name='post_chat_message'),
url(r'^ajax$', chat_message_ajax, name='chat_message_ajax'), url(r'^ajax$', chat.chat_message_ajax, name='chat_message_ajax'),
url(r'^online_status/ajax$', online_status_ajax, name='online_status_ajax'), url(r'^online_status/ajax$', chat.online_status_ajax, name='online_status_ajax'),
url(r'^get_or_create_room$', get_or_create_room, name='get_or_create_room'), url(r'^get_or_create_room$', chat.get_or_create_room, name='get_or_create_room'),
url(r'^update_last_seen$', update_last_seen, name='update_last_seen'), url(r'^update_last_seen$', chat.update_last_seen, name='update_last_seen'),
url(r'^online_status/user/ajax$', user_online_status_ajax, name='user_online_status_ajax'), url(r'^online_status/user/ajax$', chat.user_online_status_ajax, name='user_online_status_ajax'),
url(r'^toggle_ignore/(?P<user_id>\d+)$', toggle_ignore, name='toggle_ignore'), url(r'^toggle_ignore/(?P<user_id>\d+)$', chat.toggle_ignore, name='toggle_ignore'),
url(r'^get_unread_boxes$', get_unread_boxes, name='get_unread_boxes'), url(r'^get_unread_boxes$', chat.get_unread_boxes, name='get_unread_boxes'),
])), ])),
url(r'^notifications/', url(r'^notifications/',

View file

@ -57,7 +57,9 @@ class ContestMiddleware(object):
profile.update_contest() profile.update_contest()
request.participation = profile.current_contest request.participation = profile.current_contest
request.in_contest = request.participation is not None request.in_contest = request.participation is not None
request.contest_mode = request.session.get('contest_mode', True)
else: else:
request.in_contest = False request.in_contest = False
request.participation = None request.participation = None
request.in_contest_mode = request.in_contest and request.contest_mode
return self.get_response(request) return self.get_response(request)

View file

@ -286,7 +286,11 @@ def get_problem_case(problem, files):
s.decode('utf-8') s.decode('utf-8')
break break
except UnicodeDecodeError: except UnicodeDecodeError:
s += f.read(1) next_char = f.read(1)
if next_char:
s += next_char
else:
raise Exception('File %s is not able to decode in utf-8' % file)
qs = get_visible_content(s) qs = get_visible_content(s)
cache.set(cache_key, qs, 86400) cache.set(cache_key, qs, 86400)
result[file] = qs result[file] = qs

View file

@ -15,7 +15,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.db import IntegrityError from django.db import IntegrityError
from django.db.models import Case, Count, F, FloatField, IntegerField, Max, Min, Q, Sum, Value, When from django.db.models import Case, Count, F, FloatField, IntegerField, Max, Min, Q, Sum, Value, When
from django.db.models.expressions import CombinedExpression from django.db.models.expressions import CombinedExpression
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect, JsonResponse from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect, JsonResponse, HttpResponseNotAllowed
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.template.defaultfilters import date as date_filter from django.template.defaultfilters import date as date_filter
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
@ -46,7 +46,7 @@ from judge.widgets import HeavyPreviewPageDownWidget
__all__ = ['ContestList', 'ContestDetail', 'ContestRanking', 'ContestJoin', 'ContestLeave', 'ContestCalendar', __all__ = ['ContestList', 'ContestDetail', 'ContestRanking', 'ContestJoin', 'ContestLeave', 'ContestCalendar',
'ContestClone', 'ContestStats', 'ContestMossView', 'ContestMossDelete', 'contest_ranking_ajax', 'ContestClone', 'ContestStats', 'ContestMossView', 'ContestMossDelete', 'contest_ranking_ajax',
'ContestParticipationList', 'ContestParticipationDisqualify', 'get_contest_ranking_list', 'ContestParticipationList', 'ContestParticipationDisqualify', 'get_contest_ranking_list',
'base_contest_ranking_list', 'ContestClarificationView'] 'base_contest_ranking_list', 'ContestClarificationView', 'update_contest_mode']
def _find_contest(request, key, private_check=True): def _find_contest(request, key, private_check=True):
@ -428,6 +428,7 @@ class ContestLeave(LoginRequiredMixin, ContestMixin, BaseDetailView):
_('You are not in contest "%s".') % contest.key, 404) _('You are not in contest "%s".') % contest.key, 404)
profile.remove_contest() profile.remove_contest()
request.session['contest_mode'] = True # reset contest_mode
return HttpResponseRedirect(reverse('contest_view', args=(contest.key,))) return HttpResponseRedirect(reverse('contest_view', args=(contest.key,)))
@ -953,3 +954,12 @@ class ContestClarificationAjax(ContestMixin, DetailView):
cla['order'] = self.object.get_label_for_problem(problems.index(cla['problem'])) cla['order'] = self.object.get_label_for_problem(problems.index(cla['problem']))
return JsonResponse(queryset, safe=False, json_dumps_params={'ensure_ascii': False}) return JsonResponse(queryset, safe=False, json_dumps_params={'ensure_ascii': False})
def update_contest_mode(request):
if not request.is_ajax() or not request.method=='POST':
return HttpResponseNotAllowed(['POST'])
old_mode = request.session.get('contest_mode', True)
request.session['contest_mode'] = not old_mode
return HttpResponse()

View file

@ -71,7 +71,8 @@ class ProblemMixin(object):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
try: try:
return super(ProblemMixin, self).get(request, *args, **kwargs) return super(ProblemMixin, self).get(request, *args, **kwargs)
except Http404: except Http404 as e:
print(e)
return self.no_such_problem() return self.no_such_problem()
@ -90,7 +91,8 @@ class SolvedProblemMixin(object):
@cached_property @cached_property
def in_contest(self): def in_contest(self):
return self.profile is not None and self.profile.current_contest is not None return self.profile is not None and self.profile.current_contest is not None \
and self.request.in_contest_mode
@cached_property @cached_property
def contest(self): def contest(self):
@ -120,10 +122,9 @@ class ProblemSolution(SolvedProblemMixin, ProblemMixin, TitleMixin, CommentedDet
solution = get_object_or_404(Solution, problem=self.object) solution = get_object_or_404(Solution, problem=self.object)
if (not solution.is_public or solution.publish_on > timezone.now()) and \ if (not solution.is_public or solution.publish_on > timezone.now()) and \
not self.request.user.has_perm('judge.see_private_solution') or \ not self.request.user.has_perm('judge.see_private_solution'):
(self.request.user.is_authenticated and
self.request.profile.current_contest):
raise Http404() raise Http404()
context['solution'] = solution context['solution'] = solution
context['has_solved_problem'] = self.object.id in self.get_completed_problems() context['has_solved_problem'] = self.object.id in self.get_completed_problems()
return context return context

View file

@ -249,7 +249,7 @@ def problem_init_view(request, problem):
raise Http404() raise Http404()
return render(request, 'problem/yaml.html', { return render(request, 'problem/yaml.html', {
'raw_source': data, 'highlighted_source': highlight_code(data, 'yaml'), 'raw_source': data, 'highlighted_source': highlight_code(data, 'yaml', linenos=False),
'title': _('Generated init.yml for %s') % problem.name, 'title': _('Generated init.yml for %s') % problem.name,
'content_title': mark_safe(escape(_('Generated init.yml for %s')) % ( 'content_title': mark_safe(escape(_('Generated init.yml for %s')) % (
format_html('<a href="{1}">{0}</a>', problem.name, format_html('<a href="{1}">{0}</a>', problem.name,

View file

@ -262,7 +262,8 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
@cached_property @cached_property
def in_contest(self): def in_contest(self):
return self.request.user.is_authenticated and self.request.profile.current_contest is not None return self.request.user.is_authenticated and self.request.profile.current_contest is not None \
and self.request.in_contest_mode
@cached_property @cached_property
def contest(self): def contest(self):

View file

@ -92,7 +92,8 @@ class UserPage(TitleMixin, UserMixin, DetailView):
@cached_property @cached_property
def in_contest(self): def in_contest(self):
return self.profile is not None and self.profile.current_contest is not None return self.profile is not None and self.profile.current_contest is not None \
and self.request.in_contest_mode
def get_completed_problems(self): def get_completed_problems(self):
if self.in_contest: if self.in_contest:
@ -374,8 +375,8 @@ class FixedContestRanking(ContestRanking):
def users(request): def users(request):
if request.user.is_authenticated: if request.user.is_authenticated:
if request.in_contest_mode:
participation = request.profile.current_contest participation = request.profile.current_contest
if participation is not None:
contest = participation.contest contest = participation.contest
return FixedContestRanking.as_view(contest=contest)(request, contest=contest.key) return FixedContestRanking.as_view(contest=contest)(request, contest=contest.key)
return user_list_view(request) return user_list_view(request)

View file

@ -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: 2021-12-29 13:13+0700\n" "POT-Creation-Date: 2022-01-10 18:14+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"
@ -108,7 +108,7 @@ msgstr ""
msgid "Login" msgid "Login"
msgstr "Đăng nhập" msgstr "Đăng nhập"
#: dmoj/urls.py:106 templates/base.html:207 #: dmoj/urls.py:106 templates/base.html:249
msgid "Home" msgid "Home"
msgstr "Trang chủ" msgstr "Trang chủ"
@ -217,7 +217,7 @@ msgstr "Tính toán lại kết quả"
msgid "username" msgid "username"
msgstr "tên đăng nhập" msgstr "tên đăng nhập"
#: judge/admin/contest.py:320 templates/base.html:294 #: judge/admin/contest.py:320 templates/base.html:337
msgid "virtual" msgid "virtual"
msgstr "ảo" msgstr "ảo"
@ -318,7 +318,7 @@ msgstr "Email"
#: judge/admin/profile.py:96 judge/views/register.py:29 #: judge/admin/profile.py:96 judge/views/register.py:29
#: templates/registration/registration_form.html:173 #: templates/registration/registration_form.html:173
#: templates/user/edit-profile.html:114 #: templates/user/edit-profile.html:116
msgid "Timezone" msgid "Timezone"
msgstr "Múi giờ" msgstr "Múi giờ"
@ -2438,71 +2438,71 @@ msgstr "Nhập mật khẩu truy cập cho \"%s\""
msgid "You are not in contest \"%s\"." msgid "You are not in contest \"%s\"."
msgstr "Bạn không ở trong kỳ thi \"%s\"." msgstr "Bạn không ở trong kỳ thi \"%s\"."
#: judge/views/contests.py:447 #: judge/views/contests.py:448
msgid "ContestCalendar requires integer year and month" msgid "ContestCalendar requires integer year and month"
msgstr "Lịch thi yêu cầu giá trị cho năm và tháng là số nguyên" msgstr "Lịch thi yêu cầu giá trị cho năm và tháng là số nguyên"
#: judge/views/contests.py:487 #: judge/views/contests.py:488
#, python-format #, python-format
msgid "Contests in %(month)s" msgid "Contests in %(month)s"
msgstr "Các kỳ thi trong %(month)s" msgstr "Các kỳ thi trong %(month)s"
#: judge/views/contests.py:487 #: judge/views/contests.py:488
msgid "F Y" msgid "F Y"
msgstr "F Y" msgstr "F Y"
#: judge/views/contests.py:535 #: judge/views/contests.py:536
#, python-format #, python-format
msgid "%s Statistics" msgid "%s Statistics"
msgstr "%s Thống kê" msgstr "%s Thống kê"
#: judge/views/contests.py:730 #: judge/views/contests.py:731
#, python-format #, python-format
msgid "%s Rankings" msgid "%s Rankings"
msgstr "%s Bảng điểm" msgstr "%s Bảng điểm"
#: judge/views/contests.py:738 #: judge/views/contests.py:739
msgid "???" msgid "???"
msgstr "???" msgstr "???"
#: judge/views/contests.py:754 #: judge/views/contests.py:755
#, python-format #, python-format
msgid "Your participation in %s" msgid "Your participation in %s"
msgstr "Lần tham gia trong %s" msgstr "Lần tham gia trong %s"
#: judge/views/contests.py:755 #: judge/views/contests.py:756
#, python-format #, python-format
msgid "%s's participation in %s" msgid "%s's participation in %s"
msgstr "Lần tham gia của %s trong %s" msgstr "Lần tham gia của %s trong %s"
#: judge/views/contests.py:762 #: judge/views/contests.py:763
msgid "Live" msgid "Live"
msgstr "Trực tiếp" msgstr "Trực tiếp"
#: judge/views/contests.py:774 templates/contest/contest-tabs.html:13 #: judge/views/contests.py:775 templates/contest/contest-tabs.html:13
msgid "Participation" msgid "Participation"
msgstr "Lần tham gia" msgstr "Lần tham gia"
#: judge/views/contests.py:821 #: judge/views/contests.py:822
#, python-format #, python-format
msgid "%s MOSS Results" msgid "%s MOSS Results"
msgstr "%s Kết quả MOSS" msgstr "%s Kết quả MOSS"
#: judge/views/contests.py:848 #: judge/views/contests.py:849
#, python-format #, python-format
msgid "Running MOSS for %s..." msgid "Running MOSS for %s..."
msgstr "Đang chạy MOSS cho %s..." msgstr "Đang chạy MOSS cho %s..."
#: judge/views/contests.py:871 #: judge/views/contests.py:872
#, python-format #, python-format
msgid "Contest tag: %s" msgid "Contest tag: %s"
msgstr "Nhãn kỳ thi: %s" msgstr "Nhãn kỳ thi: %s"
#: judge/views/contests.py:881 judge/views/ticket.py:57 #: judge/views/contests.py:882 judge/views/ticket.py:57
msgid "Issue description" msgid "Issue description"
msgstr "Mô tả vấn đề" msgstr "Mô tả vấn đề"
#: judge/views/contests.py:924 #: judge/views/contests.py:925
#, python-format #, python-format
msgid "New clarification for %s" msgid "New clarification for %s"
msgstr "Thông báo mới cho %s" msgstr "Thông báo mới cho %s"
@ -2656,56 +2656,56 @@ msgstr "Không có bài nào như vậy"
msgid "Could not find a problem with the code \"%s\"." msgid "Could not find a problem with the code \"%s\"."
msgstr "Không tìm thấy bài tập với mã bài \"%s\"." msgstr "Không tìm thấy bài tập với mã bài \"%s\"."
#: judge/views/problem.py:111 #: judge/views/problem.py:113
#, python-brace-format #, python-brace-format
msgid "Editorial for {0}" msgid "Editorial for {0}"
msgstr "Hướng dẫn cho {0}" msgstr "Hướng dẫn cho {0}"
#: judge/views/problem.py:114 #: judge/views/problem.py:116
#, python-brace-format #, python-brace-format
msgid "Editorial for <a href=\"{1}\">{0}</a>" msgid "Editorial for <a href=\"{1}\">{0}</a>"
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>" msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
#: judge/views/problem.py:226 #: judge/views/problem.py:227
#, python-brace-format #, python-brace-format
msgid "Disscuss {0}" msgid "Disscuss {0}"
msgstr "" msgstr ""
#: judge/views/problem.py:229 #: judge/views/problem.py:230
#, python-brace-format #, python-brace-format
msgid "Discuss <a href=\"{1}\">{0}</a>" msgid "Discuss <a href=\"{1}\">{0}</a>"
msgstr "Thảo luận <a href=\"{1}\">{0}</a>" msgstr "Thảo luận <a href=\"{1}\">{0}</a>"
#: judge/views/problem.py:297 templates/contest/contest.html:79 #: judge/views/problem.py:298 templates/contest/contest.html:79
#: templates/user/user-about.html:28 templates/user/user-tabs.html:5 #: templates/user/user-about.html:28 templates/user/user-tabs.html:5
#: templates/user/users-table.html:29 #: templates/user/users-table.html:29
msgid "Problems" msgid "Problems"
msgstr "Bài tập" msgstr "Bài tập"
#: judge/views/problem.py:597 #: judge/views/problem.py:598
msgid "Banned from submitting" msgid "Banned from submitting"
msgstr "Bị cấm nộp bài" msgstr "Bị cấm nộp bài"
#: judge/views/problem.py:598 #: judge/views/problem.py:599
msgid "" msgid ""
"You have been declared persona non grata for this problem. You are " "You have been declared persona non grata for this problem. You are "
"permanently barred from submitting this problem." "permanently barred from submitting this problem."
msgstr "Bạn đã bị cấm nộp bài này." msgstr "Bạn đã bị cấm nộp bài này."
#: judge/views/problem.py:612 #: judge/views/problem.py:613
msgid "Too many submissions" msgid "Too many submissions"
msgstr "Quá nhiều lần nộp" msgstr "Quá nhiều lần nộp"
#: judge/views/problem.py:613 #: judge/views/problem.py:614
msgid "You have exceeded the submission limit for this problem." msgid "You have exceeded the submission limit for this problem."
msgstr "Bạn đã vượt quá số lần nộp cho bài này." msgstr "Bạn đã vượt quá số lần nộp cho bài này."
#: judge/views/problem.py:673 judge/views/problem.py:676 #: judge/views/problem.py:674 judge/views/problem.py:677
#, python-format #, python-format
msgid "Submit to %(problem)s" msgid "Submit to %(problem)s"
msgstr "Nộp bài cho %(problem)s" msgstr "Nộp bài cho %(problem)s"
#: judge/views/problem.py:691 #: judge/views/problem.py:692
msgid "Clone Problem" msgid "Clone Problem"
msgstr "Nhân bản bài tập" msgstr "Nhân bản bài tập"
@ -2803,7 +2803,7 @@ msgstr "Các bài nộp tốt nhất cho bài {0} trong <a href=\"{2}\">{1}</a>"
msgid "A username must contain letters, numbers, or underscores" msgid "A username must contain letters, numbers, or underscores"
msgstr "Tên đăng nhập phải chứa ký tự, chữ số, hoặc dấu gạch dưới" msgstr "Tên đăng nhập phải chứa ký tự, chữ số, hoặc dấu gạch dưới"
#: judge/views/register.py:31 templates/user/edit-profile.html:118 #: judge/views/register.py:31 templates/user/edit-profile.html:120
msgid "Preferred language" msgid "Preferred language"
msgstr "Ngôn ngữ ưa thích" msgstr "Ngôn ngữ ưa thích"
@ -2857,39 +2857,39 @@ 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:404 #: judge/views/submission.py:405
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:405 #: judge/views/submission.py:406
#, 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:436 #: judge/views/submission.py:437
#, 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:455 #: judge/views/submission.py:456
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:501 #: judge/views/submission.py:502
#, 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:502 #: judge/views/submission.py:503
#, 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:603 #: judge/views/submission.py:604
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:622 #: judge/views/submission.py:623
#, 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="
@ -2898,7 +2898,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:629 #: judge/views/submission.py:630
#, 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}"
@ -2979,29 +2979,29 @@ msgstr "Tài khoản của tôi"
msgid "User %s" msgid "User %s"
msgstr "Thành viên %s" msgstr "Thành viên %s"
#: judge/views/user.py:148 #: judge/views/user.py:149
msgid "M j, Y" msgid "M j, Y"
msgstr "j M, Y" msgstr "j M, Y"
#: judge/views/user.py:171 #: judge/views/user.py:172
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:290 #: judge/views/user.py:291
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:324 templates/admin/auth/user/change_form.html:14 #: judge/views/user.py:326 templates/admin/auth/user/change_form.html:14
#: templates/admin/auth/user/change_form.html:17 templates/base.html:255 #: templates/admin/auth/user/change_form.html:17 templates/base.html:297
#: templates/user/user-tabs.html:10 #: templates/user/user-tabs.html:10
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:333 templates/user/user-list-tabs.html:4 #: judge/views/user.py:335 templates/user/user-list-tabs.html:4
msgid "Leaderboard" msgid "Leaderboard"
msgstr "Bảng xếp hạng" msgstr "Bảng xếp hạng"
#: judge/views/user.py:408 #: judge/views/user.py:410
msgid "Import Users" msgid "Import Users"
msgstr "" msgstr ""
@ -3197,20 +3197,20 @@ msgstr "Chỉnh sửa thông tin"
msgid "Rejudge" msgid "Rejudge"
msgstr "Chấm lại" msgstr "Chấm lại"
#: templates/base.html:224 templates/chat/chat.html:566 #: templates/base.html:266 templates/chat/chat.html:566
msgid "Chat" msgid "Chat"
msgstr "Chat" msgstr "Chat"
#: templates/base.html:230 #: templates/base.html:272
msgid "Notification" msgid "Notification"
msgstr "Thông báo" msgstr "Thông báo"
#: templates/base.html:247 #: templates/base.html:289
#, python-format #, python-format
msgid "Hello, <b>%(username)s</b>." msgid "Hello, <b>%(username)s</b>."
msgstr "Xin chào, <b>%(username)s</b>." msgstr "Xin chào, <b>%(username)s</b>."
#: templates/base.html:253 templates/chat/chat.html:20 #: templates/base.html:295 templates/chat/chat.html:20
#: templates/comments/list.html:89 templates/contest/contest-list-tabs.html:24 #: templates/comments/list.html:89 templates/contest/contest-list-tabs.html:24
#: templates/contest/ranking-table.html:53 #: templates/contest/ranking-table.html:53
#: templates/problem/problem-list-tabs.html:6 #: templates/problem/problem-list-tabs.html:6
@ -3219,28 +3219,36 @@ msgstr "Xin chào, <b>%(username)s</b>."
msgid "Admin" msgid "Admin"
msgstr "" msgstr ""
#: templates/base.html:262 #: templates/base.html:304
msgid "Log out" msgid "Log out"
msgstr "Đăng xuất" msgstr "Đăng xuất"
#: templates/base.html:271 #: templates/base.html:313
#: templates/registration/password_reset_complete.html:4 #: templates/registration/password_reset_complete.html:4
msgid "Log in" msgid "Log in"
msgstr "Đăng nhập" msgstr "Đăng nhập"
#: templates/base.html:272 templates/registration/registration_form.html:177 #: templates/base.html:314 templates/registration/registration_form.html:177
msgid "or" msgid "or"
msgstr "hoặc" msgstr "hoặc"
#: templates/base.html:273 #: templates/base.html:315
msgid "Sign up" msgid "Sign up"
msgstr "Đăng ký" msgstr "Đăng ký"
#: templates/base.html:288 #: templates/base.html:331
msgid "spectating" msgid "spectating"
msgstr "đang theo dõi" msgstr "đang theo dõi"
#: templates/base.html:301 #: templates/base.html:343
msgid "Compete"
msgstr "Thi"
#: templates/base.html:345
msgid "General"
msgstr "Chung"
#: templates/base.html:352
msgid "This site works best with JavaScript enabled." msgid "This site works best with JavaScript enabled."
msgstr "" msgstr ""
@ -4638,12 +4646,12 @@ msgid "Default language"
msgstr "Ngôn ngữ ưa thích" msgstr "Ngôn ngữ ưa thích"
#: templates/registration/registration_form.html:186 #: templates/registration/registration_form.html:186
#: templates/user/edit-profile.html:181 #: templates/user/edit-profile.html:183
msgid "Affiliated organizations" msgid "Affiliated organizations"
msgstr "Tổ chức bạn muốn tham gia" msgstr "Tổ chức bạn muốn tham gia"
#: templates/registration/registration_form.html:195 #: templates/registration/registration_form.html:195
#: templates/user/edit-profile.html:136 #: templates/user/edit-profile.html:138
msgid "Notify me about upcoming contests" msgid "Notify me about upcoming contests"
msgstr "Nhận thông báo về các kỳ thi tương lai" msgstr "Nhận thông báo về các kỳ thi tương lai"
@ -4986,55 +4994,55 @@ msgstr "Không có gì."
msgid "Rank" msgid "Rank"
msgstr "Rank" msgstr "Rank"
#: templates/user/edit-profile.html:98 #: templates/user/edit-profile.html:99
msgid "Name and School" msgid "Name and School"
msgstr "Họ tên và Trường" msgstr "Họ tên và Trường"
#: templates/user/edit-profile.html:100 #: templates/user/edit-profile.html:101
msgid "Enter this form" msgid "Enter this form"
msgstr "Điền vào link này" msgstr "Điền vào link này"
#: templates/user/edit-profile.html:101 #: templates/user/edit-profile.html:102
msgid "It takes some time for admin to approve" msgid "It takes some time for admin to approve"
msgstr "Ban quản trị sẽ phê duyệt" msgstr "Ban quản trị sẽ phê duyệt"
#: templates/user/edit-profile.html:105 #: templates/user/edit-profile.html:107
msgid "Self-description" msgid "Self-description"
msgstr "Tự giới thiệu" msgstr "Tự giới thiệu"
#: templates/user/edit-profile.html:113 #: templates/user/edit-profile.html:115
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:122 #: templates/user/edit-profile.html:124
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:127 #: templates/user/edit-profile.html:129
msgid "Math engine" msgid "Math engine"
msgstr "" msgstr ""
#: templates/user/edit-profile.html:151 templates/user/edit-profile.html:152 #: templates/user/edit-profile.html:153 templates/user/edit-profile.html:154
msgid "Change your avatar" msgid "Change your avatar"
msgstr "Đổi ảnh đại diện" msgstr "Đổi ảnh đại diện"
#: templates/user/edit-profile.html:158 #: templates/user/edit-profile.html:160
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:165 #: templates/user/edit-profile.html:167
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:172 #: templates/user/edit-profile.html:174
msgid "Two Factor Authentication is disabled." msgid "Two Factor Authentication is disabled."
msgstr "Two Factor Authentication đã được hủy kích hoạt." msgstr "Two Factor Authentication đã được hủy kích hoạt."
#: templates/user/edit-profile.html:189 #: templates/user/edit-profile.html:191
msgid "User-script" msgid "User-script"
msgstr "" msgstr ""
#: templates/user/edit-profile.html:193 #: templates/user/edit-profile.html:195
msgid "Update profile" msgid "Update profile"
msgstr "Cập nhật thông tin" msgstr "Cập nhật thông tin"

View file

@ -485,12 +485,8 @@ noscript #noscript {
#contest-info { #contest-info {
font-size: 1.25em; font-size: 1.25em;
border: 5px solid $highlight_blue; border: 5px solid $highlight_blue;
border-left: 5px dotted white;
border-radius: 0 $widget_border_radius $widget_border_radius 0; border-radius: 0 $widget_border_radius $widget_border_radius 0;
background: rgba(0, 0, 0, 0.77);
z-index: 100000; z-index: 100000;
padding: 10px 12px;
color: white;
cursor: move; cursor: move;
position: fixed; position: fixed;
left: 20px; left: 20px;
@ -506,6 +502,34 @@ noscript #noscript {
} }
} }
#contest-info-main {
border-left: 5px dotted white;
background: rgba(0, 0, 0, 0.77);
padding: 10px 12px;
color: white;
display: inline;
}
#contest-info-toggle {
display: inline;
padding: 10px 12px;
border-radius: 0 10px 10px 0;
cursor: pointer;
}
.contest-info-toggle-mode-on {
background: rgba(0, 205, 0, 0.57);
}
.contest-info-toggle-mode-on:hover {
background: rgba(0, 205, 0, 0.97);
}
.contest-info-toggle-mode-off {
background: rgba(255, 0, 0, 0.57);
}
.contest-info-toggle-mode-off:hover {
background: rgba(255, 0, 0, 0.97);
}
#contest-time-remaining { #contest-time-remaining {
display: inline-block; display: inline-block;
} }

View file

@ -2,6 +2,7 @@
margin: 0; margin: 0;
padding-top: 0.1em; padding-top: 0.1em;
padding-bottom: 0.1em; padding-bottom: 0.1em;
overflow-wrap: anywhere;
} }
.chatbtn_remove_mess { .chatbtn_remove_mess {
float: right; float: right;
@ -60,14 +61,13 @@
#chat-input { #chat-input {
width: 100%; width: 100%;
padding: 0.4em; padding: 0.4em 4em 0.6em 1.2em;
padding-bottom: 0.6em;
border: 0; border: 0;
color: black; color: black;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
height: 100%; height: 100%;
font-size: 14px; font-size: 16px;
} }
#chat-online-content { #chat-online-content {
padding: 0; padding: 0;
@ -172,6 +172,20 @@
cursor: pointer; cursor: pointer;
margin-top: 0.5em; margin-top: 0.5em;
} }
.message-text {
padding: 0.4em 0.6em 0.5em;
border-radius: 15px;
max-width: 70%;
width: fit-content;
}
.message-text-other {
background: #eeeeee;
color: black;
}
.message-text-myself {
background: rgb(0, 132, 255);
color: white;
}
@media (max-width: 799px) { @media (max-width: 799px) {
#chat-area { #chat-area {

View file

@ -94,7 +94,9 @@
{% block js_media %}{% endblock %} {% block js_media %}{% endblock %}
{% if request.in_contest %} {% if request.in_contest %}
<script>$(function () { <script>$(function () {
if ($("#contest-time-remaining").length) {
count_down($("#contest-time-remaining")); count_down($("#contest-time-remaining"));
}
var selected = null, var selected = null,
x_pos = 0, y_pos = 0, x_pos = 0, y_pos = 0,
@ -117,6 +119,12 @@
$("#contest-info").show(); $("#contest-info").show();
$("#contest-info-toggle").on('click', function() {
$.post("{{url('contest_mode_ajax')}}", function() {
window.location.reload();
})
});
$(document).mousemove(function (e) { $(document).mousemove(function (e) {
x_pos = e.screenX; x_pos = e.screenX;
y_pos = e.screenY; y_pos = e.screenY;
@ -190,6 +198,42 @@
</style> </style>
</noscript> </noscript>
<style> <style>
#contest-info {
font-size: 1.25em;
border: 5px solid $highlight_blue;
border-radius: 0 $widget_border_radius $widget_border_radius 0;
z-index: 100000;
cursor: move;
position: fixed;
left: 20px;
top: 90%;
display: none;
}
#contest-info-main {
border-left: 5px dotted white;
background: rgba(0, 0, 0, 0.77);
padding: 10px 12px;
color: white;
display: inline;
}
#contest-info-toggle {
display: inline;
padding: 10px 12px;
border-radius: 0 10px 10px 0;
cursor: pointer;
}
.contest-info-toggle-mode-on {
background: rgba(0, 205, 0, 0.57);
}
.contest-info-toggle-mode-on:hover {
background: rgba(0, 205, 0, 0.97);
}
.contest-info-toggle-mode-off {
background: rgba(255, 0, 0, 0.57);
}
.contest-info-toggle-mode-off:hover {
background: rgba(255, 0, 0, 0.97);
}
</style> </style>
</head> </head>
<body> <body>
@ -284,7 +328,8 @@
</nav> </nav>
{% if request.in_contest %} {% if request.in_contest %}
<div id="contest-info"> <div id="contest-info">
<a href="{{ url('contest_view', request.participation.contest.key) }}" style="vertical-align: middle"> <div id="contest-info-main">
<a href="{{ url('contest_view', request.participation.contest.key) }}" style="vertical-align: middle; display: inline">
{{ request.participation.contest.name }} - {{ request.participation.contest.name }} -
{% if request.participation.spectate %} {% if request.participation.spectate %}
{{ _('spectating') }} {{ _('spectating') }}
@ -297,6 +342,14 @@
{% endif %} {% endif %}
</a> </a>
</div> </div>
<div id="contest-info-toggle" class="{{'contest-info-toggle-mode-on' if request.contest_mode else 'contest-info-toggle-mode-off'}}">
{% if request.contest_mode %}
<i class="fa fa-toggle-on" style="color: white"></i> {{_('Compete')}}
{% else %}
<i class="fa fa-toggle-off" style="color: white"></i> {{_('General')}}
{% endif %}
</div>
</div>
{% endif %} {% endif %}
<div id="page-container"> <div id="page-container">
<noscript> <noscript>

View file

@ -110,7 +110,7 @@
</div> </div>
<div class="blog-sidebar"> <div class="blog-sidebar">
{% if request.in_contest and request.participation.contest.use_clarifications %} {% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<div class="blog-sidebox sidebox"> <div class="blog-sidebox sidebox">
<h3>{{ _('Clarifications') }} <h3>{{ _('Clarifications') }}
<i class="fa fa-question-circle"></i> <i class="fa fa-question-circle"></i>

View file

@ -206,6 +206,7 @@ let META_HEADER = [
MathJax.Hub.Queue(["Typeset",MathJax.Hub]); MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
register_time($('.time-with-rel')); register_time($('.time-with-rel'));
remove_unread_current_user(); remove_unread_current_user();
merge_authors();
}, },
error: function (data) { error: function (data) {
console.log('Fail to check message'); console.log('Fail to check message');
@ -230,6 +231,12 @@ let META_HEADER = [
var time = moment($(this).find(".time-with-rel").attr('data-iso')); var time = moment($(this).find(".time-with-rel").attr('data-iso'));
var $content = $(this).children('.content-message'); var $content = $(this).children('.content-message');
if (username == window.user.name) {
$(this).find('.message-text').each(function() {
$(this).removeClass('message-text-other').addClass('message-text-myself');
});
}
if (username == last.username && time.diff(last.time, 'minutes') <= time_limit) { if (username == last.username && time.diff(last.time, 'minutes') <= time_limit) {
last.$content.append($body); last.$content.append($body);
$(this).parent().remove(); $(this).parent().remove();

View file

@ -92,10 +92,8 @@
} }
.body-block { .body-block {
border-radius: 4px; border-radius: 4px;
padding-left: 0.2em; padding: 0.05em 0.6em;
} width: 100%;
.body-block:hover {
background: #eee;
} }
.active-span { .active-span {
margin-top: 1em; margin-top: 1em;

View file

@ -20,8 +20,10 @@
{{_('Delete')}} {{_('Delete')}}
</a> </a>
{% endif %} {% endif %}
<div class="message-text message-text-other">
{{message.body | markdown('comment', MATH_ENGINE)|reference|str|safe }} {{message.body | markdown('comment', MATH_ENGINE)|reference|str|safe }}
</div> </div>
</div>
</span> </span>
</div> </div>
<div class="clear"></div> <div class="clear"></div>

View file

@ -319,6 +319,31 @@
} }
} }
function get_initial_rank() {
var ranks = $('.rank-td').map(function() {return this.innerHTML}).get();
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
window.user_rank = new Map();
for (var i = 0; i < ranks.length; i++) {
window.user_rank[usernames[i]] = ranks[i];
}
}
function add_initial_friend_rank() {
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
var is_virtual = [];
$('.user-name').each(function() {
if($(this).children('sup').length) {
is_virtual.push(1);
}
else is_virtual.push(0);
});
$('.rank-td').each(function(i) {
if (!is_virtual[i]) this.innerHTML += ' (' + window.user_rank[usernames[i]] + ')';
});
}
function update_ranking() { function update_ranking() {
var friend = $('#show-friends-checkbox').is(':checked'); var friend = $('#show-friends-checkbox').is(':checked');
var virtual = $('#show-virtual-checkbox').is(':checked'); var virtual = $('#show-virtual-checkbox').is(':checked');
@ -328,8 +353,13 @@
success: function(HTML) { success: function(HTML) {
$('#users-table').html(HTML); $('#users-table').html(HTML);
highlightFirstSolve(); highlightFirstSolve();
renew_filter();
$('#loading-gif').hide(); $('#loading-gif').hide();
if (!virtual && !friend) {
get_initial_rank();
}
if (friend) {
add_initial_friend_rank();
}
}, },
fail: function() { fail: function() {
console.log('Fail to update ranking'); console.log('Fail to update ranking');
@ -394,6 +424,7 @@
highlightFirstSolve(); highlightFirstSolve();
renew_filter(); renew_filter();
get_initial_rank();
{% if participation_tab %} {% if participation_tab %}
$('#show-virtual-checkbox').hide(); $('#show-virtual-checkbox').hide();
$('#show-virtual-label').hide(); $('#show-virtual-label').hide();

View file

@ -9,7 +9,7 @@
} }
</style> </style>
</noscript> </noscript>
{% if not request.in_contest %} {% if not request.in_contest_mode %}
<style> <style>
#search-org { #search-org {
width: 100%; width: 100%;
@ -131,7 +131,7 @@
}); });
</script> </script>
{% endcompress %} {% endcompress %}
{% if request.in_contest %} {% if request.in_contest_mode %}
{% compress js %} {% compress js %}
<script src="{{ static('libs/tablesorter.js') }}" type="text/javascript"></script> <script src="{{ static('libs/tablesorter.js') }}" type="text/javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
@ -184,7 +184,7 @@
<div id="common-content"> <div id="common-content">
{% block before_table %}{% endblock %} {% block before_table %}{% endblock %}
{% if not request.in_contest %} {% if not request.in_contest_mode %}
<div id="content-right" class="problems"> <div id="content-right" class="problems">
<div class="info-float"> <div class="info-float">
{% include "problem/search-form.html" %} {% include "problem/search-form.html" %}
@ -207,7 +207,7 @@
<table id="problem-table" class="table striped"> <table id="problem-table" class="table striped">
<thead> <thead>
<tr> <tr>
{% if request.in_contest %} {% if request.in_contest_mode %}
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<th class="solved"><i class="fa fa-check"></i></th> <th class="solved"><i class="fa fa-check"></i></th>
{% endif %} {% endif %}
@ -268,7 +268,7 @@
{% if problem.id in completed_problem_ids %} {% if problem.id in completed_problem_ids %}
<td solved="1"> <td solved="1">
<a href="{{ url('user_submissions', problem.code, request.user.username) }}"> <a href="{{ url('user_submissions', problem.code, request.user.username) }}">
{% if problem.is_public or request.in_contest %} {% if problem.is_public or request.in_contest_mode %}
<i class="solved-problem-color fa fa-check-circle"></i> <i class="solved-problem-color fa fa-check-circle"></i>
{% else %} {% else %}
<i class="solved-problem-color fa fa-lock"></i> <i class="solved-problem-color fa fa-lock"></i>
@ -278,7 +278,7 @@
{% elif problem.id in attempted_problems %} {% elif problem.id in attempted_problems %}
<td solved="0"> <td solved="0">
<a href="{{ url('user_submissions', problem.code, request.user.username) }}"> <a href="{{ url('user_submissions', problem.code, request.user.username) }}">
{% if problem.is_public or request.in_contest %} {% if problem.is_public or request.in_contest_mode %}
<i class="attempted-problem-color fa fa-minus-circle"></i> <i class="attempted-problem-color fa fa-minus-circle"></i>
{% else %} {% else %}
<i class="attempted-problem-color fa fa-lock"></i> <i class="attempted-problem-color fa fa-lock"></i>
@ -287,7 +287,7 @@
</td> </td>
{% else %} {% else %}
<td solved="-1"> <td solved="-1">
{% if problem.is_public or request.in_contest %} {% if problem.is_public or request.in_contest_mode %}
<i class="unsolved-problem-color fa fa-minus-circle"></i> <i class="unsolved-problem-color fa fa-minus-circle"></i>
{% else %} {% else %}
<i class="unsolved-problem-color fa fa-lock"></i> <i class="unsolved-problem-color fa fa-lock"></i>
@ -312,12 +312,12 @@
</td> </td>
{% endif %} {% endif %}
<td class="p">{{ problem.points|floatformat }}{% if problem.partial %}p{% endif %}</td> <td class="p">{{ problem.points|floatformat }}{% if problem.partial %}p{% endif %}</td>
{% if not request.in_contest %} {% if not request.in_contest_mode %}
<td class="ac-rate">{{ problem.ac_rate|floatformat(1) }}%</td> <td class="ac-rate">{{ problem.ac_rate|floatformat(1) }}%</td>
{% endif %} {% endif %}
<td class="users"> <td class="users">
<a href="{{ url('ranked_submissions', problem.code) }}"> <a href="{{ url('ranked_submissions', problem.code) }}">
{% if not request.in_contest or not hide_contest_scoreboard %} {% if not request.in_contest_mode or not hide_contest_scoreboard %}
{{ problem.user_count }} {{ problem.user_count }}
{% else %} {% else %}
??? ???
@ -335,7 +335,7 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% if request.in_contest and request.participation.contest.use_clarifications %} {% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<br><br> <br><br>
{% if can_edit_contest %} {% if can_edit_contest %}
<div style="float: right; font-size: 1.2em"> <div style="float: right; font-size: 1.2em">

View file

@ -58,7 +58,7 @@
{% endblock %} {% endblock %}
{% block content_js_media %} {% block content_js_media %}
{% if request.in_contest %} {% if request.in_contest_mode %}
<script type="text/javascript"> <script type="text/javascript">
window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}"); window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}");
</script> </script>
@ -88,7 +88,7 @@
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
{% if problem.id in completed_problem_ids %} {% if problem.id in completed_problem_ids %}
<a href="{{ url('user_submissions', problem.code, request.user.username) }}"> <a href="{{ url('user_submissions', problem.code, request.user.username) }}">
{% if problem.is_public or request.in_contest %} {% if problem.is_public or request.in_contest_mode %}
<i class="solved-problem-color title-state fa fa-check-circle"></i> <i class="solved-problem-color title-state fa fa-check-circle"></i>
{% else %} {% else %}
<i class="solved-problem-color title-state fa fa-lock"></i> <i class="solved-problem-color title-state fa fa-lock"></i>
@ -96,7 +96,7 @@
</a> </a>
{% elif problem.id in attempted_problems %} {% elif problem.id in attempted_problems %}
<a href="{{ url('user_submissions', problem.code, request.user.username) }}"> <a href="{{ url('user_submissions', problem.code, request.user.username) }}">
{% if problem.is_public or request.in_contest %} {% if problem.is_public or request.in_contest_mode %}
<i class="attempted-problem-color title-state fa fa-minus-circle"></i> <i class="attempted-problem-color title-state fa fa-minus-circle"></i>
{% else %} {% else %}
<i class="attempted-problem-color title-state fa fa-lock"></i> <i class="attempted-problem-color title-state fa fa-lock"></i>
@ -133,7 +133,7 @@
{% endblock %} {% endblock %}
{% block info_float %} {% block info_float %}
{% if request.user.is_authenticated and request.in_contest and submission_limit %} {% if request.user.is_authenticated and request.in_contest_mode and submission_limit %}
{% if submissions_left > 0 %} {% if submissions_left > 0 %}
<a href="{{ url('problem_submit', problem.code) }}" class="unselectable button full"> <a href="{{ url('problem_submit', problem.code) }}" class="unselectable button full">
{{ _('Submit solution') }} {{ _('Submit solution') }}

View file

@ -1,4 +1,4 @@
{% if request.in_contest and request.participation.contest.logo_override_image %} {% if request.in_contest_mode and request.participation.contest.logo_override_image %}
<img src="{{ request.participation.contest.logo_override_image|camo }}" alt="{{ SITE_NAME }}" height="44" style="border: none"> <img src="{{ request.participation.contest.logo_override_image|camo }}" alt="{{ SITE_NAME }}" height="44" style="border: none">
{% elif logo_override_image is defined and logo_override_image %} {% elif logo_override_image is defined and logo_override_image %}
<img src="{{ logo_override_image|camo }}" alt="{{ SITE_NAME }}" height="44" style="border: none"> <img src="{{ logo_override_image|camo }}" alt="{{ SITE_NAME }}" height="44" style="border: none">

View file

@ -2,7 +2,7 @@
{% block js_media %} {% block js_media %}
<script type="text/javascript"> <script type="text/javascript">
{% if dynamic_update and last_msg %} {% if dynamic_update and last_msg %}
{% if request.in_contest %} {% if request.in_contest_mode %}
window.current_contest = '{{request.participation.contest.key}}'; window.current_contest = '{{request.participation.contest.key}}';
{% else %} {% else %}
window.current_contest = null; window.current_contest = null;

View file

@ -24,7 +24,7 @@
<div> <div>
{{ link_user(submission.user) }} {{ link_user(submission.user) }}
<span class="time">{{ relative_time(submission.date) }}</span> <span class="time">{{ relative_time(submission.date) }}</span>
{% if not request.in_contest and submission.contest_object_id %} {% if not request.in_contest_mode and submission.contest_object_id %}
<a href="{{ url('contest_view', submission.contest_object.key) }}" <a href="{{ url('contest_view', submission.contest_object.key) }}"
class="submission-contest"> class="submission-contest">
<i title="{{ submission.contest_object.name }}" class="fa fa-dot-circle-o"></i> <i title="{{ submission.contest_object.name }}" class="fa fa-dot-circle-o"></i>

View file

@ -32,10 +32,10 @@
<tr id="overall-row" class="case-row overall-result-{{submission.result}}"> <tr id="overall-row" class="case-row overall-result-{{submission.result}}">
<td><span class="col-title">{{_('Overall: ')}}</span> <td><span class="col-title">{{_('Overall: ')}}</span>
{% if request.in_contest and submission.contest_or_none %} {% if request.in_contest_mode and submission.contest_or_none %}
{% with contest=submission.contest_or_none %} {% with contest=submission.contest_or_none %}
({{ _('%(points)s/%(total)s points', points=contest.points|roundfloat(3), {{ _('%(points)s/%(total)s', points=contest.points|roundfloat(3),
total=contest.problem.points|floatformat(-1)) }}) total=contest.problem.points|floatformat(-1)) }}
{% endwith %} {% endwith %}
{% else %} {% else %}
{{ _('%(points)s/%(total)s', points=submission.points|roundfloat(3), {{ _('%(points)s/%(total)s', points=submission.points|roundfloat(3),