From e5ae66567ab19832bd08665076ef50e70efd9dd5 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Fri, 22 Dec 2023 17:35:18 +0000 Subject: [PATCH] Unify RSS feeds One per section is a little much. Just use a single feed and be done with. Might help discoverability a little. --- website/blog/tests.py | 13 ++++------ website/common/models.py | 19 +++----------- .../common/templates/common/listing_page.html | 9 +------ website/common/tests/test_pages.py | 14 +++++----- website/common/views.py | 16 +----------- website/legacy/tests.py | 26 +++++++------------ website/legacy/urls.py | 2 +- website/legacy/views.py | 11 +------- 8 files changed, 27 insertions(+), 83 deletions(-) diff --git a/website/blog/tests.py b/website/blog/tests.py index 6a231d2..1c9929a 100644 --- a/website/blog/tests.py +++ b/website/blog/tests.py @@ -1,4 +1,5 @@ from django.test import TestCase +from django.urls import reverse from website.home.models import HomePage @@ -73,17 +74,13 @@ class BlogPostListPageTestCase(TestCase): response = self.client.get(self.page.url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.context["listing_pages"]), 2) - self.assertContains(response, self.page.reverse_subpage("feed")) def test_queries(self) -> None: with self.assertNumQueries(44): self.client.get(self.page.url) def test_feed_accessible(self) -> None: - with self.assertNumQueries(14): - response = self.client.get( - self.page.url + self.page.reverse_subpage("feed") - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response["Content-Type"], "application/xml") - self.assertContains(response, "xml-stylesheet") + response = self.client.get(self.page.url + self.page.reverse_subpage("feed")) + self.assertRedirects( + response, reverse("feed"), status_code=301, fetch_redirect_response=True + ) diff --git a/website/common/models.py b/website/common/models.py index 5b0642e..6f44e24 100644 --- a/website/common/models.py +++ b/website/common/models.py @@ -1,19 +1,17 @@ from datetime import timedelta -from typing import Any, Optional, Type +from typing import Any, Optional from urllib.parse import urlencode from django.contrib.humanize.templatetags.humanize import NaturalTimeFormatter -from django.contrib.syndication.views import Feed from django.core.paginator import EmptyPage, Paginator from django.core.paginator import Page as PaginatorPage from django.db import models from django.http.request import HttpRequest from django.http.response import Http404, HttpResponse, HttpResponseBadRequest +from django.shortcuts import redirect from django.utils import timezone -from django.utils.decorators import method_decorator from django.utils.functional import cached_property, classproperty from django.utils.text import slugify -from django.views.decorators.cache import cache_page from wagtail.admin.panels import FieldPanel, MultiFieldPanel from wagtail.contrib.routable_page.models import RoutablePageMixin, route from wagtail.contrib.settings.models import BaseGenericSetting, register_setting @@ -257,12 +255,6 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage): def show_reading_time(self) -> bool: return False - @property - def feed_class(self) -> Type[Feed]: - from .views import ContentPageFeed - - return ContentPageFeed - @route(r"^$") def index_route(self, request: HttpRequest) -> HttpResponse: self.serializer = PaginationSerializer(data=request.GET) @@ -283,13 +275,8 @@ class BaseListingPage(RoutablePageMixin, BaseContentPage): return url + "?" + urlencode(query_data) @route(r"^feed/$") - @method_decorator(cache_page(60 * 30)) def feed(self, request: HttpRequest) -> HttpResponse: - return self.feed_class( - self.get_listing_pages(), - self.get_full_url(request), - self.html_title_tag, - )(request) + return redirect("feed", permanent=True) class ListingPage(BaseListingPage): diff --git a/website/common/templates/common/listing_page.html b/website/common/templates/common/listing_page.html index 45bc1b9..3bda7cf 100644 --- a/website/common/templates/common/listing_page.html +++ b/website/common/templates/common/listing_page.html @@ -1,15 +1,8 @@ {% extends "common/content_page.html" %} -{% load wagtailroutablepage_tags wagtailadmin_tags %} - -{% block extra_head %} - {{ block.super }} - -{% endblock %} +{% load wagtailadmin_tags %} {% block hero_buttons %} - - {% if listing_pages.has_previous %} {% endif %} diff --git a/website/common/tests/test_pages.py b/website/common/tests/test_pages.py index 8dfffb4..50c2c1a 100644 --- a/website/common/tests/test_pages.py +++ b/website/common/tests/test_pages.py @@ -1,5 +1,6 @@ from django.template.loader import get_template from django.test import SimpleTestCase, TestCase +from django.urls import reverse from website.common.factories import ContentPageFactory, ListingPageFactory from website.common.models import BaseListingPage, BasePage @@ -58,14 +59,11 @@ class ListingPageTestCase(TestCase): self.assertEqual(len(response.context["listing_pages"]), 2) self.assertContains(response, self.page.reverse_subpage("feed")) - def test_feed_accessible(self) -> None: - with self.assertNumQueries(13): - response = self.client.get( - self.page.url + self.page.reverse_subpage("feed") - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response["Content-Type"], "application/xml") - self.assertContains(response, "xml-stylesheet") + def test_feed_redirects(self) -> None: + response = self.client.get(self.page.url + self.page.reverse_subpage("feed")) + self.assertRedirects( + response, reverse("feed"), status_code=301, fetch_redirect_response=True + ) def test_meta_url(self) -> None: response = self.client.get(self.page.url) diff --git a/website/common/views.py b/website/common/views.py index e738507..891865d 100644 --- a/website/common/views.py +++ b/website/common/views.py @@ -93,7 +93,7 @@ class AllPagesFeed(Feed): return {**super().feed_extra_kwargs(obj), "request": self.request} def title(self) -> str: - return f"All Pages Feed :: {get_site_title()}" + return f"Feed :: {get_site_title()}" def items(self) -> PageQuerySet: return ( @@ -149,20 +149,6 @@ class AllPagesFeed(Feed): item_enclosure_length = 0 -class ContentPageFeed(AllPagesFeed): - def __init__(self, posts: PageQuerySet, link: str, title: str): - self.posts = posts - self.link = link - self._title = title - super().__init__() - - def title(self) -> str: - return self._title - - def items(self) -> PageQuerySet: - return self.posts - - @method_decorator(cache_control(max_age=60 * 60), name="dispatch") class FaviconView(RedirectView): def get_redirect_url(self) -> str: diff --git a/website/legacy/tests.py b/website/legacy/tests.py index 4d1ba7e..d7ea112 100644 --- a/website/legacy/tests.py +++ b/website/legacy/tests.py @@ -1,24 +1,16 @@ from django.test import TestCase from django.urls import reverse -from website.blog.factories import BlogPostListPageFactory -from website.home.models import HomePage - - -class PostsFeedViewTestCase(TestCase): - @classmethod - def setUpTestData(cls) -> None: - cls.home_page = HomePage.objects.get() - cls.page = BlogPostListPageFactory(parent=cls.home_page) - - def test_redirects(self) -> None: - response = self.client.get("/posts/index.xml") - self.assertRedirects( - response, self.page.url + self.page.reverse_subpage("feed"), status_code=301 - ) - class AllPagesFeedViewTestCase(TestCase): def test_redirects(self) -> None: response = self.client.get("/index.xml") - self.assertRedirects(response, reverse("feed"), status_code=301) + self.assertRedirects( + response, reverse("feed"), status_code=301, fetch_redirect_response=True + ) + + def test_redirects_posts(self) -> None: + response = self.client.get("/posts/index.xml") + self.assertRedirects( + response, reverse("feed"), status_code=301, fetch_redirect_response=True + ) diff --git a/website/legacy/urls.py b/website/legacy/urls.py index 7be8aca..6b3eedd 100644 --- a/website/legacy/urls.py +++ b/website/legacy/urls.py @@ -5,7 +5,7 @@ from . import views app_name = "legacy" urlpatterns = [ - path("posts/index.xml", views.PostsFeedView.as_view()), + path("posts/index.xml", views.AllPagesFeedView.as_view()), path("index.xml", views.AllPagesFeedView.as_view()), path("tags//", views.TagView.as_view()), path("tags/", views.TagsView.as_view()), diff --git a/website/legacy/views.py b/website/legacy/views.py index 6b5aeb0..333c7ab 100644 --- a/website/legacy/views.py +++ b/website/legacy/views.py @@ -3,16 +3,7 @@ from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_control from django.views.generic import RedirectView -from website.blog.models import BlogPostListPage, BlogPostTagListPage, BlogPostTagPage - - -@method_decorator(cache_control(max_age=60 * 60), name="dispatch") -class PostsFeedView(RedirectView): - permanent = True - - def get_redirect_url(self) -> str: - post_list = get_object_or_404(BlogPostListPage) - return post_list.url + post_list.reverse_subpage("feed") +from website.blog.models import BlogPostTagListPage, BlogPostTagPage @method_decorator(cache_control(max_age=60 * 60), name="dispatch")