Spaces:
Running
Running
| # NewsApp β Agent Summary | |
| ## Project Structure | |
| ``` | |
| newsapp/ | |
| βββ AGENTS.md β this file | |
| βββ config.py β dataclass with all settings (feeds, weights, interests) | |
| βββ main.py β entrypoint (CLI or module) | |
| βββ requirements.txt | |
| βββ webapp.py β Flask web server (serves frontend) | |
| βββ templates/ | |
| β βββ index.html β tabbed UI, dynamically generated from categories | |
| βββ static/ β (empty, reserved for assets) | |
| βββ src/ | |
| βββ __init__.py | |
| βββ rss_feed_scraper.py β RSS feed fetcher + article extractor (trafilatura) | |
| βββ models.py β NewsItem, Article, Post, Cluster, Analysis dataclasses | |
| βββ analyzer.py β NLP: summarisation, topic classification, trust, opinion, leaning | |
| βββ clustering.py β similarity-based article clustering + scoring (removed β logic in presenter) | |
| βββ presenter.py β output formatting (terminal + web JSON) | |
| ``` | |
| ## Current State | |
| ### RSS Feeds (42 sources across 9 categories) | |
| - **Geopolitical**: BBC World, NYT World, NYT Politics, NPR, Al Jazeera, The Guardian | |
| - **World Health**: BBC Health, NYT Science, Stat News, Science Daily | |
| - **Tech**: BBC Tech, NYT Tech, TechCrunch, Wired, The Verge, Ars Technica | |
| - **Cybersecurity**: The Hacker News, Krebs on Security, BleepingComputer, Threatpost, The Record | |
| - **Funny/Weird**: The Onion, r/nottheonion, Daily Mash, Babylon Bee | |
| - **Gaming**: IGN, Eurogamer, PC Gamer, Kotaku, Gamespot, Polygon | |
| - **Movies**: Variety, Hollywood Reporter, Deadline, Screen Rant | |
| - **Arab World**: Arab News, Middle East Eye, The New Arab, France24 ME | |
| - **Tunisia**: Tunisia Online News, North Africa Post, Africa News | |
| - `posts_per_subreddit = 3` β ~126 posts total per run | |
| ### Topic Detection (keyword-based, word-boundary regex) | |
| - 21 topics tracked: gaming, movies, tunisia, arab_world, AI, climate, health, economy, space, cybersecurity, politics, science, technology, sports, education, immigration, energy, world, funny, weird, onion | |
| - Source-domain fallback: applies only when keyword matching finds zero topics (avoids false positives for off-topic articles from movie/entertainment sites) | |
| - Priority ordering determines which category wins: onion > funny > weird > cybersecurity > gaming > technology > AI > health > science > tunisia > arab_world > world > politics > immigration > economy > energy > education > climate > space > sports > movies | |
| ### Categories (9) | |
| Geopolitical | World Health | Tech | Cybersecurity | Funny/Weird | Gaming | Movies | Arab World | Tunisia | |
| ### Scoring Model | |
| - `final_score = 0.20*pop + 0.35*trust + 0.30*coverage + 0.15*recency` | |
| - Trust spread 0.05β1.00 based on source reputation, extraction success, article length, factual language, clickbait/opinion penalties | |
| - Clustering: similarity threshold 0.70; articles merge into clusters; cluster gets max(article scores) | |
| - Recency: 1.0 for <1h, decays linearly to 0.0 at 72h | |
| ### Web UI | |
| - Flask app at port 5050 | |
| - Tabbed interface (dynamically generated from CATEGORIES list) | |
| - Cards with image, topic badge, summary, trust/coverage badges, bias/factuality badges, relevance score bar, date badge, sponsor modal | |
| - Articles grouped by date (date headers in red uppercase) and sorted by relevance within each day | |
| - Article extraction via trafilatura with readability fallback | |
| - NYT blocked (403) β falls back to title-only extraction | |
| - **PressBook News Dark theme**: pure black bg, red accent (#d72924), IBM Plex Serif + Lora fonts | |
| - **Alive animations**: entrance stagger (60ms steps), card hover glow+scale+image zoom, tab sliding underline, status dot pulse, score bar fill on reveal, button hover brightness+scale, counter count-up, scroll-triggered reveal (IntersectionObserver), loading skeleton shimmer | |
| ## What We Did | |
| ### Category Overhaul (prior to this session) | |
| - Split everything into 5 categories: Geopolitical, World Health, Tech, Cybersecurity, Funny/Weird | |
| - Removed crypto topic; merged funny/weird/onion/sports into Funny/Weird | |
| - Fixed category "bleeding" (NYT World β Geopolitical, not Tech) | |
| - Added subject-based keywords + regex for all topics | |
| - Added source-domain fallback for krebs, bleepingcomputer, theonion | |
| - Priority-based `_map_category` with word-boundary patterns | |
| - Removed fluff tagging; expanded factual/clickbait/opinion signals | |
| - Recency weight reduced from 0.25 to 0.15 | |
| - Off-topic detection: penalized AI/space articles in general news feeds | |
| - Rebranded "Health" β "World Health" | |
| ### Stability & Config | |
| - Moved all settings to `Config` dataclass | |
| - Reduced feed count, added per-feed error tolerance (continues on failure) | |
| - Removed pointless re-clustering in presenter; now uses clusters from pipeline directly | |
| ### Gaming + Arab World (previous session) | |
| - Added 3 gaming feeds and 2 Arab world feeds | |
| - Added `gaming` and `arab_world` topics with keyword patterns + domain fallback | |
| - Moved `arab_world` above `world` in priority | |
| - Added Gaming and Arab World to CATEGORIES | |
| - Lowered `posts_per_subreddit` to 2 | |
| ### Date Grouping (recent) | |
| - Added `published_iso` field to Article model for reliable date sorting | |
| - Clusters sorted by date (newest first), then by relevance score within each day | |
| - Date headers rendered as indigo uppercase badges above article groups | |
| - Failed date parsing falls back to ISO format parsing for display | |
| ### Movies + Tunisia (current session) | |
| - Added 4 movie feeds (Variety, Hollywood Reporter, Deadline, Screen Rant) | |
| - Added 3 Tunisia feeds (Tunisia Online News, North Africa Post, Africa News) | |
| - Added `movies` and `tunisia` topics to TOPIC_MAP with keyword patterns | |
| - Added movie/entertainment and Tunisia domains to DOMAIN_TOPICS | |
| - Changed domain fallback to only trigger when keyword matching finds zero topics (reduces off-topic leakage) | |
| - Movies placed last in priority (acts as catch-all for entertainment sites) | |
| - Tunisia placed above arab_world/world for correct categorization of Tunisia articles | |
| - Added Movies and Tunisia to CATEGORIES (now 9 total) | |
| - Raised `posts_per_subreddit` to 3 for adequate article counts per category | |
| ### HOW TO RUN: | |
| - python webapp.py | |
| ### Media Bias / Factuality + Ownership (current session) | |
| - Expanded `Analysis` model with `source_bias`/`source_factuality`/`article_leaning` fields | |
| - `_detect_article_leaning()` replaces old `_detect_political_leaning()` with a 6-point scale: left, left-center, center, right-center, right, satire (keyword-count-based) | |
| - SPONSOR_INFO now stores `bias` (6-point MBFC-style) and `factuality` (high/mixed/low/satire) per source β 42+ outlets mapped | |
| - `_detect_sponsor()` returns `category` (Ground News 7-type system) instead of old `type` key | |
| - Sponsor page (`/sponsors`) shows bias + factuality badges per ownership group | |
| - Article cards show bias + factuality badges next to trust/coverage badges | |
| - Bias/factuality from source assigned to all articles from that source (matching Ground News methodology) | |
| - `article_leaning` kept as separate signal (keyword-based, article-specific) vs `source_bias` (MBFC rating of the outlet) | |
| - Removed orphaned `_detect_political_leaning()` static method | |
| - All new fields exposed in both HTML templates and JSON REST API | |
| ### PressBook Dark Theme + Animations (latest session) | |
| - Applied PressBook News Dark theme: pure black bg (#000), red accent (#d72924), dark cards (rgba(12,12,12,0.92)), IBM Plex Serif + Lora fonts, red gradient buttons | |
| - Replaced standalone sponsors page with per-article sponsor modal (owner name, parent, category badge, bias/factuality badges, shareholders, Wikipedia link) | |
| - Removed header link to standalone sponsors page | |
| - Changed card display from `source_bias` to `article_leaning` (keyword-based), with source bias as muted hint when different | |
| - Fixed political leaning algorithm: expanded LEFT_KEYWORDS to 30+ terms, lowered threshold to diff >= 2 | |
| - Added sourcing penalty: detects explicit outlet citations ("According to The Guardian"), penalizes score up to 0.12 | |
| - Added all "alive" animations: | |
| - Entrance stagger: cards fade+slide up with 60ms step delay per card | |
| - Hover: card glow (#d72924 shadow) + scale 1.02 + image zoom 1.05 | |
| - Tab sliding underline: JS-positioned element slides between tabs (300ms cubic-bezier) | |
| - Status dot pulse: CSS keyframe pulse (scale + box-shadow oscillation, 2s infinite) | |
| - Score bar fill: animate width from 0 to target via double rAF | |
| - Button hover brightness (1.2) + scale (1.04), press (0.97) | |
| - Counter count-up: step-wise increment from 0 to target | |
| - Scroll reveal: IntersectionObserver with 100ms threshold, reveals cards on scroll | |
| - Loading skeleton shimmer: CSS gradient shimmer (1.5s infinite), hidden on JS init | |
| - All animation durations in 150-350ms range (snappy), skeletons/shimmer at 1.5s |