Add RSS feed views

This commit is contained in:
Joakim Hellsén 2025-09-04 23:06:28 +02:00
commit 63f95a73db
5 changed files with 142 additions and 0 deletions

78
twitch/feeds.py Normal file
View file

@ -0,0 +1,78 @@
from __future__ import annotations
from django.contrib.syndication.views import Feed
from django.urls import reverse
from twitch.models import DropCampaign, Game, Organization
class OrganizationFeed(Feed):
"""RSS feed for latest organizations."""
title = "TTVDrops Organizations"
link = "/organizations/"
description = "Latest organizations on TTVDrops"
def items(self) -> list[Organization]:
"""Return the latest 100 organizations."""
return list(Organization.objects.order_by("-id")[:100])
def item_title(self, item: Organization) -> str:
"""Return the organization name as the item title."""
return item.name
def item_description(self, item: Organization) -> str:
"""Return a description of the organization."""
return f"Organization {item.name}"
def item_link(self, item: Organization) -> str:
"""Return the link to the organization detail."""
return reverse("twitch:organization_detail", args=[item.pk])
class GameFeed(Feed):
"""RSS feed for latest games."""
title = "TTVDrops Games"
link = "/games/"
description = "Latest games on TTVDrops"
def items(self) -> list[Game]:
"""Return the latest 100 games."""
return list(Game.objects.order_by("-id")[:100])
def item_title(self, item: Game) -> str:
"""Return the game name as the item title."""
return str(item)
def item_description(self, item: Game) -> str:
"""Return a description of the game."""
return f"Game {item.display_name}"
def item_link(self, item: Game) -> str:
"""Return the link to the game detail."""
return reverse("twitch:game_detail", args=[item.pk])
class DropCampaignFeed(Feed):
"""RSS feed for latest drop campaigns."""
title = "TTVDrops Drop Campaigns"
link = "/campaigns/"
description = "Latest drop campaigns on TTVDrops"
def items(self) -> list[DropCampaign]:
"""Return the latest 100 drop campaigns."""
return list(DropCampaign.objects.order_by("-added_at")[:100])
def item_title(self, item: DropCampaign) -> str:
"""Return the campaign name as the item title."""
return item.name
def item_description(self, item: DropCampaign) -> str:
"""Return a description of the campaign."""
return item.description or f"Campaign {item.name}"
def item_link(self, item: DropCampaign) -> str:
"""Return the link to the campaign detail."""
return reverse("twitch:campaign_detail", args=[item.pk])

View file

@ -3,6 +3,11 @@ from __future__ import annotations
from django.urls import path
from twitch import views
from twitch.feeds import (
DropCampaignFeed,
GameFeed,
OrganizationFeed,
)
app_name = "twitch"
@ -18,4 +23,8 @@ urlpatterns = [
path("organizations/", views.OrgListView.as_view(), name="org_list"),
path("organizations/<str:pk>/", views.OrgDetailView.as_view(), name="organization_detail"),
path("organizations/<str:org_id>/subscribe/", views.subscribe_org_notifications, name="subscribe_org_notifications"),
path("rss/organizations/", OrganizationFeed(), name="organization_feed"),
path("rss/games/", GameFeed(), name="game_feed"),
path("rss/campaigns/", DropCampaignFeed(), name="campaign_feed"),
path("docs/rss/", views.docs_rss_view, name="docs_rss"),
]

View file

@ -607,3 +607,32 @@ class GamesListView(GamesGridView):
"""List view for games in simple list format."""
template_name = "twitch/games_list.html"
def docs_rss_view(request: HttpRequest) -> HttpResponse:
"""View for /docs/rss that lists all available RSS feeds.
Args:
request: The HTTP request object.
Returns:
Rendered HTML response with list of RSS feeds.
"""
feeds: list[dict[str, str]] = [
{
"title": "Organizations",
"description": "Latest organizations",
"url": "/rss/organizations/",
},
{
"title": "Games",
"description": "Latest games",
"url": "/rss/games/",
},
{
"title": "Drop Campaigns",
"description": "Latest drop campaigns",
"url": "/rss/campaigns/",
},
]
return render(request, "twitch/docs_rss.html", {"feeds": feeds})