add bookmarks page

This commit is contained in:
Zhao-Linux 2022-11-18 04:21:32 +07:00
parent 8108967959
commit 6e72c08ef4
9 changed files with 143 additions and 9 deletions

View file

@ -404,6 +404,7 @@ urlpatterns = [
),
url(r"^user$", user.UserAboutPage.as_view(), name="user_page"),
url(r"^edit/profile/$", user.edit_profile, name="user_edit_profile"),
url(r"^user/bookmarks", user.UserBookMarkPage.as_view(), name="user_bookmark"),
url(
r"^user/(?P<user>\w+)",
include(

View file

@ -1,8 +1,12 @@
from django.db import models
from django.db.models import CASCADE
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ObjectDoesNotExist
from judge.models import Profile
from judge.models.contest import Contest
from judge.models.interface import BlogPost
from judge.models.problem import Problem, Solution
__all__ = ["BookMark"]
@ -21,12 +25,28 @@ class BookMark(models.Model):
else:
return False
def page_object(self):
try:
page = self.page
if page.startswith("p:"):
return Problem.objects.get(code=page[2:])
elif page.startswith("c:"):
return Contest.objects.get(key=page[2:])
elif page.startswith("b:"):
return BlogPost.objects.get(id=page[2:])
elif page.startswith("s:"):
return Solution.objects.get(problem__code=page[2:])
return None
except ObjectDoesNotExist:
return None
class Meta:
verbose_name = _("bookmark")
verbose_name_plural = _("bookmarks")
def __str__(self):
return f"bookmark for {self.page}"
return self.page
class MakeBookMark(models.Model):
bookmark = models.ForeignKey(BookMark, related_name="bookmark", on_delete=CASCADE)

View file

@ -129,7 +129,7 @@ class PostList(FeedView, PageVoteListView, BookMarkListView):
.order_by()
}
context = self.add_pagevote_context_data(context)
context = self.add_bookmark_context_data(context)
return context
def get_comment_page(self, post):

View file

@ -76,10 +76,8 @@ class BookMarkDetailView(TemplateResponseMixin, SingleObjectMixin, View):
return context
class BookMarkListView(ListView):
def get_context_data(self, **kwargs):
context = super(BookMarkListView, self).get_context_data(**kwargs)
for item in context["object_list"]:
def add_bookmark_context_data(self, context, obj_list="object_list"):
for item in context[obj_list]:
bookmark, _ = BookMark.objects.get_or_create(
page=self.get_comment_page(item)
)

View file

@ -72,6 +72,7 @@ from judge.views.problem import ProblemList
from judge.views.contests import ContestList
from judge.views.submission import AllSubmissions, SubmissionsListBase
from judge.views.pagevote import PageVoteListView
from judge.views.bookmark import BookMarkListView
__all__ = [
"OrganizationList",
@ -266,7 +267,7 @@ class OrganizationList(TitleMixin, ListView, OrganizationBase):
return context
class OrganizationHome(OrganizationDetailView, PageVoteListView):
class OrganizationHome(OrganizationDetailView, PageVoteListView, BookMarkListView):
template_name = "organization/home.html"
pagevote_object_name = "posts"
@ -294,6 +295,7 @@ class OrganizationHome(OrganizationDetailView, PageVoteListView):
context["title"] = self.object.name
context["posts"], context["page_obj"] = self.get_posts_and_page_obj()
context = self.add_pagevote_context_data(context, "posts")
context = self.add_bookmark_context_data(context, "posts")
# Hack: This allows page_obj to have page_range for non-ListView class
setattr(

View file

@ -13,6 +13,7 @@ from django.db import transaction
from django.db.models import Count, Max, Min
from django.db.models.fields import DateField
from django.db.models.functions import Cast, ExtractYear
from judge.models.bookmark import MakeBookMark
from django.forms import Form
from django.http import (
Http404,
@ -52,7 +53,7 @@ from judge.utils.views import (
)
from .contests import ContestRanking
__all__ = ["UserPage", "UserAboutPage", "UserProblemsPage", "users", "edit_profile"]
__all__ = ["UserPage", "UserAboutPage", "UserProblemsPage", "UserBookMarkPage", "users", "edit_profile"]
def remap_keys(iterable, mapping):
@ -349,6 +350,27 @@ class UserProblemsPage(UserPage):
return context
class UserBookMarkPage(UserPage):
template_name = "user/user-bookmarks.html"
def get_context_data(self, **kwargs):
context = super(UserBookMarkPage, self).get_context_data(**kwargs)
makedownlist = MakeBookMark.objects.filter(user=self.object)
pagelist = makedownlist.filter(bookmark__page__startswith='b')
problemlist = makedownlist.filter(bookmark__page__startswith='p')
contestlist = makedownlist.filter(bookmark__page__startswith='c')
context["pagelist"] = makedownlist
context["postlist"] = pagelist
context["problemlist"] = problemlist
context["contestlist"] = contestlist
context["haspost"] = pagelist.exists()
context["hasproblem"] = problemlist.exists()
context["hascontest"] = contestlist.exists()
return context
class UserPerformancePointsAjax(UserProblemsPage):
template_name = "user/pp-table-body.html"

View file

@ -30,7 +30,7 @@
onclick="javascript:bookmark({{ bookmark.id }})"
>
<i class="fa fa-bookmark-o" style="font-size: large;"></i>
<span class="actionbar-text">{{_("Bookmark")}} {{ bookmark.id }} </span>
<span class="actionbar-text">{{_("Bookmark")}}</span>
</span>
</span>
<span class="actionbar-block">

View file

@ -0,0 +1,90 @@
{% extends "user/user-base.html" %}
{% block title_ruler %}{% endblock %}
{% block title_row %}
{% set tab = 'bookmark' %}
{% include "user/user-tabs.html" %}
{% endblock %}
{% block user_content %}
{% if haspost %}
<div class="bookmark-group">
<h3 class="unselectable toggle closed">
<span class="fa fa-chevron-right fa-fw"></span>{{ _('Bookmarked Posts') }} ({{ postlist|length }})
</h3>
<table style="display: none" class="table toggled">
<thead>
<tr>
<th>{{ _('Post') }}</th>
</tr>
</thead>
<tbody>
{% for post in postlist %}
<tr>
<td class="bookmark-name">
<a href="{{ url('blog_post', post.bookmark.page_object().id, post.bookmark.page_object().slug) }}">{{ post.bookmark.page_object().title}} </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<i>{{ _('You have not yet bookmarked any post.') }}</i>
{% endif %}
<hr>
{% if hasproblem %}
<div class="bookmark-group">
<h3 class="unselectable toggle closed">
<span class="fa fa-chevron-right fa-fw"></span>{{ _('Bookmarked Problems') }} ({{ problemlist|length }})
</h3>
<table style="display: none" class="table toggled">
<thead>
<tr>
<th>{{ _('Problem') }}</th>
</tr>
</thead>
<tbody>
{% for problem in problemlist %}
<tr>
<td class="bookmark-name">
<a href="{{ url('problem_detail', problem.bookmark.page_object().code) }}">{{ problem.bookmark.page_object().name}} </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<i>{{ _('You have not yet bookmarked any problem.') }}</i>
{% endif %}
<hr>
{% if hascontest %}
<div class="bookmark-group">
<h3 class="unselectable toggle closed">
<span class="fa fa-chevron-right fa-fw"></span>{{ _('Bookmarked Contests') }} ({{ contestlist|length }})
</h3>
<table style="display: none" class="table toggled">
<thead>
<tr>
<th>{{ _('Contest') }}</th>
</tr>
</thead>
<tbody>
{% for contest in contestlist %}
<tr>
<td class="bookmark-name">
<a href="{{ url('contest_view', contest.bookmark.page_object().key) }}">{{ contest.bookmark.page_object().name}} </a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<i>{{ _('You have not yet bookmarked any contest.') }}</i>
{% endif %}
<hr>
{% endblock %}

View file

@ -7,6 +7,7 @@
{{ make_tab('impersonate', 'fa-eye', url('impersonate-start', user.user.id), _('Impersonate')) }}
{% endif %}
{% if user.user == request.user %}
{{ make_tab('bookmark', 'fa-bookmark', url('user_bookmark'), _('Bookmark')) }}
{{ make_tab('edit', 'fa-edit', url('user_edit_profile'), _('Edit profile')) }}
{% else %}
{% if perms.auth.change_user %}