diff --git a/app.py b/app.py index 8c41c00..1226907 100644 --- a/app.py +++ b/app.py @@ -1780,6 +1780,23 @@ class WatchlistStore: }, } + def homepage_summary(self): + with self.lock, self._connect() as conn: + rows = conn.execute( + "SELECT category, COUNT(*) AS count FROM watchlist GROUP BY category" + ).fetchall() + counts = {key: 0 for key in WATCHLIST_CATEGORY_CHOICES} + for row in rows: + counts[normalize_watchlist_category(row["category"])] = int(row["count"] or 0) + total = sum(counts.values()) + return { + "watchlist": counts["watching"], + "planned": counts["planned"], + "finished": counts["finished"], + "dropped": counts["dropped"], + "total": total, + } + def get(self, show_id): with self.lock, self._connect() as conn: row = conn.execute("SELECT * FROM watchlist WHERE show_id = ?", (str(show_id).strip(),)).fetchone() @@ -2407,6 +2424,11 @@ def get_watchlist(page=1, per_page=30, category=None): return WATCHLIST.list(page=page, per_page=per_page, category=category) +def get_watchlist_homepage_summary(): + ensure_runtime() + return WATCHLIST.homepage_summary() + + def update_watchlist_status(show_id, _mode=None): ensure_runtime() item = WATCHLIST.queue_refresh(show_id, source="manual") @@ -2857,6 +2879,7 @@ Handler = build_handler_class( ensure_runtime=ensure_runtime, episode_list=episode_list, get_config_snapshot=get_config_snapshot, + get_watchlist_homepage_summary=get_watchlist_homepage_summary, get_watchlist=get_watchlist, get_watchlist_refresh_status=get_watchlist_refresh_status, http_error=HttpError, diff --git a/http_handler.py b/http_handler.py index 09f5d21..2349544 100644 --- a/http_handler.py +++ b/http_handler.py @@ -52,6 +52,7 @@ class HandlerContext: ensure_runtime: object episode_list: object get_config_snapshot: object + get_watchlist_homepage_summary: object get_watchlist: object get_watchlist_refresh_status: object http_error: object @@ -602,6 +603,9 @@ class Handler(BaseHTTPRequestHandler): return debug_log("thumbnail.route.hit", show_id=show_id, resolved_path=path) self.file(path) + elif parsed.path == "/api/watchlist/homepage": + Handler._runtime(self) + self.json(Handler._context(self).get_watchlist_homepage_summary()) elif parsed.path in {"/api/watchlist", "/api/watchlist/get"}: Handler._runtime(self) params = parse_qs(parsed.query) diff --git a/test_app.py b/test_app.py index 7c86634..46ed758 100644 --- a/test_app.py +++ b/test_app.py @@ -3052,6 +3052,16 @@ class HandlerRouteTests(unittest.TestCase): self.assertEqual(handler.json_payload, payload) self.assertEqual(handler.json_status, HTTPStatus.OK) + def test_watchlist_homepage_route_returns_summary_counts(self): + handler = DummyHandler("/api/watchlist/homepage") + payload = {"watchlist": 1, "planned": 0, "finished": 2, "dropped": 0, "total": 3} + handler.handler_context = mock.Mock(get_watchlist_homepage_summary=mock.Mock(return_value=payload)) + + APP.Handler.do_GET(handler) + + self.assertEqual(handler.json_payload, payload) + self.assertEqual(handler.json_status, HTTPStatus.OK) + def test_update_all_post_returns_accepted_for_new_job(self): handler = DummyHandler("/api/watchlist/update-all", body=b"{}", content_length=2) payload = {"message": "Watchlist refresh started.", "job": {"id": "refresh-1"}, "created": True}