diff --git a/bookwyrm/templates/snippets/rss_content.html b/bookwyrm/templates/snippets/rss_content.html new file mode 100644 index 00000000..a72752d0 --- /dev/null +++ b/bookwyrm/templates/snippets/rss_content.html @@ -0,0 +1 @@ +{{ obj.pure_content | safe }} diff --git a/bookwyrm/templates/snippets/rss_title.html b/bookwyrm/templates/snippets/rss_title.html new file mode 100644 index 00000000..dadb5961 --- /dev/null +++ b/bookwyrm/templates/snippets/rss_title.html @@ -0,0 +1,15 @@ +{{ obj.user.display_name }}{% if obj.status_type == 'GeneratedNote' %} + {{ obj.content | safe }} +{% elif obj.status_type == 'Review' and not obj.name and not obj.content%} + rated +{% elif obj.status_type == 'Review' %} + reviewed +{% elif obj.status_type == 'Comment' %} + commented on +{% elif obj.status_type == 'Quotation' %} + quoted +{% endif %} +{% if obj.book %}{{ obj.book.title | safe}} +{% elif obj.mention_books %} +{{ obj.mention_books.first.title }} +{% endif %} \ No newline at end of file diff --git a/bookwyrm/tests/views/test_rss_feed.py b/bookwyrm/tests/views/test_rss_feed.py new file mode 100644 index 00000000..cbc97af7 --- /dev/null +++ b/bookwyrm/tests/views/test_rss_feed.py @@ -0,0 +1,52 @@ +''' testing import ''' + +from unittest.mock import patch +from django.test import RequestFactory, TestCase +import responses + +from bookwyrm import models +from bookwyrm.views import rss_feed +from bookwyrm.settings import DOMAIN + +class RssFeedView(TestCase): + ''' rss feed behaves as expected ''' + def setUp(self): + + self.site = models.SiteSettings.objects.create() + + self.user = models.User.objects.create_user( + 'rss_user', 'rss@test.rss', 'password', local=True) + + work = models.Work.objects.create(title='Test Work') + self.book = models.Edition.objects.create( + title='Example Edition', + remote_id='https://example.com/book/1', + parent_work=work + ) + + self.review = models.Review.objects.create( + name='Review name', content='test content', rating=3, + user=self.user, book=self.book) + + self.quote = models.Quotation.objects.create( + quote='a sickening sense', content='test content', + user=self.user, book=self.book) + + self.generatednote = models.GeneratedNote.objects.create( + content='test content', user=self.user) + + self.factory = RequestFactory() + + + def test_rss_feed(self): + view = rss_feed.RssFeed() + request = self.factory.get('/user/rss_user/rss') + with patch("bookwyrm.models.SiteSettings.objects.get") as site: + site.return_value = self.site + result = view(request, username=self.user.username) + self.assertEqual(result.status_code, 200) + + self.assertIn(b"Status updates from rss_user", result.content) + self.assertIn( b"a sickening sense", result.content) + self.assertIn(b"Example Edition", result.content) + diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 4f9a43ea..f03bcda9 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -3,7 +3,9 @@ from django.conf.urls.static import static from django.contrib import admin from django.urls import path, re_path + from bookwyrm import incoming, settings, views, wellknown +from bookwyrm.views.rss_feed import RssFeed from bookwyrm.utils import regex user_path = r'^user/(?P%s)' % regex.username @@ -75,6 +77,7 @@ urlpatterns = [ re_path(r'%s/followers(.json)?/?$' % user_path, views.Followers.as_view()), re_path(r'%s/following(.json)?/?$' % user_path, views.Following.as_view()), re_path(r'^edit-profile/?$', views.EditUser.as_view()), + re_path(r'%s/rss' % user_path, views.rss_feed.RssFeed()), # reading goals re_path(r'%s/goal/(?P\d{4})/?$' % user_path, views.Goal.as_view()), diff --git a/bookwyrm/views/rss_feed.py b/bookwyrm/views/rss_feed.py new file mode 100644 index 00000000..d6bcd174 --- /dev/null +++ b/bookwyrm/views/rss_feed.py @@ -0,0 +1,29 @@ +''' ''' + +from django.contrib.syndication.views import Feed +from django.urls import reverse +from bookwyrm.models.user import User +from .helpers import get_activity_feed, get_user_from_username + +class RssFeed(Feed): + + description_template = "snippets/rss_content.html" + title_template = "snippets/rss_title.html" + + def get_object(self, request, username): + return get_user_from_username(username) + + def link(self, obj): + return obj.local_path + + def title(self, obj): + return f"Status updates from {obj.display_name}" + + + def items(self, obj): + return get_activity_feed(obj, ['public', 'unlisted'], queryset=obj.status_set) + + + def item_link(self, item): + return item.local_path +