Add YouTube
This commit is contained in:
parent
ea242955d9
commit
5bdee66207
12 changed files with 214 additions and 1 deletions
0
youtube/__init__.py
Normal file
0
youtube/__init__.py
Normal file
7
youtube/apps.py
Normal file
7
youtube/apps.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class YoutubeConfig(AppConfig):
|
||||
"""Django app configuration for the YouTube app."""
|
||||
|
||||
name = "youtube"
|
||||
0
youtube/migrations/__init__.py
Normal file
0
youtube/migrations/__init__.py
Normal file
0
youtube/tests/__init__.py
Normal file
0
youtube/tests/__init__.py
Normal file
49
youtube/tests/test_youtube.py
Normal file
49
youtube/tests/test_youtube.py
Normal 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
16
youtube/urls.py
Normal 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
115
youtube/views.py
Normal 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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue