Scrape SunkwiBOT/twitch-drops-api for data
All checks were successful
Deploy to Server / deploy (push) Successful in 29s

This commit is contained in:
Joakim Hellsén 2026-06-14 17:35:24 +02:00
commit 3535d7d2dd
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
28 changed files with 4272 additions and 576 deletions

View file

@ -170,4 +170,73 @@
<p>None ✅</p>
{% endif %}
</section>
<section>
<h2>Data Source Diff — Drop Campaigns</h2>
<p>Comparing campaigns by <code>data_source</code> field in the DB.</p>
<h3>Only in SunkwiBOT/twitch-drops-api ({{ sunkibot_only_drops_count }})</h3>
{% if sunkibot_only_drops %}
<ul>
{% for c in sunkibot_only_drops %}
<li>
<a href="{% url 'twitch:campaign_detail' c.twitch_id %}">{{ c.name }}</a>
(Game: <a href="{% url 'twitch:game_detail' c.game.twitch_id %}">{{ c.game.display_name }}</a>)
</li>
{% endfor %}
</ul>
{% if sunkibot_only_drops_count > 200 %}
<p><em>… and {{ sunkibot_only_drops_count|add:"-200" }} more (showing first 200)</em></p>
{% endif %}
{% else %}
<p>None ✅</p>
{% endif %}
<h3>Only in TwitchDropsMiner ({{ miner_only_drops_count }})</h3>
{% if miner_only_drops %}
<ul>
{% for c in miner_only_drops %}
<li>
<a href="{% url 'twitch:campaign_detail' c.twitch_id %}">{{ c.name }}</a>
(Game: <a href="{% url 'twitch:game_detail' c.game.twitch_id %}">{{ c.game.display_name }}</a>)
</li>
{% endfor %}
</ul>
{% if miner_only_drops_count > 200 %}
<p><em>… and {{ miner_only_drops_count|add:"-200" }} more (showing first 200)</em></p>
{% endif %}
{% else %}
<p>None ✅</p>
{% endif %}
</section>
<section>
<h2>Data Source Diff — Reward Campaigns</h2>
<h3>Only in SunkwiBOT/twitch-drops-api ({{ sunkibot_only_rewards_count }})</h3>
{% if sunkibot_only_rewards %}
<ul>
{% for c in sunkibot_only_rewards %}
<li>
<a href="{% url 'twitch:reward_campaign_detail' c.twitch_id %}">{{ c.name }}</a>
</li>
{% endfor %}
</ul>
{% if sunkibot_only_rewards_count > 200 %}
<p><em>… and {{ sunkibot_only_rewards_count|add:"-200" }} more (showing first 200)</em></p>
{% endif %}
{% else %}
<p>None ✅</p>
{% endif %}
<h3>Only in TwitchDropsMiner ({{ miner_only_rewards_count }})</h3>
{% if miner_only_rewards %}
<ul>
{% for c in miner_only_rewards %}
<li>
<a href="{% url 'twitch:reward_campaign_detail' c.twitch_id %}">{{ c.name }}</a>
</li>
{% endfor %}
</ul>
{% if miner_only_rewards_count > 200 %}
<p><em>… and {{ miner_only_rewards_count|add:"-200" }} more (showing first 200)</em></p>
{% endif %}
{% else %}
<p>None ✅</p>
{% endif %}
</section>
{% endblock content %}

View file

@ -47,48 +47,65 @@
{% endif %}
<!-- Campaign description -->
<p>{{ campaign.description|linebreaksbr }}</p>
<div>
Published
<time datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}">{{ campaign.added_at|date:"M d, Y H:i" }}</time> ({{ campaign.added_at|timesince }} ago)
</div>
<div>
Last updated
<time datetime="{{ campaign.updated_at|date:'c' }}"
title="{{ campaign.updated_at|date:'DATETIME_FORMAT' }}">{{ campaign.updated_at|date:"M d, Y H:i" }}</time> ({{ campaign.updated_at|timesince }} ago)
</div>
<!-- Campaign end times -->
<div>
{% if campaign.end_at < now %}
Ended
<dl>
<dt>Published</dt>
<dd>
<time datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}">{{ campaign.added_at|date:"M d, Y H:i" }}</time> ({{ campaign.added_at|timesince }} ago)
</dd>
<dt>Last updated</dt>
<dd>
<time datetime="{{ campaign.updated_at|date:'c' }}"
title="{{ campaign.updated_at|date:'DATETIME_FORMAT' }}">{{ campaign.updated_at|date:"M d, Y H:i" }}</time> ({{ campaign.updated_at|timesince }} ago)
</dd>
<!-- Campaign end times -->
<dt>
{% if campaign.end_at < now %}
Ended
{% else %}
Ends in
{% endif %}
</dt>
<dd>
<time datetime="{{ campaign.end_at|date:'c' }}"
title="{{ campaign.end_at|date:'DATETIME_FORMAT' }}">{{ campaign.end_at|date:"M d, Y H:i" }}</time> ({{ campaign.end_at|timesince }} ago)
{% else %}
Ends in
<time datetime="{{ campaign.end_at|date:'c' }}"
title="{{ campaign.end_at|date:'DATETIME_FORMAT' }}">{{ campaign.end_at|date:"M d, Y H:i" }}</time> (in {{ campaign.end_at|timeuntil }})
{% endif %}
</div>
<!-- Campaign start times -->
<div>
{% if campaign.start_at > now %}
Starts in
title="{{ campaign.end_at|date:'DATETIME_FORMAT' }}">{{ campaign.end_at|date:"M d, Y H:i" }}</time>
{% if campaign.end_at < now %}
({{ campaign.end_at|timesince }} ago)
{% else %}
(in {{ campaign.end_at|timeuntil }})
{% endif %}
</dd>
<!-- Campaign start times -->
<dt>
{% if campaign.start_at > now %}
Starts in
{% else %}
Started
{% endif %}
</dt>
<dd>
<time datetime="{{ campaign.start_at|date:'c' }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }}">{{ campaign.start_at|date:"M d, Y H:i" }}</time> (in {{ campaign.start_at|timeuntil }})
{% else %}
Started
<time datetime="{{ campaign.start_at|date:'c' }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }}">{{ campaign.start_at|date:"M d, Y H:i" }}</time> ({{ campaign.start_at|timesince }} ago)
{% endif %}
</div>
<!-- Campaign duration -->
<div>
Duration is
<time datetime="{{ campaign.duration_iso }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }} to {{ campaign.end_at|date:'DATETIME_FORMAT' }}">
{{ campaign.end_at|timeuntil:campaign.start_at }}
</time>
</div>
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }}">{{ campaign.start_at|date:"M d, Y H:i" }}</time>
{% if campaign.start_at > now %}
(in {{ campaign.start_at|timeuntil }})
{% else %}
({{ campaign.start_at|timesince }} ago)
{% endif %}
</dd>
<!-- Campaign duration -->
<dt>Duration</dt>
<dd>
<time datetime="{{ campaign.duration_iso }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }} to {{ campaign.end_at|date:'DATETIME_FORMAT' }}">
{{ campaign.end_at|timeuntil:campaign.start_at }}
</time>
</dd>
<!-- Data source -->
<dt>Data source</dt>
<dd>
{{ campaign.data_source }}
</dd>
</dl>
<!-- Buttons -->
<div>
<!-- Campaign Detail URL -->
@ -103,9 +120,9 @@
title="Atom feed for {{ campaign.game.display_name }} campaigns">[atom]</a>
<a href="{% url 'core:game_campaign_feed_discord' campaign.game.twitch_id %}"
title="Discord feed for {{ campaign.game.display_name }} campaigns">[discord]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
<a href="{% url 'twitch:twitch-api-v1:get_campaign' campaign.twitch_id %}"
title="Twitch campaign API">[api]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
{% endif %}
</div>
</div>

View file

@ -50,58 +50,71 @@
</div>
<!-- Campaign Summary -->
{% if reward_campaign.summary %}<p id="campaign-summary">{{ reward_campaign.summary|linebreaksbr }}</p>{% endif %}
<!-- Campaign Status -->
<div>
<strong>Status:</strong>
{% if is_active %}
Active
{% elif reward_campaign.starts_at > now %}
Upcoming
{% else %}
Expired
{% endif %}
</div>
<div>Added at {{ reward_campaign.added_at|date:"M d, Y H:i" }} ({{ reward_campaign.added_at|timesince }} ago)</div>
<div>
Last updated at {{ reward_campaign.updated_at|date:"M d, Y H:i" }} ({{ reward_campaign.updated_at|timesince }} ago)
</div>
<!-- Reward Start Time -->
<div>
{% if reward_campaign.starts_at > now %}
Starts
{% else %}
Started at
{% endif %}
<time datetime="{{ reward_campaign.starts_at|date:'c' }}"
title="{{ reward_campaign.starts_at|date:'DATETIME_FORMAT' }}">
{{ reward_campaign.starts_at|date:"M d, Y H:i" }}
<dl>
<!-- Campaign Status -->
<dt>Status</dt>
<dd>
{% if is_active %}
Active
{% elif reward_campaign.starts_at > now %}
Upcoming
{% else %}
Expired
{% endif %}
</dd>
<dt>Added</dt>
<dd>
{{ reward_campaign.added_at|date:"M d, Y H:i" }} ({{ reward_campaign.added_at|timesince }} ago)
</dd>
<dt>Last updated</dt>
<dd>
{{ reward_campaign.updated_at|date:"M d, Y H:i" }} ({{ reward_campaign.updated_at|timesince }} ago)
</dd>
<!-- Reward Start Time -->
<dt>
{% if reward_campaign.starts_at > now %}
Starts
{% else %}
Started at
{% endif %}
</dt>
<dd>
<time datetime="{{ reward_campaign.starts_at|date:'c' }}"
title="{{ reward_campaign.starts_at|date:'DATETIME_FORMAT' }}">
{{ reward_campaign.starts_at|date:"M d, Y H:i" }}
</time>
{% if reward_campaign.starts_at > now %}
(in {{ reward_campaign.starts_at|timeuntil }})
{% else %}
({{ reward_campaign.starts_at|timesince }} ago)
{% endif %}
</time>
</div>
<!-- Reward End Time -->
<div>
{% if reward_campaign.ends_at > now %}
Ends
{% else %}
Ended at
{% endif %}
<time datetime="{{ reward_campaign.ends_at|date:'c' }}"
title="{{ reward_campaign.ends_at|date:'DATETIME_FORMAT' }}">
{{ reward_campaign.ends_at|date:"M d, Y H:i" }}
</dd>
<!-- Reward End Time -->
<dt>
{% if reward_campaign.ends_at > now %}
Ends
{% else %}
Ended at
{% endif %}
</dt>
<dd>
<time datetime="{{ reward_campaign.ends_at|date:'c' }}"
title="{{ reward_campaign.ends_at|date:'DATETIME_FORMAT' }}">
{{ reward_campaign.ends_at|date:"M d, Y H:i" }}
</time>
{% if reward_campaign.ends_at > now %}
(in {{ reward_campaign.ends_at|timeuntil }})
{% else %}
({{ reward_campaign.ends_at|timesince }} ago)
{% endif %}
</time>
</div>
<div>
{% if reward_campaign.instructions %}{{ reward_campaign.instructions|linebreaksbr }}{% endif %}
</div>
</dd>
<!-- Data source -->
<dt>Data source</dt>
<dd>
{{ reward_campaign.data_source }}
</dd>
</dl>
<div>{% if reward_campaign.instructions %}{{ reward_campaign.instructions|linebreaksbr }}{% endif %}</div>
<!-- RSS Feeds -->
<div style="margin-bottom: 1rem;">
<a href="{% url 'core:reward_campaign_feed' %}"

View file

@ -23,10 +23,10 @@
<div>
<a href="{% url 'twitch:dashboard' %}">Twitch</a> > Reward Campaigns
</div>
<p>This is an archive of old Twitch reward campaigns because we currently do not scrape them.</p>
<p>
Feel free to submit a pull request on <a href="https://github.com/TheLovinator1/ttvdrops">GitHub</a>
with a working implementation :-).
Data is scraped from <a href="https://github.com/SunkwiBOT/twitch-drops-api"
target="_blank"
rel="noopener">SunkwiBOT/twitch-drops-api</a> every 15 minutes.
</p>
<!-- RSS Feeds -->
<div>
@ -36,84 +36,81 @@
title="Atom feed for all reward campaigns">[atom]</a>
<a href="{% url 'core:reward_campaign_feed_discord' %}"
title="Discord feed for all reward campaigns">[discord]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
<a href="{% url 'twitch:twitch-api-v1:list_reward_campaigns' %}"
title="Twitch reward campaigns API">[api]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
</div>
{% if reward_campaigns %}
{% comment %}
<h5>Active Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in reward_campaigns %}
{% if campaign.starts_at <= now and campaign.ends_at >= now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% with active_campaigns=reward_campaigns|dictsortreversed:"ends_at" %}
<h5>Active Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in active_campaigns %}
{% if campaign.starts_at <= now and campaign.ends_at >= now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
Site-wide
{% endif %}
</td>
<td>
<span title="{{ campaign.ends_at|date:'M d, Y H:i' }}">Ends in {{ campaign.ends_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endcomment %}
{% comment %}
<h5>Upcoming Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in reward_campaigns %}
{% if campaign.starts_at > now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
Site-wide
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
Site-wide
{% endif %}
</td>
<td>
<span title="Starts on {{ campaign.starts_at|date:'M d, Y H:i' }}">Starts in {{ campaign.starts_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endcomment %}
</td>
<td>
<span title="{{ campaign.ends_at|date:'M d, Y H:i' }}">Ends in {{ campaign.ends_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<h5>Upcoming Reward Campaigns</h5>
<table>
<tbody>
{% for campaign in active_campaigns %}
{% if campaign.starts_at > now %}
<tr>
<td>
<a href="{% url 'twitch:reward_campaign_detail' campaign.twitch_id %}">
{% if campaign.brand %}
{{ campaign.brand }}: {{ campaign.name }}
{% else %}
{{ campaign.name }}
{% endif %}
</a>
{% if campaign.summary %}
<br />
<small>{{ campaign.summary }}</small>
{% endif %}
</td>
<td>
{% if campaign.game %}
<a href="{% url 'twitch:game_detail' campaign.game.twitch_id %}">{{ campaign.game.display_name }}</a>
{% elif campaign.is_sitewide %}
Site-wide
{% endif %}
</td>
<td>
<span title="Starts on {{ campaign.starts_at|date:'M d, Y H:i' }}">Starts in {{ campaign.starts_at|timeuntil }}</span>
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endwith %}
<h5>Past Reward Campaigns</h5>
<table>
<tbody>