From b35f8a19d0a9953ed08a1414761037436807453f Mon Sep 17 00:00:00 2001 From: Sandeep Bhat Date: Thu, 9 Jan 2025 17:14:51 +0100 Subject: [PATCH] Add a simple RSS based news app - Fetch top and latest news from NDTV's RSS feed - Display each news as a card - Style using Pico CSS --- news-app/README.md | 19 ++++++++++++++ news-app/main.py | 55 +++++++++++++++++++++++++++++++++++++++ news-app/requirements.txt | 2 ++ 3 files changed, 76 insertions(+) create mode 100644 news-app/README.md create mode 100644 news-app/main.py create mode 100644 news-app/requirements.txt diff --git a/news-app/README.md b/news-app/README.md new file mode 100644 index 0000000..6bedd3a --- /dev/null +++ b/news-app/README.md @@ -0,0 +1,19 @@ +# Simple RSS feed based news app built using FastHTML + +## News sources +Uses NDTV RSS feed to fetch the latest and top news. + +* https://www.ndtv.com/rss +* https://feeds.feedburner.com/ndtvnews-top-stories +* https://feeds.feedburner.com/ndtvnews-latest + + +## Running locally +Verified with Python3.12 + +``` +python3.12 -m venv .venv +source .venv/bin/activate +pip install -r requirements.txt +python main.py +``` diff --git a/news-app/main.py b/news-app/main.py new file mode 100644 index 0000000..8383e3c --- /dev/null +++ b/news-app/main.py @@ -0,0 +1,55 @@ +import feedparser +from fasthtml.common import * + +css = Style(':root {--pico-font-size:90%,--pico-font-family: Pacifico, cursive;}') +app = FastHTML(hdrs=(picolink, css)) + + +class NewsType(Enum): + TOP_STORIES = 1 + LATEST_STORIES = 2 + def get_rss_feed_url(news_type): + if news_type == NewsType.TOP_STORIES: + return "https://feeds.feedburner.com/ndtvnews-top-stories" + else: + return "https://feeds.feedburner.com/ndtvnews-latest" + + +def fetch_news(news_type): + feed = feedparser.parse(NewsType.get_rss_feed_url(news_type)) + return feed.entries + + +def build_articles(entries: list): + articles = list() + for entry in entries: + article = Article( + Hgroup(Summary(Strong(entry.title)), P(entry.summary)), + A("Read More", href=entry.link, target="_blank", rel="noopener noreferrer", + cls="secondary") + ) + articles.append((article, Hr())) + return Div(*articles, cls="stack") + + +def build_top_nav(): + return Nav( + Ul(Li(H2('SimpleNewsApp'))), + Ul(Li(A('Top', href='/')), Li(A('Latest', href='/latest')))) + + +@app.route("/") +def get(): + entries = fetch_news(NewsType.TOP_STORIES) + articles = build_articles(entries) + return (Title("SimpleNewsApp"), Main(build_top_nav(), *articles, cls="container")) + + +@app.route("/latest") +def get(): + entries = fetch_news(NewsType.LATEST_STORIES) + articles = build_articles(entries) + return (Title("SimpleNewsApp"), Main(build_top_nav(), *articles, cls="container")) + + +serve() diff --git a/news-app/requirements.txt b/news-app/requirements.txt new file mode 100644 index 0000000..2c89621 --- /dev/null +++ b/news-app/requirements.txt @@ -0,0 +1,2 @@ +python-fasthtml==0.12.0 +feedparser==6.0.11