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"

{author} ({submission.score})

" content += f"

{submission.selftext_html}

" 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"
  • {author} ({comment.score}) {comment.body_html}" content += f"" 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")