Add support for Atom feeds

This commit is contained in:
Joakim Hellsén 2026-03-10 07:51:55 +01:00
commit 6c22559fb5
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
16 changed files with 293 additions and 0 deletions

View file

@ -4,6 +4,18 @@
{% block title %}
{{ campaign.clean_name }}
{% endblock title %}
{% block extra_head %}
{% if campaign and campaign.game %}
<link rel="alternate"
type="application/rss+xml"
title="{{ campaign.game.display_name }} campaigns (RSS)"
href="{% url 'twitch:game_campaign_feed' campaign.game.twitch_id %}" />
<link rel="alternate"
type="application/atom+xml"
title="{{ campaign.game.display_name }} campaigns (Atom)"
href="{% url 'twitch:game_campaign_feed_atom' campaign.game.twitch_id %}" />
{% endif %}
{% endblock extra_head %}
{% block content %}
<!-- Campaign Title -->
<h1>
@ -71,6 +83,8 @@
{% if campaign.game %}
<a href="{% url 'twitch:game_campaign_feed' campaign.game.twitch_id %}"
title="RSS feed for {{ campaign.game.display_name }} campaigns">[rss]</a>
<a href="{% url 'twitch:game_campaign_feed_atom' campaign.game.twitch_id %}"
title="Atom feed for {{ campaign.game.display_name }} campaigns">[atom]</a>
{% endif %}
</div>
{% if allowed_channels %}

View file

@ -5,6 +5,16 @@
{% block title %}
Drop Campaigns - Twitch Drops Tracker
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="All campaigns (RSS)"
href="{% url 'twitch:campaign_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="All campaigns (Atom)"
href="{% url 'twitch:campaign_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<main>
<header>
@ -13,6 +23,8 @@
<div>
<a href="{% url 'twitch:campaign_feed' %}"
title="RSS feed for all campaigns">[rss]</a>
<a href="{% url 'twitch:campaign_feed_atom' %}"
title="Atom feed for all campaigns">[atom]</a>
<a href="{% url 'twitch:export_campaigns_csv' %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}"
title="Export campaigns as CSV">[csv]</a>
<a href="{% url 'twitch:export_campaigns_json' %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}"

View file

@ -4,6 +4,16 @@
{% block title %}
Twitch drops
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="All campaigns (RSS)"
href="{% url 'twitch:campaign_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="All campaigns (Atom)"
href="{% url 'twitch:campaign_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<main>
<h1>Twitch Drops</h1>
@ -16,6 +26,9 @@ Hover over the end time to see the exact date and time.
<a href="{% url 'twitch:campaign_feed' %}"
style="margin-right: 1rem"
title="RSS feed for all campaigns">RSS feed for campaigns</a>
&nbsp;|&nbsp;
<a href="{% url 'twitch:campaign_feed_atom' %}"
title="Atom feed for campaigns">Atom feed for campaigns</a>
</div>
{% if campaigns_by_game %}
{% for game_id, game_data in campaigns_by_game.items %}

View file

@ -7,6 +7,11 @@
<main>
<h1>RSS Feeds Documentation</h1>
<p>This page lists all available RSS feeds for TTVDrops.</p>
<p>
Note: Atom feeds are also available for the same resources under the
<code>/atom/</code> endpoints (links labeled "Atom" are shown next to RSS links).
Both RSS and Atom formats are supported and served in parallel for backward compatibility.
</p>
<section>
<h2>Global RSS Feeds</h2>
<p>These feeds contain all items across the entire site:</p>
@ -17,8 +22,16 @@
<p>{{ feed.description }}</p>
<p>
<a href="{{ feed.url }}">Subscribe to {{ feed.title }} RSS Feed</a>
{% if feed.atom_url %}
&nbsp;|&nbsp;
<a href="{{ feed.atom_url }}">Subscribe to {{ feed.title }} Atom Feed</a>
{% endif %}
</p>
<pre><code class="language-xml">{% if feed.example_xml %}{{ feed.example_xml|escape }}{% else %}No example XML available yet.{% endif %}</code></pre>
{% if feed.example_xml_atom %}
<h4>Atom example</h4>
<pre><code class="language-xml">{{ feed.example_xml_atom|escape }}</code></pre>
{% endif %}
</li>
{% endfor %}
</ul>
@ -35,13 +48,22 @@
<p>{{ feed.description }}</p>
<p>
Endpoint: <code>{{ feed.url }}</code>
{% if feed.atom_url %}&nbsp;|&nbsp; Atom: <code>{{ feed.atom_url }}</code>{% endif %}
</p>
{% if feed.has_sample %}
<p>
<a href="{{ feed.url }}">View a live example</a>
{% if feed.atom_url %}
&nbsp;|&nbsp;
<a href="{{ feed.atom_url }}">View Atom example</a>
{% endif %}
</p>
{% endif %}
<pre><code class="language-xml">{% if feed.example_xml %}{{ feed.example_xml|escape }}{% else %}No example XML available yet.{% endif %}</code></pre>
{% if feed.example_xml_atom %}
<h4>Atom example</h4>
<pre><code class="language-xml">{{ feed.example_xml_atom|escape }}</code></pre>
{% endif %}
</li>
{% endfor %}
</ul>

View file

@ -3,6 +3,18 @@
{% block title %}
{{ game.display_name }}
{% endblock title %}
{% block extra_head %}
{% if game %}
<link rel="alternate"
type="application/rss+xml"
title="{{ game.display_name }} campaigns (RSS)"
href="{% url 'twitch:game_campaign_feed' game.twitch_id %}" />
<link rel="alternate"
type="application/atom+xml"
title="{{ game.display_name }} campaigns (Atom)"
href="{% url 'twitch:game_campaign_feed_atom' game.twitch_id %}" />
{% endif %}
{% endblock extra_head %}
{% block content %}
<!-- Game Title -->
<h1>
@ -13,6 +25,9 @@
<div>
<a href="{% url 'twitch:game_campaign_feed' game.twitch_id %}"
title="RSS feed for {{ game.display_name }} campaigns">RSS feed for {{ game.display_name }} campaigns</a>
&nbsp;|&nbsp;
<a href="{% url 'twitch:game_campaign_feed_atom' game.twitch_id %}"
title="Atom feed for {{ game.display_name }} campaigns">Atom feed for {{ game.display_name }} campaigns</a>
</div>
<!-- Game image -->
{% if game.box_art_best_url %}

View file

@ -3,6 +3,16 @@
{% block title %}
Games - Grid View
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="Newly added games (RSS)"
href="{% url 'twitch:game_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="Newly added games (Atom)"
href="{% url 'twitch:game_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<main>
<header>
@ -10,6 +20,8 @@
<div>
<a href="{% url 'twitch:games_list' %}" title="View games as list">[list]</a>
<a href="{% url 'twitch:game_feed' %}" title="RSS feed for all games">[rss]</a>
<a href="{% url 'twitch:game_feed_atom' %}"
title="Atom feed for all games">[atom]</a>
<a href="{% url 'twitch:export_games_csv' %}"
title="Export all games as CSV">[csv]</a>
<a href="{% url 'twitch:export_games_json' %}"

View file

@ -2,12 +2,24 @@
{% block title %}
Games - List View
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="Newly added games (RSS)"
href="{% url 'twitch:game_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="Newly added games (Atom)"
href="{% url 'twitch:game_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<main>
<h1>Games List</h1>
<div>
<a href="{% url 'twitch:games_grid' %}" title="View games as grid">[grid]</a>
<a href="{% url 'twitch:game_feed' %}" title="RSS feed for all games">[rss]</a>
<a href="{% url 'twitch:game_feed_atom' %}"
title="Atom feed for all games">[atom]</a>
<a href="{% url 'twitch:export_games_csv' %}"
title="Export all games as CSV">[csv]</a>
<a href="{% url 'twitch:export_games_json' %}"

View file

@ -9,6 +9,8 @@
<a href="{% url 'twitch:organization_feed' %}"
style="margin-right: 1rem"
title="RSS feed for all organizations">RSS feed for organizations</a>
<a href="{% url 'twitch:organization_feed_atom' %}"
title="Atom feed for all organizations">[atom]</a>
</div>
<!-- Export Options -->
<div style="margin-bottom: 1rem; display: flex; gap: 1rem;">

View file

@ -2,6 +2,20 @@
{% block title %}
{{ organization.name }}
{% endblock title %}
{% block extra_head %}
{% if games %}
{% for game in games %}
<link rel="alternate"
type="application/rss+xml"
title="{{ game.display_name|default:game.name|default:game.twitch_id }} campaigns (RSS)"
href="{% url 'twitch:game_campaign_feed' game.twitch_id %}" />
<link rel="alternate"
type="application/atom+xml"
title="{{ game.display_name|default:game.name|default:game.twitch_id }} campaigns (Atom)"
href="{% url 'twitch:game_campaign_feed_atom' game.twitch_id %}" />
{% endfor %}
{% endif %}
{% endblock extra_head %}
{% block content %}
<h1 id="org-name">{{ organization.name }}</h1>
<theader>

View file

@ -4,6 +4,16 @@
{% block title %}
{{ reward_campaign.name }}
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="Reward campaigns (RSS)"
href="{% url 'twitch:reward_campaign_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="Reward campaigns (Atom)"
href="{% url 'twitch:reward_campaign_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<!-- Campaign Title -->
{% if reward_campaign.brand %}
@ -24,6 +34,8 @@
<a href="{% url 'twitch:reward_campaign_feed' %}"
style="margin-right: 1rem"
title="RSS feed for all reward campaigns">RSS feed for all reward campaigns</a>
<a href="{% url 'twitch:reward_campaign_feed_atom' %}"
title="Atom feed for all reward campaigns">[atom]</a>
</div>
<!-- Campaign Summary -->
{% if reward_campaign.summary %}<p id="campaign-summary">{{ reward_campaign.summary|linebreaksbr }}</p>{% endif %}

View file

@ -3,6 +3,16 @@
{% block title %}
Reward Campaigns - Twitch Drops Tracker
{% endblock title %}
{% block extra_head %}
<link rel="alternate"
type="application/rss+xml"
title="Reward campaigns (RSS)"
href="{% url 'twitch:reward_campaign_feed' %}" />
<link rel="alternate"
type="application/atom+xml"
title="Reward campaigns (Atom)"
href="{% url 'twitch:reward_campaign_feed_atom' %}" />
{% endblock extra_head %}
{% block content %}
<h1 id="page-title">Reward Campaigns (Quest Rewards)</h1>
<p>Browse all available quest reward campaigns</p>
@ -11,6 +21,8 @@
<a href="{% url 'twitch:reward_campaign_feed' %}"
style="margin-right: 1rem"
title="RSS feed for all reward campaigns">RSS feed for all reward campaigns</a>
<a href="{% url 'twitch:reward_campaign_feed_atom' %}"
title="Atom feed for all reward campaigns">[atom]</a>
</div>
<!-- Filter Form -->
<form id="filter-form"