diff --git a/templates/base.html b/templates/base.html index ab4d1f4..55844f8 100644 --- a/templates/base.html +++ b/templates/base.html @@ -47,6 +47,7 @@ Campaigns | Games | Organizations | + RSS Docs | {% if user.is_authenticated %} Debug | {% if user.is_staff %} diff --git a/templates/twitch/docs_rss.html b/templates/twitch/docs_rss.html new file mode 100644 index 0000000..2909f28 --- /dev/null +++ b/templates/twitch/docs_rss.html @@ -0,0 +1,25 @@ +{% extends "base.html" %} +{% load static %} +{% block title %} + RSS Feeds Documentation +{% endblock title %} +{% block content %} +
+

RSS Feeds Documentation

+

This page lists all available RSS feeds for TTVDrops.

+
+

Available RSS Feeds

+ +
+
+{% endblock content %} diff --git a/twitch/feeds.py b/twitch/feeds.py new file mode 100644 index 0000000..a1670e4 --- /dev/null +++ b/twitch/feeds.py @@ -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]) diff --git a/twitch/urls.py b/twitch/urls.py index 57dc6a6..b459ffc 100644 --- a/twitch/urls.py +++ b/twitch/urls.py @@ -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//", views.OrgDetailView.as_view(), name="organization_detail"), path("organizations//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"), ] diff --git a/twitch/views.py b/twitch/views.py index b5b1bb0..fe1f931 100644 --- a/twitch/views.py +++ b/twitch/views.py @@ -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})