Add YouTube

This commit is contained in:
Joakim Hellsén 2026-03-16 21:27:11 +01:00
commit 5bdee66207
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
12 changed files with 214 additions and 1 deletions

0
youtube/__init__.py Normal file
View file

7
youtube/apps.py Normal file
View file

@ -0,0 +1,7 @@
from django.apps import AppConfig
class YoutubeConfig(AppConfig):
"""Django app configuration for the YouTube app."""
name = "youtube"

View file

View file

View file

@ -0,0 +1,49 @@
from typing import TYPE_CHECKING
from django.test import TestCase
from django.urls import reverse
if TYPE_CHECKING:
from django.test.client import _MonkeyPatchedWSGIResponse
class YouTubeIndexViewTest(TestCase):
"""Tests for the YouTube drops channels index page."""
def test_index_returns_200(self) -> None:
"""The YouTube index page should return HTTP 200."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
assert response.status_code == 200
def test_index_displays_known_channels(self) -> None:
"""The page should include key known channels from the partner list."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode()
assert "YouTube Drops Channels" in content
assert "Call of Duty" in content
assert "PlayOverwatch" in content
assert "Hearthstone" in content
assert "Fortnite" in content
assert "Riot Games" in content
assert "Ubisoft" in content
def test_index_includes_partner_urls(self) -> None:
"""The page should render partner channel links from the source list."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode()
assert "https://www.youtube.com/channel/UCbLIqv9Puhyp9_ZjVtfOy7w" in content
assert "https://www.youtube.com/user/epicfortnite" in content
assert "https://www.youtube.com/lolesports" in content
def test_index_groups_partners_alphabetically(self) -> None:
"""Partner sections should render grouped and in alphabetical order."""
response: _MonkeyPatchedWSGIResponse = self.client.get(reverse("youtube:index"))
content: str = response.content.decode()
assert "<h2>Activision (Call of Duty)</h2>" in content
assert "<h2>Battle.net / Blizzard</h2>" in content
assert content.index("<h2>Activision (Call of Duty)</h2>") < content.index(
"<h2>Battle.net / Blizzard</h2>",
)

16
youtube/urls.py Normal file
View file

@ -0,0 +1,16 @@
from typing import TYPE_CHECKING
from django.urls import path
from youtube import views
if TYPE_CHECKING:
from django.urls.resolvers import URLPattern
from django.urls.resolvers import URLResolver
app_name = "youtube"
urlpatterns: list[URLPattern | URLResolver] = [
path(route="", view=views.index, name="index"),
]

115
youtube/views.py Normal file
View file

@ -0,0 +1,115 @@
from collections import defaultdict
from typing import TYPE_CHECKING
from django.shortcuts import render
if TYPE_CHECKING:
from django.http import HttpRequest
from django.http import HttpResponse
def index(request: HttpRequest) -> HttpResponse:
"""Render a minimal list of YouTube channels with known drops-enabled partners.
Returns:
HttpResponse: Rendered index page for YouTube drops channels.
"""
channels: list[dict[str, str]] = [
{
"partner": "Activision (Call of Duty)",
"channel": "Call of Duty",
"url": "https://www.youtube.com/channel/UCbLIqv9Puhyp9_ZjVtfOy7w",
},
{
"partner": "Battle.net / Blizzard",
"channel": "PlayOverwatch",
"url": "https://www.youtube.com/c/playoverwatch/featured",
},
{
"partner": "Battle.net / Blizzard",
"channel": "Hearthstone",
"url": "https://www.youtube.com/c/Hearthstone/featured",
},
{
"partner": "Electronic Arts",
"channel": "FIFA",
"url": "https://www.youtube.com/channel/UCFA6YGp5lvgayO20lk7_Ung",
},
{
"partner": "Electronic Arts",
"channel": "EA Madden NFL",
"url": "https://www.youtube.com/@EAMaddenNFL",
},
{
"partner": "Epic Games",
"channel": "Fortnite",
"url": "https://www.youtube.com/user/epicfortnite",
},
{
"partner": "Garena",
"channel": "Free Fire",
"url": "https://www.youtube.com/channel/UC_vVy4OI86F0amXqFN_zTMg",
},
{
"partner": "Krafton (PUBG)",
"channel": "PUBG: BATTLEGROUNDS",
"url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g",
},
{
"partner": "MLBB",
"channel": "Mobile Legends: Bang Bang",
"url": "https://www.youtube.com/channel/UCqmld-BIYME2i_ooRTo1EOg",
},
{
"partner": "NBA",
"channel": "NBA",
"url": "https://www.youtube.com/user/NBA",
},
{
"partner": "NFL",
"channel": "NFL",
"url": "https://www.youtube.com/@NFL",
},
{
"partner": "PUBG Mobile",
"channel": "PUBG MOBILE",
"url": "https://www.youtube.com/channel/UCTDO0RgowRyaAEUrPnBAg4g",
},
{
"partner": "Riot Games",
"channel": "Riot Games",
"url": "https://www.youtube.com/user/RiotGamesInc",
},
{
"partner": "Riot Games",
"channel": "LoL Esports",
"url": "https://www.youtube.com/lolesports",
},
{
"partner": "Supercell",
"channel": "Clash Royale",
"url": "https://www.youtube.com/channel/UC_F8DoJf9MZogEOU51TpTbQ",
},
{
"partner": "Ubisoft",
"channel": "Ubisoft",
"url": "https://www.youtube.com/user/ubisoft",
},
]
grouped_channels: dict[str, list[dict[str, str]]] = defaultdict(list)
for channel in channels:
grouped_channels[channel["partner"]].append(channel)
partner_groups: list[dict[str, str | list[dict[str, str]]]] = []
for partner in sorted(grouped_channels.keys(), key=str.lower):
sorted_items: list[dict[str, str]] = sorted(
grouped_channels[partner],
key=lambda item: item["channel"].lower(),
)
partner_groups.append({"partner": partner, "channels": sorted_items})
context: dict[str, list[dict[str, str | list[dict[str, str]]]]] = {
"partner_groups": partner_groups,
}
return render(request=request, template_name="youtube/index.html", context=context)