Change problem page

This commit is contained in:
cuom1999 2022-04-13 00:52:03 -05:00
parent 5c6391fb76
commit f539a90635
13 changed files with 6941 additions and 543 deletions

View file

@ -111,12 +111,13 @@ urlpatterns = [
url(r'^', include('social_django.urls')),
url(r'^feed/', include([
url(r'^problems/$', problem.ProblemFeed.as_view(), name='problem_feed'),
url(r'^tickets/$', blog.TicketFeed.as_view(), name='ticket_feed'),
url(r'^comments/$', blog.CommentFeed.as_view(), name='comment_feed'),
])),
url(r'^problems/$', problem.ProblemList.as_view(), name='problem_list'),
url(r'^problems/random/$', problem.RandomProblem.as_view(), name='problem_random'),
url(r'^problems/feed$', problem.ProblemFeed.as_view(feed_type='for_you'), name='problem_feed'),
url(r'^problems/feed/new$', problem.ProblemFeed.as_view(feed_type='new'), name='problem_feed_new'),
url(r'^problem/(?P<problem>[^/]+)', include([
url(r'^$', problem.ProblemDetail.as_view(), name='problem_detail'),

View file

@ -6,8 +6,10 @@ import os
class CollabFilter:
DOT = 'dot'
COSINE = 'cosine'
def __init__(self):
embeddings = np.load(os.path.join(settings.ML_OUTPUT_PATH, 'collab_filter/embeddings.npz'),
# name = 'collab_filter' or 'collab_filter_time'
def __init__(self, name):
embeddings = np.load(os.path.join(settings.ML_OUTPUT_PATH, name + '/embeddings.npz'),
allow_pickle=True)
arr0, arr1 = embeddings.files
self.user_embeddings = embeddings[arr0]

View file

@ -93,7 +93,7 @@ class PostList(FeedView):
context['title'] = self.title or _('Page %d of Posts') % context['page_obj'].number
context['first_page_href'] = reverse('home')
context['page_prefix'] = reverse('blog_post_list')
context['feed_type'] = 'blog'
context['page_type'] = 'blog'
context['post_comment_counts'] = {
int(page[2:]): count for page, count in
Comment.objects
@ -128,7 +128,7 @@ class TicketFeed(FeedView):
def get_context_data(self, **kwargs):
context = super(TicketFeed, self).get_context_data(**kwargs)
context['feed_type'] = 'ticket'
context['page_type'] = 'ticket'
context['first_page_href'] = self.request.path
context['page_prefix'] = '?page='
context['title'] = _('Ticket feed')
@ -146,7 +146,7 @@ class CommentFeed(FeedView):
def get_context_data(self, **kwargs):
context = super(CommentFeed, self).get_context_data(**kwargs)
context['feed_type'] = 'comment'
context['page_type'] = 'comment'
context['first_page_href'] = self.request.path
context['page_prefix'] = '?page='
context['title'] = _('Comment feed')

View file

@ -38,7 +38,6 @@ from judge.utils.problems import contest_attempted_ids, contest_completed_ids, h
from judge.utils.strings import safe_float_or_none, safe_int_or_none
from judge.utils.tickets import own_ticket_filter
from judge.utils.views import QueryStringSortMixin, SingleObjectFormView, TitleMixin, generic_message
from judge.views.blog import FeedView
from judge.ml.collab_filter import CollabFilter
@ -455,10 +454,9 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
queryset = queryset.filter(points__gte=self.point_start)
if self.point_end is not None:
queryset = queryset.filter(points__lte=self.point_end)
if self.show_editorial:
queryset = queryset.annotate(
has_public_editorial=Sum(Case(When(solution__is_public=True, then=1),
default=0, output_field=IntegerField())))
queryset = queryset.annotate(
has_public_editorial=Sum(Case(When(solution__is_public=True, then=1),
default=0, output_field=IntegerField())))
return queryset.distinct()
@ -474,6 +472,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['show_types'] = 0 if self.in_contest else int(self.show_types)
context['full_text'] = 0 if self.in_contest else int(self.full_text)
context['show_editorial'] = 0 if self.in_contest else int(self.show_editorial)
context['have_editorial'] = 0 if self.in_contest else int(self.have_editorial)
context['organizations'] = Organization.objects.all()
context['category'] = self.category
@ -486,7 +485,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['search_query'] = self.search_query
context['completed_problem_ids'] = self.get_completed_problems()
context['attempted_problems'] = self.get_attempted_problems()
context['page_type'] = 'list'
context.update(self.get_sort_paginate_context())
if not self.in_contest:
context.update(self.get_sort_context())
@ -498,6 +497,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
context['hide_contest_scoreboard'] = self.contest.scoreboard_visibility in \
(self.contest.SCOREBOARD_AFTER_CONTEST, self.contest.SCOREBOARD_AFTER_PARTICIPATION)
context['has_clarifications'] = False
if self.request.user.is_authenticated:
participation = self.request.profile.current_contest
if participation:
@ -537,6 +537,7 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
self.show_types = self.GET_with_session(request, 'show_types')
self.full_text = self.GET_with_session(request, 'full_text')
self.show_editorial = self.GET_with_session(request, 'show_editorial')
self.have_editorial = self.GET_with_session(request, 'have_editorial')
self.search_query = None
self.category = None
@ -573,44 +574,33 @@ class ProblemList(QueryStringSortMixin, TitleMixin, SolvedProblemMixin, ListView
return generic_message(request, 'FTS syntax error', e.args[1], status=400)
def post(self, request, *args, **kwargs):
to_update = ('hide_solved', 'show_types', 'full_text')
to_update = ('hide_solved', 'show_types', 'full_text',
'show_editorial', 'have_editorial')
for key in to_update:
if key in request.GET:
val = request.GET.get(key) == '1'
request.session[key] = val
else:
request.session.pop(key, None)
request.session[key] = False
return HttpResponseRedirect(request.get_full_path())
class ProblemFeed(FeedView):
class ProblemFeed(ProblemList):
model = Problem
context_object_name = 'problems'
paginate_by = 50
title = _('Problem feed')
feed_type = None
@cached_property
def profile(self):
if not self.request.user.is_authenticated:
return None
return self.request.profile
def GET_with_session(self, request, key):
if not request.GET:
return request.session.get(key, key=='hide_solved')
return request.GET.get(key, None) == '1'
def get_unsolved_queryset(self):
filter = Q(is_public=True)
if self.profile is not None:
filter |= Q(authors=self.profile)
filter |= Q(curators=self.profile)
filter |= Q(testers=self.profile)
queryset = Problem.objects.filter(filter).select_related('group').defer('description')
if not self.request.user.has_perm('see_organization_problem'):
filter = Q(is_organization_private=False)
if self.profile is not None:
filter |= Q(organizations__in=self.profile.organizations.all())
queryset = queryset.filter(filter)
if self.profile is not None:
queryset = queryset.exclude(id__in=Submission.objects.filter(user=self.profile, points=F('problem__points'))
.values_list('problem__id', flat=True))
return queryset.distinct()
def get_paginator(self, queryset, per_page, orphans=0,
allow_empty_first_page=True, **kwargs):
return DiggPaginator(queryset, per_page, body=6, padding=2,
orphans=orphans, allow_empty_first_page=allow_empty_first_page, **kwargs)
# arr = [[], [], ..]
def merge_recommendation(self, arr):
@ -636,31 +626,50 @@ class ProblemFeed(FeedView):
stop = False
return res
def get_queryset(self):
queryset = self.get_unsolved_queryset()
queryset = super(ProblemFeed, self).get_queryset()
if self.have_editorial:
queryset = queryset.filter(has_public_editorial=1)
user = self.request.profile
if self.feed_type == 'new':
return queryset.order_by('-date')
if not settings.ML_OUTPUT_PATH or not user:
return queryset.order_by('?')
cl_model = CollabFilter()
dot_rec = cl_model.user_recommendations(user, queryset, cl_model.DOT, 100)
cosine_rec = cl_model.user_recommendations(user, queryset, cl_model.COSINE, 100)
hot_problems_rec = [problem for problem in hot_problems(timedelta(days=7), 10)
if problem in queryset]
cf_model = CollabFilter('collab_filter')
cf_time_model = CollabFilter('collab_filter_time')
hot_problems_recommendations = [
problem for problem in hot_problems(timedelta(days=7), 20)
if problem in queryset
]
q = self.merge_recommendation([dot_rec, cosine_rec, hot_problems_rec])
q = self.merge_recommendation([
cf_model.user_recommendations(user, queryset, cf_model.DOT, 100),
cf_model.user_recommendations(user, queryset, cf_model.COSINE, 100),
cf_time_model.user_recommendations(user, queryset, cf_time_model.COSINE, 100),
cf_time_model.user_recommendations(user, queryset, cf_time_model.DOT, 100),
hot_problems_recommendations
])
return q
def get_context_data(self, **kwargs):
context = super(ProblemFeed, self).get_context_data(**kwargs)
context['first_page_href'] = self.request.path
context['page_prefix'] = '?page='
context['feed_type'] = 'problem'
context['page_type'] = 'feed'
context['title'] = self.title
context['feed_type'] = self.feed_type
return context
def get(self, request, *args, **kwargs):
if request.in_contest_mode:
return HttpResponseRedirect(reverse('problem_list'))
return super(ProblemFeed, self).get(request, *args, **kwargs)
class LanguageTemplateAjax(View):
def get(self, request, *args, **kwargs):

View file

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: lqdoj2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-22 04:37+0700\n"
"POT-Creation-Date: 2022-04-13 12:01+0700\n"
"PO-Revision-Date: 2021-07-20 03:44\n"
"Last-Translator: Icyene\n"
"Language-Team: Vietnamese\n"
@ -112,27 +112,27 @@ msgstr "Đăng nhập"
msgid "Home"
msgstr "Trang chủ"
#: judge/admin/comments.py:40
#: judge/admin/comments.py:41
#, python-format
msgid "%d comment successfully hidden."
msgid_plural "%d comments successfully hidden."
msgstr[0] "Đã ẩn %d bình luận."
#: judge/admin/comments.py:43
#: judge/admin/comments.py:44
msgid "Hide comments"
msgstr "Ẩn bình luận"
#: judge/admin/comments.py:47
#: judge/admin/comments.py:48
#, python-format
msgid "%d comment successfully unhidden."
msgid_plural "%d comments successfully unhidden."
msgstr[0] "Không ẩn được %d bình luận."
#: judge/admin/comments.py:50
#: judge/admin/comments.py:51
msgid "Unhide comments"
msgstr "Hiện bình luận"
#: judge/admin/comments.py:58
#: judge/admin/comments.py:59
msgid "Associated page"
msgstr "Trang liên kết"
@ -142,8 +142,8 @@ msgstr ""
#: judge/admin/contest.py:66 templates/contest/clarification.html:42
#: templates/contest/contest.html:83 templates/contest/moss.html:43
#: templates/problem/list.html:214 templates/problem/list.html:232
#: templates/problem/list.html:350 templates/user/user-problems.html:56
#: templates/problem/list.html:189 templates/problem/list.html:205
#: templates/problem/list.html:323 templates/user/user-problems.html:56
#: templates/user/user-problems.html:98
msgid "Problem"
msgstr "Bài tập"
@ -173,7 +173,7 @@ msgstr ""
msgid "Access"
msgstr "Truy cập"
#: judge/admin/contest.py:127 judge/admin/problem.py:131
#: judge/admin/contest.py:127 judge/admin/problem.py:133
msgid "Justice"
msgstr "Xử phạt"
@ -225,7 +225,7 @@ msgstr "ảo"
msgid "link path"
msgstr "đường dẫn"
#: judge/admin/interface.py:65 templates/blog/list.html:114
#: judge/admin/interface.py:65
msgid "Content"
msgstr "Nội dung"
@ -237,78 +237,90 @@ msgstr "Tổng kết"
msgid "object"
msgstr ""
#: judge/admin/organization.py:34 judge/admin/problem.py:171
#: judge/admin/organization.py:34 judge/admin/problem.py:173
#: judge/admin/profile.py:80
msgid "View on site"
msgstr "Xem trên trang"
#: judge/admin/problem.py:28
#: judge/admin/problem.py:30
msgid "Describe the changes you made (optional)"
msgstr "Mô tả các thay đổi (tùy chọn)"
#: judge/admin/problem.py:126
#: judge/admin/problem.py:128
msgid "Social Media"
msgstr "Mạng Xã Hội"
#: judge/admin/problem.py:127
#: judge/admin/problem.py:129
msgid "Taxonomy"
msgstr ""
#: judge/admin/problem.py:128 judge/admin/problem.py:258
#: judge/admin/problem.py:130 judge/admin/problem.py:284
#: templates/contest/contest.html:84 templates/problem/data.html:469
#: templates/problem/list.html:222 templates/problem/list.html:248
#: templates/problem/list.html:195 templates/problem/list.html:221
#: templates/user/base-users-table.html:10 templates/user/user-about.html:36
#: templates/user/user-about.html:52 templates/user/user-problems.html:58
msgid "Points"
msgstr "Điểm"
#: judge/admin/problem.py:129
#: judge/admin/problem.py:131
msgid "Limits"
msgstr "Giới hạn"
#: judge/admin/problem.py:130 judge/admin/submission.py:232
#: judge/admin/problem.py:132 judge/admin/submission.py:232
#: templates/stats/base.html:14 templates/submission/list.html:322
msgid "Language"
msgstr "Ngôn ngữ"
#: judge/admin/problem.py:132
#: judge/admin/problem.py:134
msgid "History"
msgstr "Lịch sử"
#: judge/admin/problem.py:168
#: judge/admin/problem.py:170
msgid "Authors"
msgstr "Các tác giả"
#: judge/admin/problem.py:183
#: judge/admin/problem.py:185
#, python-format
msgid "%d problem successfully marked as public."
msgid_plural "%d problems successfully marked as public."
msgstr[0] "%d bài tập đã được đánh dấu công khai."
#: judge/admin/problem.py:187
#: judge/admin/problem.py:189
msgid "Mark problems as public"
msgstr "Công khai bài tập"
#: judge/admin/problem.py:193
#: judge/admin/problem.py:195
#, python-format
msgid "%d problem successfully marked as private."
msgid_plural "%d problems successfully marked as private."
msgstr[0] "%d bài tập đã được đánh dấu riêng tư."
#: judge/admin/problem.py:197
#: judge/admin/problem.py:199
msgid "Mark problems as private"
msgstr "Đánh dấu các bài tập là riêng tư"
#: judge/admin/problem.py:253 judge/admin/submission.py:200
#: templates/problem/list.html:216 templates/problem/list.html:236
#: judge/admin/problem.py:279 judge/admin/submission.py:200
#: templates/problem/list.html:190 templates/problem/list.html:209
msgid "Problem code"
msgstr "Mã bài"
#: judge/admin/problem.py:263 judge/admin/submission.py:205
#: judge/admin/problem.py:289 judge/admin/submission.py:205
msgid "Problem name"
msgstr "Tên bài"
#: judge/admin/problem.py:268
#: judge/admin/problem.py:294
#, fuzzy
#| msgid "contest rating"
msgid "Voter rating"
msgstr "rating kỳ thi"
#: judge/admin/problem.py:299
#, fuzzy
#| msgid "Total points"
msgid "Voter point"
msgstr "Tổng điểm"
#: judge/admin/problem.py:304
msgid "Vote"
msgstr ""
@ -357,7 +369,7 @@ msgstr "Các bài tập không được cho phép"
msgid "These problems are NOT allowed to be submitted in this language"
msgstr "Các bài này không cho phép sử dụng ngôn ngữ này"
#: judge/admin/runtime.py:83 templates/problem/list.html:352
#: judge/admin/runtime.py:83 templates/problem/list.html:325
msgid "Description"
msgstr "Mô tả"
@ -417,7 +429,7 @@ msgstr "Tính điểm lại cái bài nộp"
#: judge/admin/submission.py:215 templates/notification/list.html:15
#: templates/organization/requests/log.html:10
#: templates/organization/requests/pending.html:13
#: templates/problem/list.html:351
#: templates/problem/list.html:324
#: templates/submission/status-testcases.html:125
#: templates/submission/status-testcases.html:127
msgid "Time"
@ -528,7 +540,7 @@ msgstr "Two Factor Authentication phải chứa 6 chữ số."
msgid "Invalid Two Factor Authentication token."
msgstr "Token Two Factor Authentication không hợp lệ."
#: judge/forms.py:148 judge/models/problem.py:97
#: judge/forms.py:148 judge/models/problem.py:98
msgid "Problem code must be ^[a-z0-9]+$"
msgstr "Mã bài phải có dạng ^[a-z0-9]+$"
@ -591,7 +603,7 @@ msgstr "người bình luận"
msgid "associated page"
msgstr "trang tương ứng"
#: judge/models/comment.py:46 judge/models/problem.py:493
#: judge/models/comment.py:46 judge/models/problem.py:494
msgid "votes"
msgstr "bình chọn"
@ -611,7 +623,7 @@ msgstr "bình luận"
msgid "comments"
msgstr ""
#: judge/models/comment.py:139 judge/models/problem.py:463
#: judge/models/comment.py:139 judge/models/problem.py:464
#, python-format
msgid "Editorial for %s"
msgstr ""
@ -729,7 +741,7 @@ msgstr ""
msgid "description"
msgstr "mô tả"
#: judge/models/contest.py:72 judge/models/problem.py:410
#: judge/models/contest.py:72 judge/models/problem.py:411
#: judge/models/runtime.py:138
msgid "problems"
msgstr "bài tập"
@ -742,12 +754,12 @@ msgstr "thời gian bắt đầu"
msgid "end time"
msgstr "thời gian kết thúc"
#: judge/models/contest.py:75 judge/models/problem.py:118
#: judge/models/problem.py:434
#: judge/models/contest.py:75 judge/models/problem.py:119
#: judge/models/problem.py:435
msgid "time limit"
msgstr "giới hạn thời gian"
#: judge/models/contest.py:76 judge/models/problem.py:136
#: judge/models/contest.py:76 judge/models/problem.py:137
msgid "publicly visible"
msgstr "công khai"
@ -846,12 +858,12 @@ msgstr ""
"kỳ thi, hãy bỏ đánh dấu ô này và chấm lại tất cả các bài."
#: judge/models/contest.py:110 judge/models/interface.py:77
#: judge/models/problem.py:157
#: judge/models/problem.py:158
msgid "private to organizations"
msgstr "riêng tư với các tổ chức"
#: judge/models/contest.py:111 judge/models/interface.py:75
#: judge/models/problem.py:155 judge/models/profile.py:77
#: judge/models/problem.py:156 judge/models/profile.py:77
msgid "organizations"
msgstr "tổ chức"
@ -859,7 +871,7 @@ msgstr "tổ chức"
msgid "If private, only these organizations may see the contest"
msgstr "Nếu riêng tư, chỉ những tổ chức này thấy được kỳ thi"
#: judge/models/contest.py:113 judge/models/problem.py:145
#: judge/models/contest.py:113 judge/models/problem.py:146
msgid "OpenGraph image"
msgstr "Hình ảnh OpenGraph"
@ -880,7 +892,7 @@ msgstr "số lượng thí sinh thi trực tiếp"
msgid "contest summary"
msgstr "tổng kết kỳ thi"
#: judge/models/contest.py:121 judge/models/problem.py:147
#: judge/models/contest.py:121 judge/models/problem.py:148
msgid "Plain-text, shown in meta description tag, e.g. for social media."
msgstr ""
@ -896,7 +908,7 @@ msgstr ""
"Mật khẩu truy cập cho các thí sinh muốn tham gia kỳ thi. Để trống nếu không "
"dùng."
#: judge/models/contest.py:125 judge/models/problem.py:141
#: judge/models/contest.py:125 judge/models/problem.py:142
msgid "personae non gratae"
msgstr ""
@ -1041,14 +1053,14 @@ msgid "contest participations"
msgstr "lần tham gia kỳ thi"
#: judge/models/contest.py:491 judge/models/contest.py:513
#: judge/models/contest.py:554 judge/models/problem.py:409
#: judge/models/problem.py:414 judge/models/problem.py:432
#: judge/models/contest.py:554 judge/models/problem.py:410
#: judge/models/problem.py:415 judge/models/problem.py:433
#: judge/models/problem_data.py:40
msgid "problem"
msgstr "bài tập"
#: judge/models/contest.py:493 judge/models/contest.py:517
#: judge/models/problem.py:129
#: judge/models/problem.py:130
msgid "points"
msgstr "điểm"
@ -1180,7 +1192,7 @@ msgstr "mục cha"
msgid "post title"
msgstr "tiêu đề bài đăng"
#: judge/models/interface.py:67 judge/models/problem.py:452
#: judge/models/interface.py:67 judge/models/problem.py:453
msgid "authors"
msgstr "tác giả"
@ -1188,7 +1200,7 @@ msgstr "tác giả"
msgid "slug"
msgstr "slug"
#: judge/models/interface.py:69 judge/models/problem.py:450
#: judge/models/interface.py:69 judge/models/problem.py:451
msgid "public visibility"
msgstr "khả năng hiển thị công khai"
@ -1252,287 +1264,287 @@ msgstr "thời gian gửi"
msgid "messages in the thread"
msgstr "tin nhắn trong chuỗi"
#: judge/models/problem.py:26
#: judge/models/problem.py:27
msgid "problem category ID"
msgstr "mã của nhóm bài"
#: judge/models/problem.py:27
#: judge/models/problem.py:28
msgid "problem category name"
msgstr "tên nhóm bài"
#: judge/models/problem.py:34
#: judge/models/problem.py:35
msgid "problem type"
msgstr "dạng bài"
#: judge/models/problem.py:35 judge/models/problem.py:113
#: judge/models/problem.py:36 judge/models/problem.py:114
msgid "problem types"
msgstr "dạng bài"
#: judge/models/problem.py:39
#: judge/models/problem.py:40
msgid "problem group ID"
msgstr "mã của nhóm bài"
#: judge/models/problem.py:40
#: judge/models/problem.py:41
msgid "problem group name"
msgstr "tên nhóm bài"
#: judge/models/problem.py:47 judge/models/problem.py:116
#: judge/models/problem.py:48 judge/models/problem.py:117
msgid "problem group"
msgstr "nhóm bài"
#: judge/models/problem.py:48
#: judge/models/problem.py:49
msgid "problem groups"
msgstr "nhóm bài"
#: judge/models/problem.py:52
#: judge/models/problem.py:53
msgid "key"
msgstr ""
#: judge/models/problem.py:54
#: judge/models/problem.py:55
msgid "link"
msgstr "đường dẫn"
#: judge/models/problem.py:55
#: judge/models/problem.py:56
msgid "full name"
msgstr "tên đầy đủ"
#: judge/models/problem.py:56 judge/models/profile.py:33
#: judge/models/problem.py:57 judge/models/profile.py:33
#: judge/models/runtime.py:24
msgid "short name"
msgstr "tên ngắn"
#: judge/models/problem.py:57
#: judge/models/problem.py:58
msgid "Displayed on pages under this license"
msgstr "Được hiển thị trên các trang theo giấy phép này"
#: judge/models/problem.py:58
#: judge/models/problem.py:59
msgid "icon"
msgstr "icon"
#: judge/models/problem.py:58
#: judge/models/problem.py:59
msgid "URL to the icon"
msgstr "Đường dẫn icon"
#: judge/models/problem.py:59
#: judge/models/problem.py:60
msgid "license text"
msgstr "văn bản giấy phép"
#: judge/models/problem.py:68
#: judge/models/problem.py:69
msgid "license"
msgstr ""
#: judge/models/problem.py:69
#: judge/models/problem.py:70
msgid "licenses"
msgstr ""
#: judge/models/problem.py:96
#: judge/models/problem.py:97
msgid "problem code"
msgstr ""
#: judge/models/problem.py:98
#: judge/models/problem.py:99
msgid "A short, unique code for the problem, used in the url after /problem/"
msgstr ""
#: judge/models/problem.py:100
#: judge/models/problem.py:101
msgid "problem name"
msgstr ""
#: judge/models/problem.py:101
#: judge/models/problem.py:102
msgid "The full name of the problem, as shown in the problem list."
msgstr ""
#: judge/models/problem.py:103
#: judge/models/problem.py:104
msgid "problem body"
msgstr ""
#: judge/models/problem.py:104
#: judge/models/problem.py:105
msgid "creators"
msgstr ""
#: judge/models/problem.py:105
#: judge/models/problem.py:106
msgid "These users will be able to edit the problem, and be listed as authors."
msgstr ""
#: judge/models/problem.py:107
#: judge/models/problem.py:108
msgid "curators"
msgstr ""
#: judge/models/problem.py:108
#: judge/models/problem.py:109
msgid ""
"These users will be able to edit the problem, but not be listed as authors."
msgstr ""
#: judge/models/problem.py:110
#: judge/models/problem.py:111
msgid "testers"
msgstr ""
#: judge/models/problem.py:112
#: judge/models/problem.py:113
msgid "These users will be able to view the private problem, but not edit it."
msgstr ""
#: judge/models/problem.py:114
#: judge/models/problem.py:115
msgid "The type of problem, as shown on the problem's page."
msgstr ""
#: judge/models/problem.py:117
#: judge/models/problem.py:118
msgid "The group of problem, shown under Category in the problem list."
msgstr ""
#: judge/models/problem.py:119
#: judge/models/problem.py:120
msgid ""
"The time limit for this problem, in seconds. Fractional seconds (e.g. 1.5) "
"are supported."
msgstr ""
#: judge/models/problem.py:123 judge/models/problem.py:437
#: judge/models/problem.py:124 judge/models/problem.py:438
msgid "memory limit"
msgstr ""
#: judge/models/problem.py:124
#: judge/models/problem.py:125
msgid ""
"The memory limit for this problem, in kilobytes (e.g. 64mb = 65536 "
"kilobytes)."
msgstr ""
#: judge/models/problem.py:130
#: judge/models/problem.py:131
msgid ""
"Points awarded for problem completion. Points are displayed with a 'p' "
"suffix if partial."
msgstr ""
#: judge/models/problem.py:133
#: judge/models/problem.py:134
msgid "allows partial points"
msgstr ""
#: judge/models/problem.py:134
#: judge/models/problem.py:135
msgid "allowed languages"
msgstr ""
#: judge/models/problem.py:135
#: judge/models/problem.py:136
msgid "List of allowed submission languages."
msgstr ""
#: judge/models/problem.py:137
#: judge/models/problem.py:138
msgid "manually managed"
msgstr ""
#: judge/models/problem.py:138
#: judge/models/problem.py:139
msgid "Whether judges should be allowed to manage data or not."
msgstr ""
#: judge/models/problem.py:139
#: judge/models/problem.py:140
msgid "date of publishing"
msgstr ""
#: judge/models/problem.py:140
#: judge/models/problem.py:141
msgid ""
"Doesn't have magic ability to auto-publish due to backward compatibility"
msgstr ""
#: judge/models/problem.py:142
#: judge/models/problem.py:143
msgid "Bans the selected users from submitting to this problem."
msgstr ""
#: judge/models/problem.py:144
#: judge/models/problem.py:145
msgid "The license under which this problem is published."
msgstr ""
#: judge/models/problem.py:146
#: judge/models/problem.py:147
msgid "problem summary"
msgstr ""
#: judge/models/problem.py:148
#: judge/models/problem.py:149
msgid "number of users"
msgstr ""
#: judge/models/problem.py:149
#: judge/models/problem.py:150
msgid "The number of users who solved the problem."
msgstr ""
#: judge/models/problem.py:150
#: judge/models/problem.py:151
msgid "solve rate"
msgstr ""
#: judge/models/problem.py:156
#: judge/models/problem.py:157
msgid "If private, only these organizations may see the problem."
msgstr ""
#: judge/models/problem.py:415 judge/models/problem.py:433
#: judge/models/problem.py:416 judge/models/problem.py:434
#: judge/models/runtime.py:111
msgid "language"
msgstr ""
#: judge/models/problem.py:416
#: judge/models/problem.py:417
msgid "translated name"
msgstr ""
#: judge/models/problem.py:417
#: judge/models/problem.py:418
msgid "translated description"
msgstr ""
#: judge/models/problem.py:421
#: judge/models/problem.py:422
msgid "problem translation"
msgstr ""
#: judge/models/problem.py:422
#: judge/models/problem.py:423
msgid "problem translations"
msgstr ""
#: judge/models/problem.py:426
#: judge/models/problem.py:427
msgid "clarified problem"
msgstr ""
#: judge/models/problem.py:427
#: judge/models/problem.py:428
msgid "clarification body"
msgstr ""
#: judge/models/problem.py:428
#: judge/models/problem.py:429
msgid "clarification timestamp"
msgstr ""
#: judge/models/problem.py:443
#: judge/models/problem.py:444
msgid "language-specific resource limit"
msgstr ""
#: judge/models/problem.py:444
#: judge/models/problem.py:445
msgid "language-specific resource limits"
msgstr ""
#: judge/models/problem.py:448
#: judge/models/problem.py:449
msgid "associated problem"
msgstr ""
#: judge/models/problem.py:451
#: judge/models/problem.py:452
msgid "publish date"
msgstr ""
#: judge/models/problem.py:453
#: judge/models/problem.py:454
msgid "editorial content"
msgstr "nội dung lời giải"
#: judge/models/problem.py:469
#: judge/models/problem.py:470
msgid "solution"
msgstr "lời giải"
#: judge/models/problem.py:470
#: judge/models/problem.py:471
msgid "solutions"
msgstr "lời giải"
#: judge/models/problem.py:475
#: judge/models/problem.py:476
#, fuzzy
#| msgid "point value"
msgid "proposed point value"
msgstr "điểm"
#: judge/models/problem.py:476
#: judge/models/problem.py:477
msgid "The amount of points you think this problem deserves."
msgstr ""
#: judge/models/problem.py:486
#: judge/models/problem.py:487
msgid "The time this vote was cast"
msgstr ""
#: judge/models/problem.py:492
#: judge/models/problem.py:493
msgid "vote"
msgstr ""
@ -2386,16 +2398,12 @@ msgid "Page %d of Posts"
msgstr "Trang %d"
#: judge/views/blog.py:134
#, fuzzy
#| msgid "Ticket title"
msgid "Ticket feed"
msgstr "Tiêu đề báo cáo"
msgstr "Báo cáo"
#: judge/views/blog.py:152
#, fuzzy
#| msgid "Comment body"
msgid "Comment feed"
msgstr "Nội dung bình luận"
msgstr "Bình luận"
#: judge/views/comment.py:28
msgid "Messing around, are we?"
@ -2710,42 +2718,40 @@ msgstr "Hướng dẫn cho {0}"
msgid "Editorial for <a href=\"{1}\">{0}</a>"
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
#: judge/views/problem.py:342 templates/blog/list.html:121
#: templates/contest/contest.html:79 templates/user/user-about.html:28
#: templates/user/user-tabs.html:5 templates/user/users-table.html:29
#: judge/views/problem.py:342 templates/contest/contest.html:79
#: templates/user/user-about.html:28 templates/user/user-tabs.html:5
#: templates/user/users-table.html:29
msgid "Problems"
msgstr "Bài tập"
#: judge/views/problem.py:589
#, fuzzy
#| msgid "Problem code"
#: judge/views/problem.py:592
msgid "Problem feed"
msgstr "Mã bài"
msgstr "Bài tập"
#: judge/views/problem.py:685
#: judge/views/problem.py:731
msgid "Banned from submitting"
msgstr "Bị cấm nộp bài"
#: judge/views/problem.py:686
#: judge/views/problem.py:732
msgid ""
"You have been declared persona non grata for this problem. You are "
"permanently barred from submitting this problem."
msgstr "Bạn đã bị cấm nộp bài này."
#: judge/views/problem.py:700
#: judge/views/problem.py:746
msgid "Too many submissions"
msgstr "Quá nhiều lần nộp"
#: judge/views/problem.py:701
#: judge/views/problem.py:747
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."
#: judge/views/problem.py:761 judge/views/problem.py:764
#: judge/views/problem.py:807 judge/views/problem.py:810
#, python-format
msgid "Submit to %(problem)s"
msgstr "Nộp bài cho %(problem)s"
#: judge/views/problem.py:779
#: judge/views/problem.py:825
msgid "Clone Problem"
msgstr "Nhân bản bài tập"
@ -3228,10 +3234,8 @@ msgstr "Xem bài nộp"
#: templates/admin/judge/problem/change_form.html:19
#: templates/admin/judge/problem/change_form.html:22
#, fuzzy
#| msgid "View on site"
msgid "View votes"
msgstr "Xem trên trang"
msgstr "Xem bình chọn"
#: templates/admin/judge/profile/change_form.html:14
#: templates/admin/judge/profile/change_form.html:17
@ -3322,61 +3326,57 @@ msgstr ""
" vào %(time)s\n"
" "
#: templates/blog/list.html:107
msgid "Feed"
msgstr ""
#: templates/blog/list.html:109
msgid "Events"
msgstr "Sự kiện"
#: templates/blog/list.html:117
#: templates/blog/list.html:59
msgid "News"
msgstr "Tin tức"
#: templates/blog/list.html:125 templates/comments/list.html:2
#: templates/blog/list.html:60 templates/comments/list.html:2
msgid "Comments"
msgstr "Bình luận"
#: templates/blog/list.html:129
#: templates/blog/list.html:61
msgid "Tickets"
msgstr "Báo cáo"
#: templates/blog/list.html:148
#: templates/blog/list.html:62
msgid "Events"
msgstr "Sự kiện"
#: templates/blog/list.html:78
msgid "You have no ticket"
msgstr "Bạn không có báo cáo"
#: templates/blog/list.html:163 templates/problem/list.html:347
#: templates/blog/list.html:94 templates/problem/list.html:320
#: templates/problem/problem.html:407
msgid "Clarifications"
msgstr "Thông báo"
#: templates/blog/list.html:169
#: templates/blog/list.html:100
msgid "Add"
msgstr "Thêm mới"
#: templates/blog/list.html:188 templates/problem/list.html:369
#: templates/blog/list.html:119 templates/problem/list.html:342
#: templates/problem/problem.html:418
msgid "No clarifications have been made at this time."
msgstr "Không có thông báo nào."
#: templates/blog/list.html:196
#: templates/blog/list.html:127
msgid "Ongoing contests"
msgstr "Kỳ thi đang diễn ra"
#: templates/blog/list.html:204
#: templates/blog/list.html:135
msgid "Ends in"
msgstr "Còn"
#: templates/blog/list.html:214
#: templates/blog/list.html:145
msgid "Upcoming contests"
msgstr "Kỳ thi sắp diễn ra"
#: templates/blog/list.html:230
#: templates/blog/list.html:161
msgid "Top Rating"
msgstr "Top Rating"
#: templates/blog/list.html:246
#: templates/blog/list.html:177
msgid "Top Score"
msgstr "Top Score"
@ -3593,7 +3593,7 @@ msgstr "Hôm nay"
msgid "Next"
msgstr "Tiếp"
#: templates/contest/contest-list-tabs.html:21
#: templates/contest/contest-list-tabs.html:21 templates/problem/list.html:174
#: templates/problem/problem-list-tabs.html:5
msgid "List"
msgstr "Danh sách"
@ -3714,11 +3714,12 @@ msgstr "Tỷ lệ AC"
#: templates/contest/contest.html:86 templates/contest/list.html:237
#: templates/contest/list.html:291 templates/contest/list.html:371
#: templates/problem/list.html:223 templates/problem/list.html:254
#: templates/problem/list.html:196 templates/problem/list.html:227
msgid "Users"
msgstr "Số lượng"
#: templates/contest/contest.html:111 templates/problem/list.html:330
#: templates/contest/contest.html:111 templates/problem/list.html:231
#: templates/problem/list.html:303
msgid "Editorial"
msgstr "Hướng dẫn"
@ -3738,7 +3739,7 @@ msgstr ""
msgid "Show"
msgstr "Hiển thị"
#: templates/contest/list.html:102 templates/problem/list.html:68
#: templates/contest/list.html:102 templates/problem/list.html:76
msgid "Organizations..."
msgstr "Tổ chức..."
@ -3864,7 +3865,7 @@ msgstr "Thêm vào đó, chỉ những tổ chức này mới được tham gia
msgid "Only the following organizations may access this contest:"
msgstr "Chỉ những tổ chức sau được tham gia kỳ thi:"
#: templates/contest/ranking-table.html:9 templates/problem/search-form.html:35
#: templates/contest/ranking-table.html:9 templates/problem/search-form.html:36
msgid "Organization"
msgstr "Tổ chức"
@ -4249,32 +4250,40 @@ msgstr ""
"viết hướng dẫn này. <br><br> <b>Chép code từ bài hướng dẫn để nộp bài là "
"hành vi có thể dẫn đến khóa tài khoản.</b>"
#: templates/problem/list.html:66
#: templates/problem/list.html:74
msgid "Filter by type..."
msgstr "Lọc theo dạng..."
#: templates/problem/list.html:193
msgid "Hot problems"
msgstr "Bài tập mới"
#: templates/problem/list.html:173
msgid "Feed"
msgstr "Gợi ý"
#: templates/problem/list.html:218 templates/problem/list.html:240
#: templates/problem/search-form.html:45 templates/user/user-problems.html:57
#: templates/problem/list.html:191 templates/problem/list.html:213
#: templates/problem/search-form.html:46 templates/user/user-problems.html:57
msgid "Category"
msgstr "Nhóm"
#: templates/problem/list.html:220 templates/problem/list.html:244
#: templates/problem/list.html:193 templates/problem/list.html:217
msgid "Types"
msgstr "Dạng"
#: templates/problem/list.html:251
#: templates/problem/list.html:224
#, python-format
msgid "AC %%"
msgstr "AC %%"
#: templates/problem/list.html:342
#: templates/problem/list.html:315
msgid "Add clarifications"
msgstr "Thêm thông báo"
#: templates/problem/list.html:351
msgid "FOR YOU"
msgstr "DÀNH CHO BẠN"
#: templates/problem/list.html:354
msgid "NEW"
msgstr "MỚI NHẤT"
#: templates/problem/manage_submission.html:55
msgid "Leave empty to not filter by language"
msgstr "Để trống nếu không lọc theo ngôn ngữ"
@ -4492,40 +4501,40 @@ msgid "Search problems..."
msgstr "Tìm bài tập..."
#: templates/problem/search-form.html:14
msgid "Full text search"
msgstr ""
#: templates/problem/search-form.html:21
msgid "Hide solved problems"
msgstr "Ẩn các bài đã giải"
#: templates/problem/search-form.html:27
#: templates/problem/search-form.html:20
msgid "Show problem types"
msgstr "Hiển thị dạng bài"
#: templates/problem/search-form.html:32
#: templates/problem/search-form.html:26
msgid "Show editorial"
msgstr "Hiển thị hướng dẫn"
#: templates/problem/search-form.html:48 templates/problem/search-form.html:50
#: templates/problem/search-form.html:32
msgid "Have editorial"
msgstr "Có hướng dẫn"
#: templates/problem/search-form.html:49 templates/problem/search-form.html:51
#: templates/submission/submission-list-tabs.html:4
msgid "All"
msgstr "Tất cả"
#: templates/problem/search-form.html:62
#: templates/problem/search-form.html:63
msgid "Problem types"
msgstr "Dạng bài"
#: templates/problem/search-form.html:73
#: templates/problem/search-form.html:74
msgid "Point range"
msgstr "Mốc điểm"
#: templates/problem/search-form.html:79 templates/submission/list.html:331
#: templates/problem/search-form.html:80 templates/submission/list.html:331
#: templates/ticket/list.html:248
msgid "Go"
msgstr "Lọc"
#: templates/problem/search-form.html:80
#: templates/problem/search-form.html:81
msgid "Random"
msgstr "Ngẫu nhiên"
@ -5340,6 +5349,9 @@ msgstr "Thông tin"
msgid "Check all"
msgstr "Chọn tất cả"
#~ msgid "Hot problems"
#~ msgstr "Bài tập mới"
#~ msgid "Discuss <a href=\"{1}\">{0}</a>"
#~ msgstr "Thảo luận <a href=\"{1}\">{0}</a>"

View file

@ -1,6 +1,6 @@
@import "vars";
.blog-content {
.middle-content {
padding-right: 0em;
vertical-align: top;
margin-right: 0;
@ -32,11 +32,18 @@
}
}
.blog-sidebar {
.blog-sidebar, .right-sidebar {
width: 100%;
margin-left: auto;
}
.left-sidebar-item.active {
color: green;
.sidebar-icon {
color: green;
}
}
.blog-sidebox {
h3 {
padding-bottom: 0.25em;
@ -95,19 +102,21 @@
}
.left-sidebar-item {
display: inline-block;
margin-left: 2em;
}
.blog-left-sidebar {
.left-sidebar {
text-align: right;
padding-right: 1em;
margin-bottom: 1em;
border-radius: 7px;
}
}
@media (min-width: 800px) {
.blog-content, .blog-sidebar {
.middle-content, .blog-sidebar, .right-sidebar {
display: block !important;
}
.blog-content {
.middle-content {
margin-right: 1em !important;
}
@ -115,20 +124,20 @@
display: none;
}
#blog-container {
#three-col-container {
display: flex;
}
.blog-content {
.middle-content {
max-width: 71.5%;
margin-left: 10%;
}
.blog-sidebar {
.blog-sidebar, .right-sidebar {
width: 18%;
}
.blog-left-sidebar {
.left-sidebar {
width: 8%;
margin-right: 1em;
position: fixed;
@ -203,7 +212,7 @@
color: gray;
}
.blog-left-sidebar {
.left-sidebar {
background-color: #f0f1f3;
color: #616161;
}

6338
resources/fontawesome/fontawesome.css vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -77,6 +77,7 @@
flex: 26.5%;
max-width: unset;
padding-top: 0;
padding-left: 0;
}
}
@ -293,3 +294,39 @@ ul.problem-list {
font-size: 13px;
}
}
.problem-feed-option {
width: 90%;
margin-left: auto;
margin-right: auto;
padding: 1em;
border-radius: 5px;
margin-bottom: 1em
}
.problem-feed-option-item {
padding: 10px 15px;
border-radius: 2em;
font-weight: bold;
background: lightgray;
margin-right: 1em;
color: gray;
cursor: pointer;
}
.pcodecell {
text-transform: uppercase;
}
.problem-feed-option-item.active {
background: goldenrod;
color: darkblue;
}
@media (max-width: 799px) {
.problem-middle-right {
display: flex;
flex-direction: column-reverse;
}
}

View file

@ -1,21 +1,17 @@
{% extends "base.html" %}
{% block title_row %}{% endblock %}
{% block title_ruler %}{% endblock %}
{% block media %}
<link rel="alternate" type="application/atom+xml" href="{{ url('blog_atom') }}" title="Atom Blog Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('blog_rss') }}" title="RSS Blog Feed">
<link rel="alternate" type="application/atom+xml" href="{{ url('comment_atom') }}" title="Atom Comment Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('comment_rss') }}" title="RSS Comment Feed">
<link rel="alternate" type="application/atom+xml" href="{{ url('problem_atom') }}" title="Atom Problem Feed">
<link rel="alternate" type="application/rss+xml" href="{{ url('problem_rss') }}" title="RSS Problem Feed">
{% extends "three-column-content.html" %}
{% block three_col_media %}
{% include "blog/media-css.html" %}
<style>
@media (max-width: 800px) {
@media (max-width: 799px) {
.title {
clear: both;
}
}
@media (min-width: 800px) {
#event-tab {
display: none;
}
}
.time {
margin-left: 0;
}
@ -36,237 +32,162 @@
#add-clarification:hover {
color: cyan;
}
#content {
width: 99%;
margin-left: 0;
}
</style>
{% endblock %}
{% block js_media %}
{% block three_col_js %}
<script type="text/javascript">
$(document).ready(function () {
$('.time-remaining').each(function () {
count_down($(this));
});
$('.blog-sidebar').hide();
$('#blog-tab').find('a').click(function (e) {
e.preventDefault();
$('#blog-tab').addClass('active');
$('#event-tab').removeClass('active');
$('.blog-content').show();
$('.blog-sidebar').hide();
});
$('#event-tab').find('a').click(function (e) {
$('.right-sidebar').hide();
$('#event-tab').click(function (e) {
e.preventDefault();
$('.left-sidebar-item').removeClass('active');
$('#event-tab').addClass('active');
$('#blog-tab').removeClass('active');
$('.blog-content').hide();
$('.blog-sidebar').show();
$('.middle-content').hide();
$('.right-sidebar').show();
});
$('.blog-description').on('click', function() {
var max_height = $(this).css('max-height');
if (max_height !== 'fit-content') {
$(this).css('max-height', 'fit-content');
$(this).parent().css('background-image', 'inherit')
.css('padding-bottom', '0.5em');
$(this).css('cursor', 'auto');
}
})
$('.blog-description').each(function() {
if ($(this).prop('scrollHeight') > $(this).height() ) {
$(this).parent().css('background-image', '-webkit-linear-gradient(bottom, gray, lightgray 3%, transparent 8%, transparent 100%)');
$(this).parent().css('padding-bottom', '0');
$(this).css('cursor', 'pointer');
}
});
$('.left-sidebar-item').on('click', function() {
var url = $(this).attr('data-href');
window.location.replace(url);
});
{% if feed_type == 'blog' %}
$('#news-icon').css('color', 'green');
{% elif feed_type == 'problem' %}
$('#problems-icon').css('color', 'green');
{% elif feed_type == 'ticket' %}
$('#tickets-icon').css('color', 'green');
{% elif feed_type == 'comment' %}
$('#comments-icon').css('color', 'green');
{% endif %}
});
</script>
{% endblock %}
{% block body %}
{% block before_posts %}{% endblock %}
<div id="mobile" class="tabs">
<ul>
<li id="blog-tab" class="tab active"><a href="#">
<i class="tab-icon fa fa-info-circle"></i> {{ _('Feed') }}
</a></li>
<li id="event-tab" class="tab"><a href="#"><i class="tab-icon fa fa-rss"></i> {{ _('Events') }}</a></li>
</ul>
{% block left_sidebar %}
<div class="left-sidebar">
{{ make_tab_item('blog', 'fa fa-rss', url('home'), _('News')) }}
{{ make_tab_item('comment', 'fa fa-comments', url('comment_feed'), _('Comments')) }}
{{ make_tab_item('ticket', 'fa fa-question-circle', url('ticket_feed'), _('Tickets')) }}
{{ make_tab_item('event', 'fa fa-calendar', '#', _('Events')) }}
</div>
<div id="blog-container">
<div class="blog-left-sidebar">
<h3 class="left-sidebar-header">{{_('Content')}}</h3>
<div class="left-sidebar-item" data-href="{{url('home')}}">
<div class="sidebar-icon" id="news-icon"><i class="fa fa-rss"></i></div>
{{_('News')}}
</div>
<div class="left-sidebar-item" data-href="{{url('problem_feed')}}">
<div class="sidebar-icon" id="problems-icon"><i class="fa fa-tasks"></i></div>
{{_('Problems')}}
</div>
<div class="left-sidebar-item" data-href="{{url('comment_feed')}}">
<div class="sidebar-icon" id="comments-icon"><i class="fa fa-comments"></i></div>
{{_('Comments')}}
</div>
<div class="left-sidebar-item" data-href="{{url('ticket_feed')}}">
<div class="sidebar-icon" id="tickets-icon"><i class="fa fa-question-circle"></i></div>
{{_('Tickets')}}
</div>
</div>
<div class="blog-content">
{% set show_organization_private_icon=True %}
{% if feed_type == 'blog' %}
{% for post in posts %}
{% include "blog/content.html" %}
{% endfor %}
{% elif feed_type == 'problem' %}
{% for problem in problems %}
{% include "problem/feed.html" %}
{% endfor %}
{% elif feed_type == 'ticket' %}
{% if tickets %}
{% for ticket in tickets %}
{% include "ticket/feed.html" %}
{% endfor %}
{% else %}
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
{% endif %}
{% elif feed_type == 'comment' %}
{% for comment in comments %}
{% include "comments/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
{% endif %}
</div>
<div class="blog-sidebar">
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Clarifications') }}
<i class="fa fa-question-circle"></i>
{% if can_edit_contest %}
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
class="fa fa-plus-circle"
id="add-clarification"
title="{{_('Add')}}">
</a>
{% endif %}
</h3>
<div class="sidebox-content">
{% if has_clarifications %}
<ul>
{% for clarification in clarifications %}
<li class="clarification">
<a href="{{ url('problem_detail', clarification.problem.code) }}"
class="problem">
{{ clarification.problem.name }}
</a>
<span class="time">{{ relative_time(clarification.date) }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-clarifications-message">
{{ _('No clarifications have been made at this time.') }}
</p>
{% endif %}
</div>
</div>
{% endif %}
{% if current_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in current_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if future_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in future_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Rating') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_rated %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{user.rating}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Score') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_scorer %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{ user.performance_points|floatformat(0) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% block after_posts %}{% endblock %}
{% endblock %}
{% block bodyend %}
{{ super() }}
{% if REQUIRE_JAX %}
{% include "mathjax-load.html" %}
{% block middle_content %}
{% set show_organization_private_icon=True %}
{% if page_type == 'blog' %}
{% for post in posts %}
{% include "blog/content.html" %}
{% endfor %}
{% elif page_type == 'ticket' %}
{% if tickets %}
{% for ticket in tickets %}
{% include "ticket/feed.html" %}
{% endfor %}
{% else %}
<h3 style="text-align: center">{{_('You have no ticket')}}</h3>
{% endif %}
{% elif page_type == 'comment' %}
{% for comment in comments %}
{% include "comments/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom:10px;margin-top:10px">{% include "list-pages.html" %}</div>
{% endif %}
{% include "comments/math.html" %}
{% endblock %}
{% block right_sidebar %}
<div class="right-sidebar">
{% if request.in_contest_mode and request.participation.contest.use_clarifications %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Clarifications') }}
<i class="fa fa-question-circle"></i>
{% if can_edit_contest %}
<a href="{{url('new_contest_clarification', request.participation.contest.key)}}"
class="fa fa-plus-circle"
id="add-clarification"
title="{{_('Add')}}">
</a>
{% endif %}
</h3>
<div class="sidebox-content">
{% if has_clarifications %}
<ul>
{% for clarification in clarifications %}
<li class="clarification">
<a href="{{ url('problem_detail', clarification.problem.code) }}"
class="problem">
{{ clarification.problem.name }}
</a>
<span class="time">{{ relative_time(clarification.date) }}</span>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-clarifications-message">
{{ _('No clarifications have been made at this time.') }}
</p>
{% endif %}
</div>
</div>
{% endif %}
{% if current_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Ongoing contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in current_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Ends in') }} {{ _('%(countdown)s.', countdown=contest.end_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if future_contests %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Upcoming contests') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content">
{% for contest in future_contests %}
<div class="contest">
<div class="contest-list-title">
<a href="{{ url('contest_view', contest.key) }}">{{ contest.name }}</a>
</div>
<div class="time">
{{ _('Starting in %(countdown)s.', countdown=contest.start_time|as_countdown) }}
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Rating') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_rated %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{user.rating}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="blog-sidebox sidebox">
<h3>{{ _('Top Score') }} <i class="fa fa-trophy"></i></h3>
<div class="sidebox-content" style="padding: 0; border: 0">
<table class="table feed-table">
<tbody>
{% for user in top_scorer %}
<tr>
<td style="padding: 7px 2px"><b>{{loop.index}}</b></td>
<td>{{link_user(user)}}</td>
<td>{{ user.performance_points|floatformat(0) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View file

@ -3,6 +3,13 @@
<a href="{{ url('problem_detail', problem.code) }}">
{{ problem.name }}
</a>
{% if problem.id in completed_problem_ids %}
<i class="solved-problem-color fa fa-check-circle"></i>
{% elif problem.id in attempted_problems %}
<i class="attempted-problem-color fa fa-minus-circle"></i>
{% else %}
<i class="unsolved-problem-color fa fa-minus-circle"></i>
{% endif %}
</h3>
{% with authors=problem.authors.all() %}
{% if authors %}
@ -12,7 +19,7 @@
</div>
{% endif %}
{% endwith %}
{% if true %}
{% if show_types %}
<div class="problem-feed-types">
<i class="fa fa-tag"></i>
{% for type in problem.types_list %}

View file

@ -1,6 +1,5 @@
{% extends "common-content.html" %}
{% block media %}
{% extends "three-column-content.html" %}
{% block three_col_media %}
<link rel="stylesheet" href="{{ static('libs/nouislider.min.css') }}">
<noscript>
<style>
@ -34,11 +33,15 @@
ul.problem-list {
padding: 0 !important;
}
#content {
width: 99%;
margin-left: 0;
}
</style>
{% endif %}
{% endblock %}
{% block js_media %}
{% block three_col_js %}
<script>
window.point_start = {{point_start}};
window.point_end = {{point_end}};
@ -48,6 +51,13 @@
<script src="{{ static('libs/nouislider.min.js') }}" type="text/javascript"></script>
<script>
$(function () {
{% if not request.in_contest_mode %}
// wrap middle and write column
if (window.matchMedia('(max-width: 799px)').matches) {
$('.middle-content').next().addBack().wrapAll('<div class="problem-middle-right"/>');
}
{% endif %}
var $form = $('form#filter-form');
var $search = $('#search');
var $category = $('#category');
@ -83,7 +93,7 @@
$('#go').click(clean_submit);
$('input#full_text, input#hide_solved, input#show_types, input#show_editorial').click(function () {
$('input#full_text, input#hide_solved, input#show_types, input#show_editorial, input#have_editorial').click(function () {
prep_form();
($('<form>').attr('action', window.location.pathname + '?' + $form.serialize())
.append($('<input>').attr('type', 'hidden').attr('name', 'csrfmiddlewaretoken')
@ -91,18 +101,6 @@
.attr('method', 'POST').appendTo($('body')).submit());
});
var info_float = $('.info-float');
var container = $('#content-right');
if (window.bad_browser) {
container.css('float', 'right');
} else if (!featureTest('position', 'sticky')) {
fix_div(info_float, 55);
$(window).resize(function () {
info_float.width(container.width());
});
info_float.width(container.width());
}
var intFormatter = {
to: function (value) {
return value;
@ -159,50 +157,30 @@
return (node.hasClass('p') ? text.replace(/p$/, '') : text);
}
});
window.register_contest_notification("{{url('contest_clarification_ajax', request.participation.contest.key)}}");
{% if request.in_contest_mode %}
$('.left-sidebar').hide();
$('.middle-content').css('max-width', '80%');
{% endif %}
});
</script>
{% endcompress %}
{% endif %}
{% endblock %}
{% block title_ruler %}{% endblock %}
{% block title_row %}
{% set tab = 'list' %}
{% set title = 'Problems' %}
{% include "problem/problem-list-tabs.html" %}
{% endblock %}
{% block body %}
{% if page_obj.num_pages > 1 %}
<div style="margin-bottom: 7px; margin-top: 11px;">
{% include "list-pages.html" %}
{% block left_sidebar %}
{% if not request.in_contest_mode %}
<div class="left-sidebar">
{{ make_tab_item('feed', 'fa fa-pagelines', url('problem_feed'), _('Feed')) }}
{{ make_tab_item('list', 'fa fa-list', url('problem_list'), _('List')) }}
{{ make_tab_item('admin', 'fa fa-edit', url('admin:judge_problem_changelist'), _('Admin')) }}
</div>
{% endif %}
{% endblock %}
<div id="common-content">
{% block before_table %}{% endblock %}
{% if not request.in_contest_mode %}
<div id="content-right" class="problems">
<div class="info-float">
{% include "problem/search-form.html" %}
{% if hot_problems %}
<div class="sidebox">
<h3>{{ _('Hot problems') }} <i class="fa fa-fire"></i></h3>
<div class="sidebox-content">
<ul class="problem-list">{% for problem in hot_problems %}
<li><a href="{{ url('problem_detail', problem.code) }}" class="hot-problem-link">
{{ problem.name }}
</a></li>
{% endfor %}</ul>
</div>
</div>
{% endif %}
</div>
</div>
{% endif %}
{% block middle_content %}
{% if in_contest_mode or page_type == 'list' %}
<div id="content-left" class="problems">
<table id="problem-table" class="table striped">
<thead>
@ -212,9 +190,7 @@
<th class="solved"><i class="fa fa-check"></i></th>
{% endif %}
<th class="problem">{{ _('Problem') }}</th>
<!-- Luong begin -->
<th class="pcode">{{ _('Problem code') }}</th>
<!-- Luong end -->
<th class="category">{{ _('Category') }}</th>
{% if show_types %}
<th>{{ _('Types') }}</th>
@ -255,7 +231,7 @@
</th>
{% if show_editorial %}
<th class="editorial">
Editorial
{{_('Editorial')}}
</th>
{% endif %}
{% endif %}
@ -370,18 +346,34 @@
</p>
{% endif %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
{% endif %}
</div>
</div>
<br>
<!-- Luong begin -->
<script>
$(".pcodecell").each(function(idx, elt){
var pcode = elt.text;
elt.text = pcode.toUpperCase();
});
</script>
<!-- Luong end -->
{% elif page_type == 'feed' %}
<div class="problem-feed-option">
<a href="{{url('problem_feed')}}" class="problem-feed-option-item {{'active' if feed_type=='for_you'}}">
{{_('FOR YOU')}}
</a>
<a href="{{url('problem_feed_new')}}" class="problem-feed-option-item {{'active' if feed_type=='new'}}">
{{_('NEW')}}
</a>
</div>
{% for problem in problems %}
{% include "problem/feed.html" %}
{% endfor %}
{% endif %}
{% if page_obj.num_pages > 1 %}
<div style="margin-top:10px;">{% include "list-pages.html" %}</div>
{% endif %}
{% endblock %}
{% block right_sidebar %}
{% if not request.in_contest_mode %}
<div class="right-sidebar">
<div id="content-right" class="problems">
<div class="info-float">
{% include "problem/search-form.html" %}
</div>
</div>
</div>
{% endif %}
{% endblock %}

View file

@ -7,13 +7,6 @@
<input id="search" type="text" name="search" value="{{ search_query or '' }}"
placeholder="{{ _('Search problems...') }}">
</div>
<!-- {% if has_fts %}
<div>
<input id="full_text" type="checkbox" name="full_text" value="1"
{% if full_text %}checked{% endif %}>
<label for="full_text">{{ _('Full text search') }}</label>
</div>
{% endif %} -->
{% if request.user.is_authenticated %}
<div>
<input id="hide_solved" type="checkbox" name="hide_solved" value="1"
@ -26,11 +19,19 @@
{% if show_types %} checked{% endif %}>
<label for="show_types">{{ _('Show problem types') }}</label>
</div>
<div>
<input id="show_editorial" type="checkbox" name="show_editorial" value="1"
{% if show_editorial %} checked{% endif %}>
<label for="show_editorial">{{ _('Show editorial') }}</label>
</div>
{% if page_type == 'list' %}
<div>
<input id="show_editorial" type="checkbox" name="show_editorial" value="1"
{% if show_editorial %} checked{% endif %}>
<label for="show_editorial">{{ _('Show editorial') }}</label>
</div>
{% elif page_type == 'feed' %}
<div>
<input id="have_editorial" type="checkbox" name="have_editorial" value="1"
{% if have_editorial %} checked{% endif %}>
<label for="have_editorial">{{ _('Have editorial') }}</label>
</div>
{% endif %}
<div class="filter-form-group">
<label for="type"><i>{{ _('Organization') }}</i></label>
<select id="search-org" name="orgs" multiple>

View file

@ -0,0 +1,69 @@
{% extends "base.html" %}
{% block title_row %}{% endblock %}
{% block title_ruler %}{% endblock %}
{% block media %}
<style>
#content {
width: 98%;
margin-left: 0;
}
</style>
{% block three_col_media %}{% endblock %}
{% endblock %}
{% block js_media %}
<script type="text/javascript">
$(document).ready(function () {
$('.left-sidebar-item').on('click', function() {
var url = $(this).attr('data-href');
if (url === '#') return;
window.location.href = url;
});
$('.blog-description').on('click', function() {
var max_height = $(this).css('max-height');
if (max_height !== 'fit-content') {
$(this).css('max-height', 'fit-content');
$(this).parent().css('background-image', 'inherit')
.css('padding-bottom', '0.5em');
$(this).css('cursor', 'auto');
}
})
$('.blog-description').each(function() {
if ($(this).prop('scrollHeight') > $(this).height() ) {
$(this).parent().css('background-image', '-webkit-linear-gradient(bottom, gray, lightgray 3%, transparent 8%, transparent 100%)');
$(this).parent().css('padding-bottom', '0');
$(this).css('cursor', 'pointer');
}
});
});
</script>
{% block three_col_js %}{% endblock %}
{% endblock %}
{% macro make_tab_item(name, fa, url, text) %}
<div class="left-sidebar-item {% if page_type == name %}active{% endif %}" data-href="{{ url }}" id="{{ name }}-tab">
<div class="sidebar-icon"><i class="{{ fa }}"></i></div>
{{ text }}
</div>
{% endmacro %}
{% block body %}
{% block before_posts %}{% endblock %}
<div id="three-col-container">
{% block left_sidebar %}{% endblock %}
<div class="middle-content">
{% block middle_content %}{% endblock %}
</div>
{% block right_sidebar %}{% endblock %}
</div>
{% block after_posts %}{% endblock %}
{% endblock %}
{% block bodyend %}
{{ super() }}
{% if REQUIRE_JAX %}
{% include "mathjax-load.html" %}
{% endif %}
{% include "comments/math.html" %}
{% endblock %}