From 0552f4e6dca3da8fc168d0749b8b36523208371a Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 7 Feb 2024 15:04:47 +0000 Subject: [PATCH 1/6] add rss feeds --- server/apps/main/feeds.py | 59 +++++++++++++++++++ .../apps/main/templates/main/application.html | 6 ++ .../main/templates/main/experiences_page.html | 5 +- server/apps/main/templates/main/feed.html | 10 ++++ server/apps/main/urls.py | 3 + server/apps/main/views.py | 5 +- 6 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 server/apps/main/feeds.py create mode 100644 server/apps/main/templates/main/feed.html diff --git a/server/apps/main/feeds.py b/server/apps/main/feeds.py new file mode 100644 index 00000000..731a617f --- /dev/null +++ b/server/apps/main/feeds.py @@ -0,0 +1,59 @@ +from .models import PublicExperience +from django.contrib.syndication.views import Feed +from django.urls import reverse +from server.apps.main.helpers import extract_triggers_to_show, expand_filter +from django.utils.feedgenerator import Atom1Feed + +class PublicExperienceFeed(Feed): + description_template = "main/feed.html" + + def get_object(self, request): + # check if 'all triggers' is in keys + all_triggers = request.GET.get("all_triggers", False) + # set all trigger labels if set + if all_triggers: + allowed_triggers = { + "abuse", + "violence", + "drug", + "mentalhealth", + "negbody", + "other", + } + else: + # Check the allowed triggers + allowed_triggers = set(request.GET.keys()) + triggers_to_show = extract_triggers_to_show(allowed_triggers) + return triggers_to_show + + def title(self, obj): + return "AutSPACEs public experiences" + + def link(self, obj): + return "https://example.com" + + def description(self, obj): + joined_triggers = ", ".join(obj) + if joined_triggers: + return "This feed includes potentially triggering stories related to %s" % joined_triggers + else: + return "No triggering content is included in this feed" + + def item_link(self, item): + return reverse('main:single_story', args=[item.experience_id]) + + def item_title(self, item): + return item.title_text + + def item_pubdate(self, item): + return item.created_at + + def items(self, obj): + experiences = PublicExperience.objects.filter(moderation_status="approved") + experiences = expand_filter(experiences, obj) + experiences = experiences.order_by("-created_at")[:5] + return experiences + +class PublicExperienceAtomFeed(PublicExperienceFeed): + feed_type = Atom1Feed + subtitle = PublicExperienceFeed.description \ No newline at end of file diff --git a/server/apps/main/templates/main/application.html b/server/apps/main/templates/main/application.html index 7e33371c..0646f09f 100644 --- a/server/apps/main/templates/main/application.html +++ b/server/apps/main/templates/main/application.html @@ -26,6 +26,12 @@ {%block page_css%} {% endblock %} + + {% if rss_link %} + + + {% endif %} + diff --git a/server/apps/main/templates/main/experiences_page.html b/server/apps/main/templates/main/experiences_page.html index f829e5c8..05fbcd91 100644 --- a/server/apps/main/templates/main/experiences_page.html +++ b/server/apps/main/templates/main/experiences_page.html @@ -135,8 +135,9 @@

View Stories

- +
+ You can also subscribe to this page as a feed. The current trigger options will be preserved.
{% if searched %}
@@ -144,8 +145,6 @@

View Stories

{% endif %} - -
{% for experience in experiences %} diff --git a/server/apps/main/templates/main/feed.html b/server/apps/main/templates/main/feed.html new file mode 100644 index 00000000..ba02b00e --- /dev/null +++ b/server/apps/main/templates/main/feed.html @@ -0,0 +1,10 @@ + +

Experience

+

+{{ obj.experience_text }} +

+ +

Difference

+

+ {{ obj.difference_text }} +

\ No newline at end of file diff --git a/server/apps/main/urls.py b/server/apps/main/urls.py index 43e67b60..af9eb1c5 100644 --- a/server/apps/main/urls.py +++ b/server/apps/main/urls.py @@ -1,5 +1,6 @@ from django.urls import path, re_path from server.apps.main import views +from server.apps.main import feeds app_name = "main" @@ -33,4 +34,6 @@ path("registration/", views.registration, name="registration"), path("single_story//",views.single_story,name="single_story"), path("success_confirm/", views.success_confirm, name="success_confirm"), + path("public_experiences/rss/", feeds.PublicExperienceFeed(), name='rss_feed'), + path("public_experiences/atom/", feeds.PublicExperienceAtomFeed(), name='atom_feed'), ] diff --git a/server/apps/main/views.py b/server/apps/main/views.py index 983b34a1..c7488620 100644 --- a/server/apps/main/views.py +++ b/server/apps/main/views.py @@ -410,7 +410,10 @@ def list_public_experiences(request): exp_context = {"experiences": page_experiences} - context = {**tts, **exp_context, **search_context} + rss_link = reverse("main:rss_feed") + "?" + request.GET.urlencode() + atom_link = rss_link = reverse("main:atom_feed") + "?" + request.GET.urlencode() + + context = {'rss_link': rss_link, 'atom_link': atom_link, **tts, **exp_context, **search_context} # Standard page showing all moderated stories return render(request, "main/experiences_page.html", context=context) From 66177267c6d7564a42cc710963041680d5b5db70 Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 7 Feb 2024 15:35:37 +0000 Subject: [PATCH 2/6] replace url scheme --- server/apps/main/feeds.py | 4 ++-- server/apps/main/urls.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/apps/main/feeds.py b/server/apps/main/feeds.py index 731a617f..1e499cb8 100644 --- a/server/apps/main/feeds.py +++ b/server/apps/main/feeds.py @@ -30,7 +30,7 @@ def title(self, obj): return "AutSPACEs public experiences" def link(self, obj): - return "https://example.com" + return reverse("main:public_experiences") def description(self, obj): joined_triggers = ", ".join(obj) @@ -51,7 +51,7 @@ def item_pubdate(self, item): def items(self, obj): experiences = PublicExperience.objects.filter(moderation_status="approved") experiences = expand_filter(experiences, obj) - experiences = experiences.order_by("-created_at")[:5] + experiences = experiences.order_by("-created_at")[:10] return experiences class PublicExperienceAtomFeed(PublicExperienceFeed): diff --git a/server/apps/main/urls.py b/server/apps/main/urls.py index af9eb1c5..c38bec79 100644 --- a/server/apps/main/urls.py +++ b/server/apps/main/urls.py @@ -34,6 +34,6 @@ path("registration/", views.registration, name="registration"), path("single_story//",views.single_story,name="single_story"), path("success_confirm/", views.success_confirm, name="success_confirm"), - path("public_experiences/rss/", feeds.PublicExperienceFeed(), name='rss_feed'), - path("public_experiences/atom/", feeds.PublicExperienceAtomFeed(), name='atom_feed'), + path("public_experiences/rss.xml", feeds.PublicExperienceFeed(), name='rss_feed'), + path("public_experiences/atom.xml", feeds.PublicExperienceAtomFeed(), name='atom_feed'), ] From 635f49ef488a44aaff246e5d2d9cc8932a5121df Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 7 Feb 2024 15:53:43 +0000 Subject: [PATCH 3/6] update text --- server/apps/main/templates/main/feed.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/apps/main/templates/main/feed.html b/server/apps/main/templates/main/feed.html index ba02b00e..99aade63 100644 --- a/server/apps/main/templates/main/feed.html +++ b/server/apps/main/templates/main/feed.html @@ -1,10 +1,10 @@ -

Experience

+

The experience

{{ obj.experience_text }}

-

Difference

+

What would make a difference

{{ obj.difference_text }}

\ No newline at end of file From 1def2229ed21afe7cfce463b8c0cf597413d8ff2 Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 7 Feb 2024 17:00:10 +0000 Subject: [PATCH 4/6] start adding feed tests --- server/apps/main/tests/test_views.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/server/apps/main/tests/test_views.py b/server/apps/main/tests/test_views.py index d9892c6f..c4b2edb8 100644 --- a/server/apps/main/tests/test_views.py +++ b/server/apps/main/tests/test_views.py @@ -804,3 +804,21 @@ def test_my_stories_pagination_page2(self): assert len(stories) == min(num_items_per_page, n_stories) # check story numbering assert stories[0]['number'] == num_items_per_page + 1 # first story on page 1 is continuation of page 1 + + + + def test_feeds(self): + c = Client() + c.force_login(self.user_a) + response = c.get("/main/public_experiences/rss.xml") + assert response.status_code == 200 + self.assertTemplateUsed(response, "main/feed.html") + # Check that there is only one story visible - the one with no triggering labels + self.assertContains(response,"No triggering content is included in this feed") + self.assertContains(response,"", count=1) + + # If you allow the abuse tag there should be 2 stories one with no tags one with the abuse tag + search_response_abuse = c.get("/main/public_experiences/rss.xml?abuse=True") + print(search_response_abuse.content) + self.assertNotContains(search_response_abuse,"No triggering content is included in this feed") + self.assertContains(search_response_abuse,"", count=2) \ No newline at end of file From 3cd1361ca8f76a8cf88ee3d1f6a5640dc7e2fd0b Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Wed, 7 Feb 2024 17:11:15 +0000 Subject: [PATCH 5/6] mssing test cover --- server/apps/main/tests/test_views.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/server/apps/main/tests/test_views.py b/server/apps/main/tests/test_views.py index c4b2edb8..49ac0ffc 100644 --- a/server/apps/main/tests/test_views.py +++ b/server/apps/main/tests/test_views.py @@ -819,6 +819,11 @@ def test_feeds(self): # If you allow the abuse tag there should be 2 stories one with no tags one with the abuse tag search_response_abuse = c.get("/main/public_experiences/rss.xml?abuse=True") - print(search_response_abuse.content) self.assertNotContains(search_response_abuse,"No triggering content is included in this feed") - self.assertContains(search_response_abuse,"", count=2) \ No newline at end of file + self.assertContains(search_response_abuse,"", count=2) + + + search_response_t = c.get("/main/public_experiences/rss.xml?all_triggers=True") + self.assertContains(search_response_t,"", count=2) + + From 658d7001265dfc86abb62eef2f407aadbbadc85d Mon Sep 17 00:00:00 2001 From: Bastian Greshake Tzovaras Date: Mon, 12 Feb 2024 09:04:24 +0000 Subject: [PATCH 6/6] move rss to bottom --- server/apps/main/templates/main/experiences_page.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/apps/main/templates/main/experiences_page.html b/server/apps/main/templates/main/experiences_page.html index 05fbcd91..5c0104ab 100644 --- a/server/apps/main/templates/main/experiences_page.html +++ b/server/apps/main/templates/main/experiences_page.html @@ -136,8 +136,6 @@

View Stories

-
- You can also subscribe to this page as a feed. The current trigger options will be preserved.
{% if searched %}
@@ -228,6 +226,8 @@

Recommendation

{% include 'main/pagination.html' with stories=experiences page_query_param='page' %} {% endif %} +
+ You can also subscribe to this page as a feed. The current trigger options will be preserved.