diff options
| author | Ben Sima <ben@bsima.me> | 2025-11-15 23:16:45 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bsima.me> | 2025-11-15 23:16:45 -0500 |
| commit | 79e9158793e65b984494c12d02277a1c8790c484 (patch) | |
| tree | ff3a86d68b0829bdbca4fc01f433918c14be5280 /Biz/PodcastItLater | |
| parent | a4f7427540840d31195ad37d7c68955ec7a36584 (diff) | |
Add public feed routes and update home page
- Add /public route showing public episodes - Add /public.rss RSS
feed for public episodes - Update home page to show public feed when
not logged in - Use user_episodes junction table instead of user_id
filtering - All tests passing
Diffstat (limited to 'Biz/PodcastItLater')
| -rw-r--r-- | Biz/PodcastItLater/Web.py | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/Biz/PodcastItLater/Web.py b/Biz/PodcastItLater/Web.py index 8caaf8c..14bca1b 100644 --- a/Biz/PodcastItLater/Web.py +++ b/Biz/PodcastItLater/Web.py @@ -807,10 +807,12 @@ def index(request: Request) -> HomePage: queue_items = Core.Database.get_user_queue_status( user_id, ) - episodes = Core.Database.get_user_recent_episodes( + episodes = Core.Database.get_user_episodes( user_id, - 10, ) + else: + # Show public feed when not logged in + episodes = Core.Database.get_public_episodes(10) return HomePage( queue_items=queue_items, @@ -820,6 +822,22 @@ def index(request: Request) -> HomePage: ) +@app.get("/public") +def public_feed(request: Request) -> HomePage: + """Display public feed page.""" + # Always show public episodes, whether user is logged in or not + episodes = Core.Database.get_public_episodes(50) + user_id = request.session.get("user_id") + user = Core.Database.get_user_by_id(user_id) if user_id else None + + return HomePage( + queue_items=[], + episodes=episodes, + user=user, + error=None, + ) + + def _handle_test_login(email: str, request: Request) -> Response: """Handle login in test mode.""" # Special handling for demo account @@ -1318,6 +1336,48 @@ def rss_feed(request: Request, token: str) -> Response: # noqa: ARG001 return Response(f"Error generating feed: {e}", status_code=500) +@app.get("/public.rss") +def public_rss_feed(request: Request) -> Response: # noqa: ARG001 + """Generate public RSS podcast feed.""" + try: + # Get public episodes + episodes = Core.Database.get_public_episodes(50) + + fg = FeedGenerator() + fg.title("PodcastItLater Public Feed") + fg.description("Curated articles converted to audio") + fg.author(name=RSS_CONFIG["author"]) + fg.language(RSS_CONFIG["language"]) + fg.link(href=f"{RSS_CONFIG['base_url']}/public.rss") + fg.id(f"{RSS_CONFIG['base_url']}/public.rss") + + for episode in episodes: + fe = fg.add_entry() + episode_sqid = encode_episode_id(episode["id"]) + fe.id(f"{RSS_CONFIG['base_url']}/episode/{episode_sqid}") + fe.title(episode["title"]) + fe.description(episode["title"]) + fe.enclosure( + episode["audio_url"], + str(episode.get("content_length", 0)), + "audio/mpeg", + ) + # SQLite timestamps don't have timezone info, so add UTC + created_at = datetime.fromisoformat(episode["created_at"]) + if created_at.tzinfo is None: + created_at = created_at.replace(tzinfo=timezone.utc) + fe.pubDate(created_at) + + rss_str = fg.rss_str(pretty=True) + return Response( + rss_str, + media_type="application/rss+xml; charset=utf-8", + ) + + except (ValueError, KeyError, AttributeError) as e: + return Response(f"Error generating feed: {e}", status_code=500) + + @app.get("/episode/{episode_id:int}") def episode_detail_legacy( request: Request, # noqa: ARG001 |
