From 9b4afe3f7ab98f42194d12cae430b0f7345c4644 Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 15 Nov 2025 19:11:45 -0500 Subject: Add individual episode pages with sharing and media player - Create new Episode.py module with episode-specific components - EpisodePlayer: HTML5 audio player - ShareButton: Clipboard copy with Bootstrap input-group pattern - SignupBanner: Promotional banner for non-authenticated users - EpisodeDetailPage: Full page layout - Update Web.py to add /episode/ route (public, no auth required) - Make episode titles clickable in EpisodeList component - Add Database.get_episode_by_id() method for efficient queries - Update RSS feed and share buttons to use Bootstrap input-group pattern - Add comprehensive test suite for episode detail pages All episode pages are publicly accessible and include: - Media player to listen to episodes - Share button with URL copying - Links to original articles - Creator attribution banner for non-logged-in users Amp-Thread-ID: https://ampcode.com/threads/T-cc5d29f0-454e-4864-8d7e-1ad69a42afa9 Co-authored-by: Amp --- Biz/PodcastItLater/Core.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'Biz/PodcastItLater/Core.py') diff --git a/Biz/PodcastItLater/Core.py b/Biz/PodcastItLater/Core.py index f32e81b..9e3f830 100644 --- a/Biz/PodcastItLater/Core.py +++ b/Biz/PodcastItLater/Core.py @@ -322,6 +322,23 @@ class Database: # noqa: PLR0904 rows = cursor.fetchall() return [dict(row) for row in rows] + @staticmethod + def get_episode_by_id(episode_id: int) -> dict[str, Any] | None: + """Fetch single episode by ID.""" + with Database.get_connection() as conn: + cursor = conn.cursor() + cursor.execute( + """ + SELECT id, title, audio_url, duration, created_at, + content_length, author, original_url, user_id + FROM episodes + WHERE id = ? + """, + (episode_id,), + ) + row = cursor.fetchone() + return dict(row) if row is not None else None + @staticmethod def get_all_episodes( user_id: int | None = None, -- cgit v1.2.3