Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSS for shelves #3013

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
856737e
working rss feed for shelves
Sep 29, 2023
4ae0dbd
add a failing test for rss feeds for shelves
Sep 29, 2023
c142e38
fix linting issue
Oct 1, 2023
f665aea
fixed method without docstring
Oct 1, 2023
339298c
Mock activitystreams add_book_statuses_task
Nov 5, 2023
d3d5f1b
remove duplicate sitesettings error
Nov 5, 2023
7a25869
Merge branch 'main' into rss-for-shelves
jaschaurbach Jan 20, 2024
7b388ae
Sort RSS Feed by Shelved date
mattkatz Mar 13, 2024
3754af7
/rss shouldn't be optional in the rss route
mattkatz Mar 13, 2024
a2e41fa
/rss shouldn't be optional in the rss route
mattkatz Mar 13, 2024
975c3ba
Correct docstring on rss feed
mattkatz Mar 13, 2024
e3ca543
Remove extraneous function
Mar 13, 2024
5b8e083
use privacy__in to respect shelf privacy settings
Mar 13, 2024
63d6486
Merge branch 'main' into rss-for-shelves
mattkatz Mar 19, 2024
6976cb4
add user name to shelf rss feed title
mattkatz Mar 19, 2024
cd29b44
improve shelf rss description
mattkatz Mar 19, 2024
1d8bd2b
add translation usage
Mar 19, 2024
09d857e
support same identifiers as book page in rss
Mar 19, 2024
1e14d63
Missing brackets and correct blocktrans usage
dato Mar 19, 2024
5340ed3
Drop `default` filter in favor of per-metadata item conditionals
dato Mar 19, 2024
8dc412c
remove pure_name since it only applies to statuses
Apr 14, 2024
a0d15cc
Don't show a colon if there is no author_text
Apr 14, 2024
74e2103
handle cases where edition has no author
Apr 14, 2024
98724df
use display_name to avoid name rendering as None
Apr 14, 2024
7c6f001
fix edition formatting and add alt link
hughrun Apr 26, 2024
9942444
Merge branch 'main' into rss-for-shelves
hughrun Aug 30, 2024
0c0acab
Merge fix into pr 3013
hughrun Aug 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bookwyrm/templates/rss/edition.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{obj.title}} by {{obj.author_text}}
dato marked this conversation as resolved.
Show resolved Hide resolved
{{obj.description|default:""}}
hughrun marked this conversation as resolved.
Show resolved Hide resolved
{% if obj.description %}ISBN: {{item.isbn_10|default:""}}{% endif %}
{% if obj.description %}ISBN13: {{item.isbn_13}}{% endif %}
23 changes: 23 additions & 0 deletions bookwyrm/tests/views/test_rss_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,26 @@ def test_rss_quotation_only(self, *_):
self.assertEqual(result.status_code, 200)

self.assertIn(b"a sickening sense", result.content)

def test_rss_shelf(self, *_):
"""load the rss feed of a shelf"""
with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"):
hughrun marked this conversation as resolved.
Show resolved Hide resolved
# make the shelf
shelf = models.Shelf.objects.create(
name="Test Shelf", identifier="test-shelf", user=self.local_user
)
# put the shelf on the book
models.ShelfBook.objects.create(
book=self.book,
shelf=shelf,
user=self.local_user,
)
models.SiteSettings.objects.create()
view = rss_feed.RssShelfFeed()
request = self.factory.get("/user/books/test-shelf/rss")
request.user = self.local_user
result = view(
request, username=self.local_user.username, shelf_identifier="test-shelf"
)
self.assertEqual(result.status_code, 200)
self.assertIn(b"Example Edition", result.content)
10 changes: 10 additions & 0 deletions bookwyrm/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,11 +540,21 @@
views.Shelf.as_view(),
name="shelf",
),
re_path(
rf"^{USER_PATH}/(shelf|books)/(?P<shelf_identifier>[\w-]+)(/rss)?/?$",
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
views.rss_feed.RssShelfFeed(),
name="shelf-rss",
),
re_path(
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$",
views.Shelf.as_view(),
name="shelf",
),
re_path(
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+)(/rss)?/?$",
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
views.rss_feed.RssShelfFeed(),
name="shelf-rss",
),
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"^shelve/?$", views.shelve),
Expand Down
64 changes: 64 additions & 0 deletions bookwyrm/views/rss_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.contrib.syndication.views import Feed
from django.template.loader import get_template
from django.utils.translation import gettext_lazy as _
from django.shortcuts import get_object_or_404
from ..models import Review, Quotation, Comment

from .helpers import get_user_from_username
Expand Down Expand Up @@ -177,3 +178,66 @@ def item_link(self, item):
def item_pubdate(self, item):
"""publication date of the item"""
return item.published_date


class RssShelfFeed(Feed):
"""serialize a shelf activity in rss"""

description_template = "rss/edition.html"

def item_title(self, item):
"""render the item title"""
if hasattr(item, "pure_name") and item.pure_name:
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
return item.pure_name
authors = item.authors
authors.display_name = f"{item.author_text}:"
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
template = get_template("rss/title.html")
return template.render({"user": authors, "item_title": item.title}).strip()

def get_object(
self, request, shelf_identifier, username
): # pylint: disable=arguments-differ
"""the user who's posts get serialized"""
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
user = get_user_from_username(request.user, username)
# always get privacy, don't support rss over anything private
# Shelf.privacy_filter(request.user).filter(user=user).all()

# TODO: get the SHELF of the object
shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
shelf.raise_visible_to_user(request.user)
return shelf

def link(self, obj):
"""link to the shelf"""
return obj.local_path

def title(self, obj):
"""title of the rss feed entry"""
return _(f"Books added to {obj.name}")
mattkatz marked this conversation as resolved.
Show resolved Hide resolved

def items(self, obj):
"""the user's activity feed"""
return obj.books.order_by("-published_date")[:10]
mattkatz marked this conversation as resolved.
Show resolved Hide resolved

def item_link(self, item):
"""link to the status"""
return item.local_path

def item_pubdate(self, item):
"""publication date of the item"""
return item.published_date

def description(self, obj):
"""description of the shelf including the shelf name and user."""
# if there's a description, lets add it. Not everyone puts a description in.
desc = ""
if obj.description:
desc = f" {obj.description}"
return f"Books added to the '{obj.name}' shelf for {obj.user.name}.{desc}"
mattkatz marked this conversation as resolved.
Show resolved Hide resolved

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# TODO: gotta check that this is the SHELF user!
context["user"] = kwargs["request"].user
context["shelf"] = kwargs["obj"]
return context
mattkatz marked this conversation as resolved.
Show resolved Hide resolved
Loading