Adds "all books" view"

This commit is contained in:
Mouse Reeve 2021-03-31 10:23:20 -07:00
parent 2fd917a6cc
commit a670c8d366
4 changed files with 27 additions and 34 deletions

View file

@ -20,10 +20,13 @@
<div class="column"> <div class="column">
<div class="tabs"> <div class="tabs">
<ul> <ul>
<li class="{% if shelf.identifier == 'all' %}is-active{% endif %}">
<a href="{% url 'user-shelves' user|username %}"{% if shelf.identifier == 'all' %} aria-current="page"{% endif %}>{% trans "All books" %}</a>
</li>
{% for shelf_tab in shelves %} {% for shelf_tab in shelves %}
<li class="{% if shelf_tab.identifier == shelf.identifier %}is-active{% endif %}"> <li class="{% if shelf_tab.identifier == shelf.identifier %}is-active{% endif %}">
<a href="{{ shelf_tab.local_path }}"{% if shelf_tab.identifier == shelf.identifier %} aria-current="page"{% endif %}>{% if shelf_tab.identifier == 'to-read' %}{% trans "To Read" %}{% elif shelf_tab.identifier == 'reading' %}{% trans "Currently Reading" %}{% elif shelf_tab.identifier == 'read' %}{% trans "Read" %}{% else %}{{ shelf_tab.name }}{% endif %}</a> <a href="{{ shelf_tab.local_path }}"{% if shelf_tab.identifier == shelf.identifier %} aria-current="page"{% endif %}>{% if shelf_tab.identifier == 'to-read' %}{% trans "To Read" %}{% elif shelf_tab.identifier == 'reading' %}{% trans "Currently Reading" %}{% elif shelf_tab.identifier == 'read' %}{% trans "Read" %}{% else %}{{ shelf_tab.name }}{% endif %}</a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
@ -81,7 +84,6 @@
{% endif %} {% endif %}
</tr> </tr>
{% for book in books %} {% for book in books %}
{% with book=book.book %}
<tr class="book-preview"> <tr class="book-preview">
<td> <td>
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book size="small" %}</a> <a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book size="small" %}</a>
@ -113,13 +115,12 @@
</td> </td>
{% endif %} {% endif %}
</tr> </tr>
{% endwith %}
{% endfor %} {% endfor %}
</table> </table>
</div> </div>
{% else %} {% else %}
<p>{% trans "This shelf is empty." %}</p> <p>{% trans "This shelf is empty." %}</p>
{% if shelf.editable %} {% if shelf.id and shelf.editable %}
<form name="delete-shelf" action="/delete-shelf/{{ shelf.id }}" method="post"> <form name="delete-shelf" action="/delete-shelf/{{ shelf.id }}" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="user" value="{{ request.user.id }}"> <input type="hidden" name="user" value="{{ request.user.id }}">

View file

@ -151,8 +151,8 @@ urlpatterns = [
re_path( re_path(
r"^list/(?P<list_id>\d+)/curate/?$", views.Curate.as_view(), name="list-curate" r"^list/(?P<list_id>\d+)/curate/?$", views.Curate.as_view(), name="list-curate"
), ),
# shelf # Uyser books
re_path(r"%s/books/?$" % user_path, views.user_shelves_page, name="user-shelves"), re_path(r"%s/books/?$" % user_path, views.Shelf.as_view(), name="user-shelves"),
re_path( re_path(
r"^%s/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % user_path, r"^%s/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % user_path,
views.Shelf.as_view(), views.Shelf.as_view(),

View file

@ -27,7 +27,7 @@ from .rss_feed import RssFeed
from .password import PasswordResetRequest, PasswordReset, ChangePassword from .password import PasswordResetRequest, PasswordReset, ChangePassword
from .search import Search from .search import Search
from .shelf import Shelf from .shelf import Shelf
from .shelf import user_shelves_page, create_shelf, delete_shelf from .shelf import create_shelf, delete_shelf
from .shelf import shelve, unshelve from .shelf import shelve, unshelve
from .site import Site from .site import Site
from .status import CreateStatus, DeleteStatus from .status import CreateStatus, DeleteStatus

View file

@ -1,4 +1,6 @@
""" shelf views""" """ shelf views"""
from collections import namedtuple
from django.db import IntegrityError from django.db import IntegrityError
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator from django.core.paginator import Paginator
@ -6,6 +8,7 @@ from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _
from django.views import View from django.views import View
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
@ -13,14 +16,14 @@ from bookwyrm import forms, models
from bookwyrm.activitypub import ActivitypubResponse from bookwyrm.activitypub import ActivitypubResponse
from bookwyrm.settings import PAGE_LENGTH from bookwyrm.settings import PAGE_LENGTH
from .helpers import is_api_request, get_edition, get_user_from_username from .helpers import is_api_request, get_edition, get_user_from_username
from .helpers import handle_reading_status from .helpers import handle_reading_status, privacy_filter, object_visible_to_user
# pylint: disable= no-self-use # pylint: disable= no-self-use
class Shelf(View): class Shelf(View):
""" shelf page """ """ shelf page """
def get(self, request, username, shelf_identifier): def get(self, request, username, shelf_identifier=None):
""" display a shelf """ """ display a shelf """
try: try:
user = get_user_from_username(request.user, username) user = get_user_from_username(request.user, username)
@ -32,35 +35,28 @@ class Shelf(View):
except ValueError: except ValueError:
page = 1 page = 1
shelves = privacy_filter(request.user, user.shelf_set)
# get the shelf and make sure the logged in user should be able to see it
if shelf_identifier: if shelf_identifier:
shelf = user.shelf_set.get(identifier=shelf_identifier) shelf = user.shelf_set.get(identifier=shelf_identifier)
if not object_visible_to_user(request.user, shelf):
return HttpResponseNotFound()
# this is a constructed "all books" view, with a fake "shelf" obj
else: else:
shelf = user.shelf_set.first() FakeShelf = namedtuple("Shelf", ("identifier", "name", "user", "books"))
books = models.Edition.objects.filter(
shelfbook__shelf__in=shelves.all()
).distinct()
shelf = FakeShelf("all", _("All books"), user, books)
is_self = request.user == user is_self = request.user == user
shelves = user.shelf_set
if not is_self:
follower = user.followers.filter(id=request.user.id).exists()
# make sure the user has permission to view the shelf
if shelf.privacy == "direct" or (
shelf.privacy == "followers" and not follower
):
return HttpResponseNotFound()
# only show other shelves that should be visible
if follower:
shelves = shelves.filter(privacy__in=["public", "followers"])
else:
shelves = shelves.filter(privacy="public")
if is_api_request(request): if is_api_request(request):
return ActivitypubResponse(shelf.to_activity(**request.GET)) return ActivitypubResponse(shelf.to_activity(**request.GET))
paginated = Paginator( paginated = Paginator(
models.ShelfBook.objects.filter(user=user, shelf=shelf) shelf.books.order_by("-updated_date").all(),
.order_by("-updated_date")
.all(),
PAGE_LENGTH, PAGE_LENGTH,
) )
@ -95,11 +91,6 @@ class Shelf(View):
return redirect(shelf.local_path) return redirect(shelf.local_path)
def user_shelves_page(request, username):
""" default shelf """
return Shelf.as_view()(request, username, None)
@login_required @login_required
@require_POST @require_POST
def create_shelf(request): def create_shelf(request):
@ -176,7 +167,8 @@ def shelve(request):
models.ShelfBook.objects.create( models.ShelfBook.objects.create(
book=book, shelf=desired_shelf, user=request.user book=book, shelf=desired_shelf, user=request.user
) )
# The book is already on this shelf. Might be good to alert, or reject the action? # The book is already on this shelf.
# Might be good to alert, or reject the action?
except IntegrityError: except IntegrityError:
pass pass
return redirect(request.headers.get("Referer", "/")) return redirect(request.headers.get("Referer", "/"))