diff options
Diffstat (limited to 'Biz')
| -rw-r--r-- | Biz/PodcastItLater/Web.py | 66 |
1 files changed, 63 insertions, 3 deletions
diff --git a/Biz/PodcastItLater/Web.py b/Biz/PodcastItLater/Web.py index a4c3c16..ee63b60 100644 --- a/Biz/PodcastItLater/Web.py +++ b/Biz/PodcastItLater/Web.py @@ -79,6 +79,36 @@ RSS_CONFIG = { } +def format_duration(seconds: int | None) -> str: + """Format duration from seconds to human-readable format. + + Examples: + 300 -> "5m" + 3840 -> "1h 4m" + 11520 -> "3h 12m" + """ + if seconds is None or seconds <= 0: + return "Unknown" + + # Constants for time conversion + seconds_per_minute = 60 + minutes_per_hour = 60 + + # Round up to nearest minute + minutes = (seconds + seconds_per_minute - 1) // seconds_per_minute + + if minutes < minutes_per_hour: + return f"{minutes}m" + + hours = minutes // minutes_per_hour + remaining_minutes = minutes % minutes_per_hour + + if remaining_minutes == 0: + return f"{hours}h" + + return f"{hours}h {remaining_minutes}m" + + def extract_og_metadata(url: str) -> tuple[str | None, str | None]: """Extract Open Graph title and author from URL. @@ -409,9 +439,7 @@ class EpisodeList(Component[AnyChildren, EpisodeListAttrs]): episode_items = [] for episode in episodes: - duration_str = ( - f"{episode['duration']}s" if episode["duration"] else "Unknown" - ) + duration_str = format_duration(episode.get("duration")) episode_items.append( html.div( html.h4(episode["title"]), @@ -970,6 +998,37 @@ class BaseWebTest(Test.TestCase): Core.Database.teardown() +class TestDurationFormatting(Test.TestCase): + """Test duration formatting functionality.""" + + def test_format_duration_minutes_only(self) -> None: + """Test formatting durations less than an hour.""" + self.assertEqual(format_duration(60), "1m") + self.assertEqual(format_duration(240), "4m") + self.assertEqual(format_duration(300), "5m") + self.assertEqual(format_duration(3599), "60m") + + def test_format_duration_hours_and_minutes(self) -> None: + """Test formatting durations with hours and minutes.""" + self.assertEqual(format_duration(3600), "1h") + self.assertEqual(format_duration(3840), "1h 4m") + self.assertEqual(format_duration(11520), "3h 12m") + self.assertEqual(format_duration(7320), "2h 2m") + + def test_format_duration_round_up(self) -> None: + """Test that seconds are rounded up to nearest minute.""" + self.assertEqual(format_duration(61), "2m") + self.assertEqual(format_duration(119), "2m") + self.assertEqual(format_duration(121), "3m") + self.assertEqual(format_duration(3601), "1h 1m") + + def test_format_duration_edge_cases(self) -> None: + """Test edge cases for duration formatting.""" + self.assertEqual(format_duration(None), "Unknown") + self.assertEqual(format_duration(0), "Unknown") + self.assertEqual(format_duration(-100), "Unknown") + + class TestAuthentication(BaseWebTest): """Test authentication functionality.""" @@ -1509,6 +1568,7 @@ def test() -> None: Test.run( App.Area.Test, [ + TestDurationFormatting, TestAuthentication, TestArticleSubmission, TestRSSFeed, |
