mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-09-29 23:02:02 +00:00
Generation of slugs and new urls to handle slugs
- TODO: redirect to correct slug if not found.
This commit is contained in:
parent
0751a56474
commit
ebf463fc91
22 changed files with 71 additions and 29 deletions
|
@ -55,7 +55,7 @@ class Author(BookDataModel):
|
||||||
"""generate the url from the openlibrary id"""
|
"""generate the url from the openlibrary id"""
|
||||||
return f"https://openlibrary.org/authors/{self.openlibrary_key}"
|
return f"https://openlibrary.org/authors/{self.openlibrary_key}"
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""editions and works both use "book" instead of model_name"""
|
"""editions and works both use "book" instead of model_name"""
|
||||||
return f"https://{DOMAIN}/author/{self.id}"
|
return f"https://{DOMAIN}/author/{self.id}"
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.db.models import Q
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.utils.text import slugify
|
||||||
|
|
||||||
from bookwyrm.settings import DOMAIN
|
from bookwyrm.settings import DOMAIN
|
||||||
from .fields import RemoteIdField
|
from .fields import RemoteIdField
|
||||||
|
@ -34,14 +35,31 @@ class BookWyrmModel(models.Model):
|
||||||
updated_date = models.DateTimeField(auto_now=True)
|
updated_date = models.DateTimeField(auto_now=True)
|
||||||
remote_id = RemoteIdField(null=True, activitypub_field="id")
|
remote_id = RemoteIdField(null=True, activitypub_field="id")
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""generate a url that resolves to the local object"""
|
"""generate the url that resolves to the local object, without a slug"""
|
||||||
base_path = f"https://{DOMAIN}"
|
base_path = f"https://{DOMAIN}"
|
||||||
if hasattr(self, "user"):
|
if hasattr(self, "user"):
|
||||||
base_path = f"{base_path}{self.user.local_path}"
|
base_path = f"{base_path}{self.user.local_path}"
|
||||||
|
|
||||||
model_name = type(self).__name__.lower()
|
model_name = type(self).__name__.lower()
|
||||||
return f"{base_path}/{model_name}/{self.id}"
|
return f"{base_path}/{model_name}/{self.id}"
|
||||||
|
|
||||||
|
def get_remote_id(self):
|
||||||
|
"""generate a url that resolves to the local object, with a slug suffix"""
|
||||||
|
path = self.get_permalink()
|
||||||
|
|
||||||
|
name = None
|
||||||
|
if hasattr(self, "name_field"):
|
||||||
|
name = getattr(self, self.name_field)
|
||||||
|
elif hasattr(self, "name"):
|
||||||
|
name = self.name
|
||||||
|
|
||||||
|
if name:
|
||||||
|
slug = slugify(name)
|
||||||
|
path = f"{path}/s/{slug}"
|
||||||
|
|
||||||
|
return path
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""this is just here to provide default fields for other models"""
|
"""this is just here to provide default fields for other models"""
|
||||||
|
|
||||||
|
|
|
@ -203,7 +203,7 @@ class Book(BookDataModel):
|
||||||
|
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""editions and works both use "book" instead of model_name"""
|
"""editions and works both use "book" instead of model_name"""
|
||||||
return f"https://{DOMAIN}/book/{self.id}"
|
return f"https://{DOMAIN}/book/{self.id}"
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Group(BookWyrmModel):
|
||||||
description = fields.TextField(blank=True, null=True)
|
description = fields.TextField(blank=True, null=True)
|
||||||
privacy = fields.PrivacyField()
|
privacy = fields.PrivacyField()
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""don't want the user to be in there in this case"""
|
"""don't want the user to be in there in this case"""
|
||||||
return f"https://{DOMAIN}/group/{self.id}"
|
return f"https://{DOMAIN}/group/{self.id}"
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ class List(OrderedCollectionMixin, BookWyrmModel):
|
||||||
embed_key = models.UUIDField(unique=True, null=True, editable=False)
|
embed_key = models.UUIDField(unique=True, null=True, editable=False)
|
||||||
activity_serializer = activitypub.BookList
|
activity_serializer = activitypub.BookList
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""don't want the user to be in there in this case"""
|
"""don't want the user to be in there in this case"""
|
||||||
return f"https://{DOMAIN}/list/{self.id}"
|
return f"https://{DOMAIN}/list/{self.id}"
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ class UserRelationship(BookWyrmModel):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""use shelf identifier in remote_id"""
|
"""use shelf identifier in remote_id"""
|
||||||
base_path = self.user_subject.remote_id
|
base_path = self.user_subject.remote_id
|
||||||
return f"{base_path}#follows/{self.id}"
|
return f"{base_path}#follows/{self.id}"
|
||||||
|
|
|
@ -21,7 +21,7 @@ class Report(BookWyrmModel):
|
||||||
links = models.ManyToManyField("Link", blank=True)
|
links = models.ManyToManyField("Link", blank=True)
|
||||||
resolved = models.BooleanField(default=False)
|
resolved = models.BooleanField(default=False)
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
return f"https://{DOMAIN}/settings/reports/{self.id}"
|
return f"https://{DOMAIN}/settings/reports/{self.id}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
||||||
"""can the shelf be safely deleted?"""
|
"""can the shelf be safely deleted?"""
|
||||||
return self.editable and not self.shelfbook_set.exists()
|
return self.editable and not self.shelfbook_set.exists()
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""shelf identifier instead of id"""
|
"""shelf identifier instead of id"""
|
||||||
base_path = self.user.remote_id
|
base_path = self.user.remote_id
|
||||||
identifier = self.identifier or self.get_identifier()
|
identifier = self.identifier or self.get_identifier()
|
||||||
|
|
|
@ -396,7 +396,7 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
|
||||||
activity_serializer = activitypub.PublicKey
|
activity_serializer = activitypub.PublicKey
|
||||||
serialize_reverse_fields = [("owner", "owner", "id")]
|
serialize_reverse_fields = [("owner", "owner", "id")]
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
# self.owner is set by the OneToOneField on User
|
# self.owner is set by the OneToOneField on User
|
||||||
return f"{self.owner.remote_id}/#main-key"
|
return f"{self.owner.remote_id}/#main-key"
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ class AnnualGoal(BookWyrmModel):
|
||||||
|
|
||||||
unique_together = ("user", "year")
|
unique_together = ("user", "year")
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_permalink(self):
|
||||||
"""put the year in the path"""
|
"""put the year in the path"""
|
||||||
return f"{self.user.remote_id}/goal/{self.year}"
|
return f"{self.user.remote_id}/goal/{self.year}"
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@
|
||||||
{% if user_statuses.review_count or user_statuses.comment_count or user_statuses.quotation_count %}
|
{% if user_statuses.review_count or user_statuses.comment_count or user_statuses.quotation_count %}
|
||||||
<nav class="tabs">
|
<nav class="tabs">
|
||||||
<ul>
|
<ul>
|
||||||
{% url 'book' book.id as tab_url %}
|
{% url 'book' book.id book.name|slugify as tab_url %}
|
||||||
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
<li {% if tab_url == request.path %}class="is-active"{% endif %}>
|
||||||
<a href="{{ tab_url }}#reviews">{% trans "Reviews" %} ({{ review_count }})</a>
|
<a href="{{ tab_url }}#reviews">{% trans "Reviews" %} ({{ review_count }})</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<nav class="breadcrumb subtitle" aria-label="breadcrumbs">
|
<nav class="breadcrumb subtitle" aria-label="breadcrumbs">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{% url 'book' book.id %}">{{ book|book_title }}</a></li>
|
<li><a href="{% url 'book' book.id book.name|slugify %}">{{ book|book_title }}</a></li>
|
||||||
<li class="is-active">
|
<li class="is-active">
|
||||||
<a href="#" aria-current="page">
|
<a href="#" aria-current="page">
|
||||||
{% trans "Edit links" %}
|
{% trans "Edit links" %}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<nav class="breadcrumb subtitle" aria-label="breadcrumbs">
|
<nav class="breadcrumb subtitle" aria-label="breadcrumbs">
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{% url 'lists' %}">{% trans "Lists" %}</a></li>
|
<li><a href="{% url 'lists' %}">{% trans "Lists" %}</a></li>
|
||||||
<li><a href="{% url 'list' list.id %}">{{ list.name|truncatechars:30 }}</a></li>
|
<li><a href="{% url 'list' list_id=list.id slug=list.name|slugify %}">{{ list.name|truncatechars:30 }}</a></li>
|
||||||
<li class="is-active">
|
<li class="is-active">
|
||||||
<a href="#" aria-current="page">
|
<a href="#" aria-current="page">
|
||||||
{% trans "Curate" %}
|
{% trans "Curate" %}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
<form name="edit-list" method="post" action="{% url 'list' list.id %}">
|
<form name="edit-list" method="post" action="{% url 'list' list_id=list.id slug=list.name|slugify %}">
|
||||||
{% include 'lists/form.html' %}
|
{% include 'lists/form.html' %}
|
||||||
</form>
|
</form>
|
||||||
{% include "lists/delete_list_modal.html" with id="delete_list" %}
|
{% include "lists/delete_list_modal.html" with id="delete_list" %}
|
||||||
|
|
|
@ -180,7 +180,7 @@
|
||||||
<h2 class="title is-5">
|
<h2 class="title is-5">
|
||||||
{% trans "Sort List" %}
|
{% trans "Sort List" %}
|
||||||
</h2>
|
</h2>
|
||||||
<form name="sort" action="{% url 'list' list.id %}" method="GET" class="block">
|
<form name="sort" action="{% url 'list' list_id=list.id slug=list.name|slugify %}" method="GET" class="block">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="id_sort_by">{% trans "Sort By" %}</label>
|
<label class="label" for="id_sort_by">{% trans "Sort By" %}</label>
|
||||||
<div class="select is-fullwidth">
|
<div class="select is-fullwidth">
|
||||||
|
@ -207,7 +207,7 @@
|
||||||
{% trans "Suggest Books" %}
|
{% trans "Suggest Books" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</h2>
|
</h2>
|
||||||
<form name="search" action="{% url 'list' list.id %}" method="GET" class="block">
|
<form name="search" action="{% url 'list' list_id=list.id slug=list.name|slugify %}" method="GET" class="block">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input aria-label="{% trans 'Search for a book' %}" class="input" type="text" name="q" placeholder="{% trans 'Search for a book' %}" value="{{ query }}">
|
<input aria-label="{% trans 'Search for a book' %}" class="input" type="text" name="q" placeholder="{% trans 'Search for a book' %}" value="{{ query }}">
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if query %}
|
{% if query %}
|
||||||
<p class="help"><a href="{% url 'list' list.id %}">{% trans "Clear search" %}</a></p>
|
<p class="help"><a href="{% url 'list' list_id=list.id slug=list.name|slugify %}">{% trans "Clear search" %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
{% if not suggested_books %}
|
{% if not suggested_books %}
|
||||||
|
|
|
@ -372,7 +372,10 @@ urlpatterns = [
|
||||||
# groups
|
# groups
|
||||||
re_path(rf"{USER_PATH}/groups/?$", views.UserGroups.as_view(), name="user-groups"),
|
re_path(rf"{USER_PATH}/groups/?$", views.UserGroups.as_view(), name="user-groups"),
|
||||||
re_path(
|
re_path(
|
||||||
r"^group/(?P<group_id>\d+)(.json)?/?$", views.Group.as_view(), name="group"
|
rf"^group/(?P<group_id>\d+)(.json)?/?$", views.Group.as_view(), name="group"
|
||||||
|
),
|
||||||
|
re_path(
|
||||||
|
rf"^group/(?P<group_id>\d+){regex.SLUG}/?$", views.Group.as_view(), name="group"
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^group/delete/(?P<group_id>\d+)/?$", views.delete_group, name="delete-group"
|
r"^group/delete/(?P<group_id>\d+)/?$", views.delete_group, name="delete-group"
|
||||||
|
@ -400,7 +403,8 @@ urlpatterns = [
|
||||||
re_path(rf"{USER_PATH}/lists/?$", views.UserLists.as_view(), name="user-lists"),
|
re_path(rf"{USER_PATH}/lists/?$", views.UserLists.as_view(), name="user-lists"),
|
||||||
re_path(r"^list/?$", views.Lists.as_view(), name="lists"),
|
re_path(r"^list/?$", views.Lists.as_view(), name="lists"),
|
||||||
re_path(r"^list/saved/?$", views.SavedLists.as_view(), name="saved-lists"),
|
re_path(r"^list/saved/?$", views.SavedLists.as_view(), name="saved-lists"),
|
||||||
re_path(r"^list/(?P<list_id>\d+)(.json)?/?$", views.List.as_view(), name="list"),
|
re_path(rf"^list/(?P<list_id>\d+)(\.json)?/?$", views.List.as_view(), name="list"),
|
||||||
|
re_path(rf"^list/(?P<list_id>\d+){regex.SLUG}/?$", views.List.as_view(), name="list"),
|
||||||
re_path(
|
re_path(
|
||||||
r"^list/(?P<list_id>\d+)/item/(?P<list_item>\d+)/?$",
|
r"^list/(?P<list_id>\d+)/item/(?P<list_item>\d+)/?$",
|
||||||
views.ListItem.as_view(),
|
views.ListItem.as_view(),
|
||||||
|
@ -435,11 +439,21 @@ urlpatterns = [
|
||||||
views.Shelf.as_view(),
|
views.Shelf.as_view(),
|
||||||
name="shelf",
|
name="shelf",
|
||||||
),
|
),
|
||||||
|
re_path(
|
||||||
|
rf"^{USER_PATH}/(shelf|books)/(?P<shelf_identifier>[\w-]+){regex.SLUG}/?$",
|
||||||
|
views.Shelf.as_view(),
|
||||||
|
name="shelf",
|
||||||
|
),
|
||||||
re_path(
|
re_path(
|
||||||
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$",
|
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$",
|
||||||
views.Shelf.as_view(),
|
views.Shelf.as_view(),
|
||||||
name="shelf",
|
name="shelf",
|
||||||
),
|
),
|
||||||
|
re_path(
|
||||||
|
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+){regex.SLUG}/?$",
|
||||||
|
views.Shelf.as_view(),
|
||||||
|
name="shelf",
|
||||||
|
),
|
||||||
re_path(r"^create-shelf/?$", views.create_shelf, name="shelf-create"),
|
re_path(r"^create-shelf/?$", views.create_shelf, name="shelf-create"),
|
||||||
re_path(r"^delete-shelf/(?P<shelf_id>\d+)/?$", views.delete_shelf),
|
re_path(r"^delete-shelf/(?P<shelf_id>\d+)/?$", views.delete_shelf),
|
||||||
re_path(r"^shelve/?$", views.shelve),
|
re_path(r"^shelve/?$", views.shelve),
|
||||||
|
@ -464,6 +478,7 @@ urlpatterns = [
|
||||||
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),
|
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),
|
||||||
# statuses
|
# statuses
|
||||||
re_path(rf"{STATUS_PATH}(.json)?/?$", views.Status.as_view(), name="status"),
|
re_path(rf"{STATUS_PATH}(.json)?/?$", views.Status.as_view(), name="status"),
|
||||||
|
re_path(rf"{STATUS_PATH}{regex.SLUG}/?$", views.Status.as_view(), name="status"),
|
||||||
re_path(rf"{STATUS_PATH}/activity/?$", views.Status.as_view(), name="status"),
|
re_path(rf"{STATUS_PATH}/activity/?$", views.Status.as_view(), name="status"),
|
||||||
re_path(
|
re_path(
|
||||||
rf"{STATUS_PATH}/replies(.json)?/?$", views.Replies.as_view(), name="replies"
|
rf"{STATUS_PATH}/replies(.json)?/?$", views.Replies.as_view(), name="replies"
|
||||||
|
@ -500,6 +515,7 @@ urlpatterns = [
|
||||||
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
|
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
|
||||||
# books
|
# books
|
||||||
re_path(rf"{BOOK_PATH}(.json)?/?$", views.Book.as_view(), name="book"),
|
re_path(rf"{BOOK_PATH}(.json)?/?$", views.Book.as_view(), name="book"),
|
||||||
|
re_path(rf"{BOOK_PATH}{regex.SLUG}/?$", views.Book.as_view(), name="book"),
|
||||||
re_path(
|
re_path(
|
||||||
rf"{BOOK_PATH}/(?P<user_statuses>review|comment|quote)/?$",
|
rf"{BOOK_PATH}/(?P<user_statuses>review|comment|quote)/?$",
|
||||||
views.Book.as_view(),
|
views.Book.as_view(),
|
||||||
|
@ -552,7 +568,10 @@ urlpatterns = [
|
||||||
re_path(r"^isbn/(?P<isbn>\d+)(.json)?/?$", views.Isbn.as_view()),
|
re_path(r"^isbn/(?P<isbn>\d+)(.json)?/?$", views.Isbn.as_view()),
|
||||||
# author
|
# author
|
||||||
re_path(
|
re_path(
|
||||||
r"^author/(?P<author_id>\d+)(.json)?/?$", views.Author.as_view(), name="author"
|
rf"^author/(?P<author_id>\d+)(.json)?/?$", views.Author.as_view(), name="author"
|
||||||
|
),
|
||||||
|
re_path(
|
||||||
|
rf"^author/(?P<author_id>\d+){regex.SLUG}/?$", views.Author.as_view(), name="author"
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^author/(?P<author_id>\d+)/edit/?$",
|
r"^author/(?P<author_id>\d+)/edit/?$",
|
||||||
|
|
|
@ -6,5 +6,6 @@ STRICT_LOCALNAME = r"@[a-zA-Z_\-\.0-9]+"
|
||||||
USERNAME = rf"{LOCALNAME}(@{DOMAIN})?"
|
USERNAME = rf"{LOCALNAME}(@{DOMAIN})?"
|
||||||
STRICT_USERNAME = rf"\B{STRICT_LOCALNAME}(@{DOMAIN})?\b"
|
STRICT_USERNAME = rf"\B{STRICT_LOCALNAME}(@{DOMAIN})?\b"
|
||||||
FULL_USERNAME = rf"{LOCALNAME}@{DOMAIN}\b"
|
FULL_USERNAME = rf"{LOCALNAME}@{DOMAIN}\b"
|
||||||
|
SLUG = r"/s/(?P<slug>[-_a-z0-9]+)"
|
||||||
# should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2;
|
# should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2;
|
||||||
BOOKWYRM_USER_AGENT = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"
|
BOOKWYRM_USER_AGENT = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"
|
||||||
|
|
|
@ -19,7 +19,7 @@ from bookwyrm.views.helpers import is_api_request
|
||||||
class Author(View):
|
class Author(View):
|
||||||
"""this person wrote a book"""
|
"""this person wrote a book"""
|
||||||
|
|
||||||
def get(self, request, author_id):
|
def get(self, request, author_id, slug=None):
|
||||||
"""landing page for an author"""
|
"""landing page for an author"""
|
||||||
author = get_object_or_404(models.Author, id=author_id)
|
author = get_object_or_404(models.Author, id=author_id)
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ from bookwyrm.views.helpers import is_api_request
|
||||||
class Book(View):
|
class Book(View):
|
||||||
"""a book! this is the stuff"""
|
"""a book! this is the stuff"""
|
||||||
|
|
||||||
def get(self, request, book_id, user_statuses=False):
|
def get(self, request, book_id, **kwargs):
|
||||||
"""info about a book"""
|
"""info about a book"""
|
||||||
if is_api_request(request):
|
if is_api_request(request):
|
||||||
book = get_object_or_404(
|
book = get_object_or_404(
|
||||||
|
@ -30,7 +30,7 @@ class Book(View):
|
||||||
)
|
)
|
||||||
return ActivitypubResponse(book.to_activity())
|
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
|
# it's safe to use this OR because edition and work and subclasses of the same
|
||||||
# table, so they never have clashing IDs
|
# table, so they never have clashing IDs
|
||||||
|
|
|
@ -113,7 +113,7 @@ class DirectMessage(View):
|
||||||
class Status(View):
|
class Status(View):
|
||||||
"""get posting"""
|
"""get posting"""
|
||||||
|
|
||||||
def get(self, request, username, status_id):
|
def get(self, request, username, status_id, slug=None):
|
||||||
"""display a particular status (and replies, etc)"""
|
"""display a particular status (and replies, etc)"""
|
||||||
user = get_user_from_username(request.user, username)
|
user = get_user_from_username(request.user, username)
|
||||||
status = get_object_or_404(
|
status = get_object_or_404(
|
||||||
|
|
|
@ -20,7 +20,7 @@ from .helpers import get_user_from_username
|
||||||
class Group(View):
|
class Group(View):
|
||||||
"""group page"""
|
"""group page"""
|
||||||
|
|
||||||
def get(self, request, group_id):
|
def get(self, request, group_id, slug=None):
|
||||||
"""display a group"""
|
"""display a group"""
|
||||||
|
|
||||||
group = get_object_or_404(models.Group, id=group_id)
|
group = get_object_or_404(models.Group, id=group_id)
|
||||||
|
@ -80,7 +80,7 @@ class Group(View):
|
||||||
class UserGroups(View):
|
class UserGroups(View):
|
||||||
"""a user's groups page"""
|
"""a user's groups page"""
|
||||||
|
|
||||||
def get(self, request, username):
|
def get(self, request, username, slug=None):
|
||||||
"""display a group"""
|
"""display a group"""
|
||||||
user = get_user_from_username(request.user, username)
|
user = get_user_from_username(request.user, username)
|
||||||
groups = (
|
groups = (
|
||||||
|
|
|
@ -25,8 +25,11 @@ from bookwyrm.views.helpers import is_api_request
|
||||||
class List(View):
|
class List(View):
|
||||||
"""book list page"""
|
"""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"""
|
"""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 = get_object_or_404(models.List, id=list_id)
|
||||||
book_list.raise_visible_to_user(request.user)
|
book_list.raise_visible_to_user(request.user)
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,9 @@ from bookwyrm.views.helpers import is_api_request, get_user_from_username
|
||||||
class Shelf(View):
|
class Shelf(View):
|
||||||
"""shelf page"""
|
"""shelf page"""
|
||||||
|
|
||||||
def get(self, request, username, shelf_identifier=None):
|
def get(self, request, username, **kwargs):
|
||||||
"""display a shelf"""
|
"""display a shelf"""
|
||||||
|
shelf_identifier = kwargs.get("shelf_identifier")
|
||||||
user = get_user_from_username(request.user, username)
|
user = get_user_from_username(request.user, username)
|
||||||
|
|
||||||
is_self = user == request.user
|
is_self = user == request.user
|
||||||
|
|
Loading…
Reference in a new issue