Merge pull request #2007 from viviicat/url-names
Add names of books/lists/authors/etc as slugs, redirect to slugified version of the page
This commit is contained in:
commit
241169650d
15 changed files with 106 additions and 23 deletions
|
@ -11,20 +11,24 @@ from bookwyrm import forms, models
|
|||
from bookwyrm.activitypub import ActivitypubResponse
|
||||
from bookwyrm.connectors import connector_manager
|
||||
from bookwyrm.settings import PAGE_LENGTH
|
||||
from bookwyrm.views.helpers import is_api_request
|
||||
from bookwyrm.views.helpers import is_api_request, maybe_redirect_local_path
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
class Author(View):
|
||||
"""this person wrote a book"""
|
||||
|
||||
def get(self, request, author_id):
|
||||
# pylint: disable=unused-argument
|
||||
def get(self, request, author_id, slug=None):
|
||||
"""landing page for an author"""
|
||||
author = get_object_or_404(models.Author, id=author_id)
|
||||
|
||||
if is_api_request(request):
|
||||
return ActivitypubResponse(author.to_activity())
|
||||
|
||||
if redirect_local_path := maybe_redirect_local_path(request, author):
|
||||
return redirect_local_path
|
||||
|
||||
books = (
|
||||
models.Work.objects.filter(editions__authors=author)
|
||||
.order_by("created_date")
|
||||
|
|
|
@ -15,14 +15,14 @@ from bookwyrm.activitypub import ActivitypubResponse
|
|||
from bookwyrm.connectors import connector_manager, ConnectorException
|
||||
from bookwyrm.connectors.abstract_connector import get_image
|
||||
from bookwyrm.settings import PAGE_LENGTH
|
||||
from bookwyrm.views.helpers import is_api_request
|
||||
from bookwyrm.views.helpers import is_api_request, maybe_redirect_local_path
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
class Book(View):
|
||||
"""a book! this is the stuff"""
|
||||
|
||||
def get(self, request, book_id, user_statuses=False, update_error=False):
|
||||
def get(self, request, book_id, **kwargs):
|
||||
"""info about a book"""
|
||||
if is_api_request(request):
|
||||
book = get_object_or_404(
|
||||
|
@ -30,7 +30,11 @@ class Book(View):
|
|||
)
|
||||
return ActivitypubResponse(book.to_activity())
|
||||
|
||||
user_statuses = user_statuses if request.user.is_authenticated else False
|
||||
user_statuses = (
|
||||
kwargs.get("user_statuses", False)
|
||||
if request.user.is_authenticated
|
||||
else False
|
||||
)
|
||||
|
||||
# it's safe to use this OR because edition and work and subclasses of the same
|
||||
# table, so they never have clashing IDs
|
||||
|
@ -46,6 +50,11 @@ class Book(View):
|
|||
if not book or not book.parent_work:
|
||||
raise Http404()
|
||||
|
||||
if redirect_local_path := not user_statuses and maybe_redirect_local_path(
|
||||
request, book
|
||||
):
|
||||
return redirect_local_path
|
||||
|
||||
# all reviews for all editions of the book
|
||||
reviews = models.Review.privacy_filter(request.user).filter(
|
||||
book__parent_work__editions=book
|
||||
|
@ -80,7 +89,7 @@ class Book(View):
|
|||
else None,
|
||||
"rating": reviews.aggregate(Avg("rating"))["rating__avg"],
|
||||
"lists": lists,
|
||||
"update_error": update_error,
|
||||
"update_error": kwargs.get("update_error", False),
|
||||
}
|
||||
|
||||
if request.user.is_authenticated:
|
||||
|
|
|
@ -15,7 +15,7 @@ from bookwyrm.activitypub import ActivitypubResponse
|
|||
from bookwyrm.settings import PAGE_LENGTH, STREAMS
|
||||
from bookwyrm.suggested_users import suggested_users
|
||||
from .helpers import filter_stream_by_status_type, get_user_from_username
|
||||
from .helpers import is_api_request, is_bookwyrm_request
|
||||
from .helpers import is_api_request, is_bookwyrm_request, maybe_redirect_local_path
|
||||
from .annual_summary import get_annual_summary_year
|
||||
|
||||
|
||||
|
@ -113,7 +113,8 @@ class DirectMessage(View):
|
|||
class Status(View):
|
||||
"""get posting"""
|
||||
|
||||
def get(self, request, username, status_id):
|
||||
# pylint: disable=unused-argument
|
||||
def get(self, request, username, status_id, slug=None):
|
||||
"""display a particular status (and replies, etc)"""
|
||||
user = get_user_from_username(request.user, username)
|
||||
status = get_object_or_404(
|
||||
|
@ -130,6 +131,9 @@ class Status(View):
|
|||
status.to_activity(pure=not is_bookwyrm_request(request))
|
||||
)
|
||||
|
||||
if redirect_local_path := maybe_redirect_local_path(request, status):
|
||||
return redirect_local_path
|
||||
|
||||
visible_thread = (
|
||||
models.Status.privacy_filter(request.user)
|
||||
.filter(thread_id=status.thread_id)
|
||||
|
|
|
@ -14,17 +14,22 @@ from django.db.models.functions import Greatest
|
|||
|
||||
from bookwyrm import forms, models
|
||||
from bookwyrm.suggested_users import suggested_users
|
||||
from .helpers import get_user_from_username
|
||||
from .helpers import get_user_from_username, maybe_redirect_local_path
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
class Group(View):
|
||||
"""group page"""
|
||||
|
||||
def get(self, request, group_id):
|
||||
# pylint: disable=unused-argument
|
||||
def get(self, request, group_id, slug=None):
|
||||
"""display a group"""
|
||||
|
||||
group = get_object_or_404(models.Group, id=group_id)
|
||||
group.raise_visible_to_user(request.user)
|
||||
|
||||
if redirect_local_path := maybe_redirect_local_path(request, group):
|
||||
return redirect_local_path
|
||||
|
||||
lists = (
|
||||
models.List.privacy_filter(request.user)
|
||||
.filter(group=group)
|
||||
|
@ -80,7 +85,8 @@ class Group(View):
|
|||
class UserGroups(View):
|
||||
"""a user's groups page"""
|
||||
|
||||
def get(self, request, username):
|
||||
# pylint: disable=unused-argument
|
||||
def get(self, request, username, slug=None):
|
||||
"""display a group"""
|
||||
user = get_user_from_username(request.user, username)
|
||||
groups = (
|
||||
|
|
|
@ -8,6 +8,7 @@ from dateutil.parser import ParserError
|
|||
from requests import HTTPError
|
||||
from django.db.models import Q
|
||||
from django.conf import settings as django_settings
|
||||
from django.shortcuts import redirect
|
||||
from django.http import Http404
|
||||
from django.utils import translation
|
||||
|
||||
|
@ -201,3 +202,21 @@ def filter_stream_by_status_type(activities, allowed_types=None):
|
|||
)
|
||||
|
||||
return activities
|
||||
|
||||
|
||||
def maybe_redirect_local_path(request, model):
|
||||
"""
|
||||
if the request had an invalid path, return a permanent redirect response to the
|
||||
correct one, including a slug if any.
|
||||
if path is valid, returns False.
|
||||
"""
|
||||
|
||||
# don't redirect empty path for unit tests which currently have this
|
||||
if request.path in ("/", model.local_path):
|
||||
return False
|
||||
|
||||
new_path = model.local_path
|
||||
if len(request.GET) > 0:
|
||||
new_path = f"{model.local_path}?{request.GET.urlencode()}"
|
||||
|
||||
return redirect(new_path, permanent=True)
|
||||
|
|
|
@ -18,21 +18,27 @@ from django.views.decorators.http import require_POST
|
|||
from bookwyrm import book_search, forms, models
|
||||
from bookwyrm.activitypub import ActivitypubResponse
|
||||
from bookwyrm.settings import PAGE_LENGTH
|
||||
from bookwyrm.views.helpers import is_api_request
|
||||
from bookwyrm.views.helpers import is_api_request, maybe_redirect_local_path
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
class List(View):
|
||||
"""book list page"""
|
||||
|
||||
def get(self, request, list_id, add_failed=False, add_succeeded=False):
|
||||
def get(self, request, list_id, **kwargs):
|
||||
"""display a book list"""
|
||||
add_failed = kwargs.get("add_failed", False)
|
||||
add_succeeded = kwargs.get("add_succeeded", False)
|
||||
|
||||
book_list = get_object_or_404(models.List, id=list_id)
|
||||
book_list.raise_visible_to_user(request.user)
|
||||
|
||||
if is_api_request(request):
|
||||
return ActivitypubResponse(book_list.to_activity(**request.GET))
|
||||
|
||||
if r := maybe_redirect_local_path(request, book_list):
|
||||
return r
|
||||
|
||||
query = request.GET.get("q")
|
||||
suggestions = None
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue