feedleware/feedleware/twitch/feed.py

74 lines
2.2 KiB
Python

from datetime import datetime
from ..feedformatter import Feed
from .twitch import APIClient
def parse_iso(iso: str) -> datetime:
return datetime.fromisoformat(iso.replace("Z", "+00:00"))
def construct_rss(client: APIClient, login: str) -> str:
"""
Build a RSS stream for a Twitch user.
:param client: Twitch API client
:param login: user login
:returns: RSS stream
:raises HTTPException: if one of the requests fail
:raises NoSuchUser: if the user does not exist
"""
user_info = client.user(login)
channel_id = user_info["id"]
videos = client.videos(channel_id)
stream = client.stream(channel_id)
feed = Feed()
user_url = f"https://www.twitch.tv/{user_info['login']}"
# Set the feed/channel level properties
feed.feed["title"] = user_info["display_name"]
feed.feed["link"] = user_url
feed.feed["author"] = "Twitch RSS Generated"
feed.feed["description"] = user_info["description"]
feed.feed["ttl"] = '10'
if stream is not None:
item = {}
item["guid"] = stream["id"]
item["title"] = "[⏺️ Live] " + stream.get("title", "Untitled Stream")
item["link"] = user_url
item["description"] = stream.get("game_name", "")
item["pubDate"] = parse_iso(stream["started_at"]).timetuple()
feed.items.append(item)
for video in videos:
if video.get("viewable", "public") != "public":
continue
item = {}
if video.get("stream_id") is not None:
if stream is not None and stream["id"] == video["stream_id"]:
# Do not add a second item for the active stream
continue
item["guid"] = video["stream_id"]
else:
item["guid"] = video["id"]
item["title"] = video.get("title", "Untitled Video")
link = video.get("url", user_url)
thumbnail = video["thumbnail_url"] \
.replace("%{width}", "600") \
.replace("%{height}", "400")
item["link"] = link
item["description"] = f'<a href="{link}"><img src="{thumbnail}" /></a>'
item["pubDate"] = parse_iso(video["published_at"]).timetuple()
feed.items.append(item)
return feed.format_rss2_string()