rss/main.py

73 lines
2.4 KiB
Python

from contextlib import asynccontextmanager
from datetime import datetime, timezone
from os import environ
import asyncpraw
from async_lru import alru_cache
from fastapi import FastAPI, Response, HTTPException
from feedgen.feed import FeedGenerator
REDDIT_CLIENT_ID = environ["REDDIT_CLIENT_ID"]
REDDIT_CLIENT_SECRET = environ["REDDIT_CLIENT_SECRET"]
REDDIT_PASSWORD = environ["REDDIT_PASSWORD"]
REDDIT_USERNAME = environ["REDDIT_USERNAME"]
RSS_HOST = environ["RSS_HOST"]
@alru_cache(ttl=15 * 60)
async def fetch(feed, comments):
fg = FeedGenerator()
fg.id(f'{RSS_HOST}/{feed}')
fg.title(f'r/{feed}')
fg.link(href=f'{RSS_HOST}/{feed}')
fg.description(f'r/{feed}')
client = asyncpraw.Reddit(
user_agent="stuff",
client_id=REDDIT_CLIENT_ID,
client_secret=REDDIT_CLIENT_SECRET,
username=REDDIT_USERNAME,
password=REDDIT_PASSWORD,
)
async with client as reddit:
subreddit = await reddit.subreddit(feed)
async for submission in subreddit.top(limit=30, time_filter="week"):
if submission.selftext == "":
continue
fe = fg.add_entry()
fe.id(submission.id)
fe.title(submission.title)
fe.link(href=submission.url)
fe.pubDate(datetime.fromtimestamp(submission.created_utc, timezone.utc))
author = 'none' if submission.author is None else submission.author.name
content = f"<p>{author} ({submission.score})</p>"
content += f"<p>{submission.selftext_html}</p>"
if comments:
comments = ""
for comment in await submission.comments():
if isinstance(comment, asyncpraw.models.MoreComments):
continue
if comment.author is None:
continue
author = comment.author.name
if author.lower() == 'automoderator':
continue
comments += f"<li>{author} ({comment.score}) {comment.body_html}"
content += f"<ul>{comments}</ul>"
fe.content(content)
rss = fg.rss_str(pretty=True)
return rss
app = FastAPI()
@app.get("/{feed}")
async def root(feed: str, comments: bool = False):
rss = await fetch(feed, comments)
return Response(content=rss, media_type="application/xml")