add external Stremio catalogs#86
Conversation
Let users bring curated catalogs from external addons into librarySync so they can be filtered like built-in catalogs, including hiding watched items. Cache and refresh them on a recurring worker job so addon manifests stay fast and stable.
There was a problem hiding this comment.
Pull request overview
Adds support for configuring and serving external Stremio addon catalogs in librarySync, including periodic cached refresh and UI/API management, and integrates external catalogs into the published Stremio addon manifest and catalog serving logic.
Changes:
- Introduce DB models + migration for external catalogs and cached catalog items.
- Add API routes, manifest/catalog integration, and frontend UI/JS for discovery + CRUD + refresh.
- Add worker mode + scheduled job to periodically refresh cached external catalog items, plus tests for manifest/query behavior.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/tests/test_stremio_addon_catalogs.py | Extends manifest tests for external catalog ordering and adds SQL query assertions for watched-item filtering. |
| backend/src/librarysync/worker.py | Registers external_catalog_refresh worker mode and handler. |
| backend/src/librarysync/templates/stremio-addon.html | Adds “External catalogs” UI section for discovery and management. |
| backend/src/librarysync/static/page-stremio-addon.js | Implements external catalog discovery, CRUD, refresh actions, and rendering in the UI. |
| backend/src/librarysync/jobs/external_catalog_refresh.py | Adds scheduled job runner to refresh enabled external catalogs periodically. |
| backend/src/librarysync/db/models.py | Adds StremioExternalCatalog and StremioExternalCatalogItem models. |
| backend/src/librarysync/db/migrations/versions/d2b7c8f9a1e0_add_stremio_external_catalogs.py | Creates new tables + indexes/constraints for external catalogs and items. |
| backend/src/librarysync/core/external_catalog.py | Adds normalization, discovery, refresh, and media-item resolution for external catalogs via HTTP. |
| backend/src/librarysync/config.py | Adds settings for refresh interval hours and max cached items. |
| backend/src/librarysync/api/routes_stremio_addon_public.py | Adds external catalogs into manifest and serves external catalog queries with watched filtering and ordering. |
| backend/src/librarysync/api/routes_stremio_addon.py | Adds external catalog discovery/CRUD/refresh endpoints and slug uniqueness across custom/external catalogs. |
| .env.example | Documents new worker mode/concurrency and external catalog refresh settings. |
There was a problem hiding this comment.
Pull request overview
Adds support for external Stremio catalogs (sourced from manifests and supported list URLs) to librarySync’s Stremio addon feature, including discovery, CRUD, caching/refresh, and watched-item filtering so curated feeds can hide already-watched titles.
Changes:
- Introduces external catalog discovery + refresh pipeline (core logic, API endpoints, worker mode, and scheduled refresh job).
- Adds DB schema/models/migrations for external catalogs and cached catalog items.
- Updates Stremio addon UI + client JS to manage external catalogs and adds/extends tests around manifest and query behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Updates Ruff line-length configuration. |
| backend/tests/test_stremio_addon_catalogs.py | Adds tests for external catalogs, URL parsing, dedupe, and refresh error mapping. |
| backend/src/librarysync/worker.py | Registers new external_catalog_refresh worker mode. |
| backend/src/librarysync/templates/stremio-addon.html | Adds external catalogs section to the Stremio addon page. |
| backend/src/librarysync/static/page-stremio-addon.js | Implements UI discovery + CRUD + refresh workflows for external catalogs. |
| backend/src/librarysync/jobs/letterboxd_import.py | Exposes a helper to build list candidates for reuse. |
| backend/src/librarysync/jobs/external_catalog_refresh.py | Adds scheduled job loop to refresh enabled external catalogs. |
| backend/src/librarysync/db/models.py | Adds StremioExternalCatalog and StremioExternalCatalogItem models. |
| backend/src/librarysync/db/migrations/versions/d2b7c8f9a1e0_add_stremio_external_catalogs.py | Creates tables/indexes for external catalogs and items. |
| backend/src/librarysync/db/migrations/versions/e4f6a8b1c2d3_add_external_catalog_source_fields.py | Adds source_kind and source_provider fields. |
| backend/src/librarysync/core/watchlist_links.py | Adds parsing helpers for TMDB/TVDB/MDBList/IMDb link types. |
| backend/src/librarysync/core/external_catalog.py | Implements discovery, normalization/validation, refresh, and provider loaders. |
| backend/src/librarysync/config.py | Adds env-configurable refresh interval and max-items settings. |
| backend/src/librarysync/api/routes_stremio_addon_public.py | Adds external catalogs to manifest and serving logic (including watched filtering). |
| backend/src/librarysync/api/routes_stremio_addon.py | Adds external catalog API endpoints (discover/list/create/update/delete/refresh). |
| .env.example | Documents new worker mode + concurrency + refresh settings. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds support for “external Stremio catalogs” (sourced from other Stremio manifests and supported list URLs) to librarySync, including persistence, refresh workers, UI management, and manifest/catalog serving with optional hiding of already-watched items.
Changes:
- Adds DB models + migrations for external catalogs and cached catalog items, plus API endpoints for discovery/CRUD/refresh.
- Updates the public Stremio addon manifest + catalog serving to include external catalogs and to optionally filter out watched/completed items.
- Adds a periodic worker mode to refresh external catalogs, plus UI controls and tests for key behaviors.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Updates Ruff line-length configuration to 120. |
| backend/tests/test_stremio_addon_catalogs.py | Adds tests for external catalog manifest placement, query filtering, URL parsing, dedupe helpers, refresh error mapping, etc. |
| backend/src/librarysync/worker.py | Registers new external_catalog_refresh worker mode. |
| backend/src/librarysync/templates/stremio-addon.html | Adds “External catalogs” section and form to the addon UI. |
| backend/src/librarysync/static/page-stremio-addon.js | Implements external catalog discovery/create/update/delete/refresh UI flows. |
| backend/src/librarysync/jobs/letterboxd_import.py | Exposes a wrapper helper for building list candidates (reused by external catalogs). |
| backend/src/librarysync/jobs/external_catalog_refresh.py | New scheduled job processor to refresh enabled external catalogs periodically. |
| backend/src/librarysync/db/models.py | Adds StremioExternalCatalog and StremioExternalCatalogItem ORM models. |
| backend/src/librarysync/db/migrations/versions/d2b7c8f9a1e0_add_stremio_external_catalogs.py | Creates initial external catalogs + items tables. |
| backend/src/librarysync/db/migrations/versions/e4f6a8b1c2d3_add_external_catalog_source_fields.py | Adds source_kind / source_provider fields to external catalogs. |
| backend/src/librarysync/core/watchlist_links.py | Adds parsers for TMDB/TVDB/MDBList/IMDb URLs used during discovery. |
| backend/src/librarysync/core/external_catalog.py | New core implementation: discovery, normalization, refresh, list-provider fetchers, dedupe, SSRF-ish host checks, and media-item mapping. |
| backend/src/librarysync/config.py | Adds settings for external catalog refresh interval and max items. |
| backend/src/librarysync/api/routes_stremio_addon_public.py | Includes external catalogs in manifest and serves external catalog items (with watched filtering + ordering). |
| backend/src/librarysync/api/routes_stremio_addon.py | Adds discovery + CRUD + refresh endpoints for external catalogs and slug uniqueness across custom/external catalogs. |
| AGENTS.md | Updates documented line length to 120. |
| .vscode/settings.json | Updates editor rulers to 120. |
| .github/copilot-instructions.md | Updates documented line length to 120. |
| .env.example | Documents new worker mode + env vars for external catalog refresh settings. |
| if not filters.get("show_watched", False): | ||
| now_date = datetime.now(timezone.utc).date() | ||
| progress_subq = build_show_progress_subquery(user_id, now_date) | ||
| query = query.outerjoin(progress_subq, progress_subq.c.media_item_id == MediaItem.id) | ||
| directly_watched_exists = ( | ||
| select(WatchedItem.id) | ||
| .where( | ||
| WatchedItem.user_id == user_id, | ||
| WatchedItem.media_item_id == MediaItem.id, | ||
| ) | ||
| .exists() | ||
| ) | ||
| completed_show_clause = and_( | ||
| MediaItem.media_type.in_(["tv", "anime"]), | ||
| progress_subq.c.total_released > 0, | ||
| progress_subq.c.watched_count >= progress_subq.c.total_released, | ||
| ) | ||
| query = query.where( | ||
| or_( | ||
| StremioExternalCatalogItem.media_item_id.is_(None), | ||
| ~or_(directly_watched_exists, completed_show_clause), | ||
| ) | ||
| ) |
| payload = response.json() | ||
|
|
||
| if not isinstance(payload, list): | ||
| raise ValueError("MDBList list payload is invalid") |
Summary
Testing