84dcf9e010
Jellyfin: get_user_id() returned the configured user_id verbatim, so a
username like "admin" hit /Users/admin/Views and got HTTP 400 ("The value
'admin' is not valid."). The index worker already had username->Id
resolution, but the live API paths (dashboard counts, media query) did not.
Route all user-scoped paths through the new JellyfinClient.resolve_user_id()
(exact Id match -> Name match -> first user), cached per service/credentials
in get_user_id() so repeated requests don't re-list users. The worker is
simplified to call the same method.
qBittorrent: _login() raised "qBittorrent login failed: " (empty) on a 200
with an empty body, which happens when base_url doesn't reach the qBittorrent
login handler (wrong URL/path or a reverse proxy misroute) — not a credentials
issue. Now accepts the SID cookie as a success signal (reverse proxies that
mangle the body), returns a clear "invalid username or password" for "Fails.",
and surfaces a diagnostic error (HTTP status + body + base_url/proxy hint) for
any other/empty body.
Tests: new tests/test_jellyfin_client.py (5) + 3 qBittorrent login tests.
Full backend suite (384) passes; ruff clean.
2.4 KiB
2.4 KiB
backend/src/media_library_viewer_api (index)
dir: backend/src/media_library_viewer_api
role
FastAPI backend providing authenticated APIs for remote media library inspection, SSH job execution, and observability via Jellyfin integration.
parent
index: backend/src/.pi-map.index.md map: backend/src/.pi-map.md
children
- backend/src/media_library_viewer_api/clients index: backend/src/media_library_viewer_api/clients/.pi-map.index.md map: backend/src/media_library_viewer_api/clients/.pi-map.md
- backend/src/media_library_viewer_api/domain index: backend/src/media_library_viewer_api/domain/.pi-map.index.md map: backend/src/media_library_viewer_api/domain/.pi-map.md
- backend/src/media_library_viewer_api/integrations index: backend/src/media_library_viewer_api/integrations/.pi-map.index.md map: backend/src/media_library_viewer_api/integrations/.pi-map.md
- backend/src/media_library_viewer_api/models index: backend/src/media_library_viewer_api/models/.pi-map.index.md map: backend/src/media_library_viewer_api/models/.pi-map.md
- backend/src/media_library_viewer_api/routers index: backend/src/media_library_viewer_api/routers/.pi-map.index.md map: backend/src/media_library_viewer_api/routers/.pi-map.md
- backend/src/media_library_viewer_api/services index: backend/src/media_library_viewer_api/services/.pi-map.index.md map: backend/src/media_library_viewer_api/services/.pi-map.md
- backend/src/media_library_viewer_api/widgets index: backend/src/media_library_viewer_api/widgets/.pi-map.index.md map: backend/src/media_library_viewer_api/widgets/.pi-map.md
- backend/src/media_library_viewer_api/workers index: backend/src/media_library_viewer_api/workers/.pi-map.index.md map: backend/src/media_library_viewer_api/workers/.pi-map.md
files
- __init__.py
- auth.py
- config.py
- dependencies.py
- jobs.py
- logging_utils.py
- main.py
- observability.py
- path_utils.py
- utils.py
- version.py
links
index: backend/src/media_library_viewer_api/.pi-map.index.md map: backend/src/media_library_viewer_api/.pi-map.md
workflows
- change media_library_viewer_api behavior read: __init__.py, auth.py, config.py
- change media_library_viewer_api config read: config.py
- explore media_library_viewer_api subdirectories index: backend/src/media_library_viewer_api/clients/.pi-map.index.md, backend/src/media_library_viewer_api/domain/.pi-map.index.md, backend/src/media_library_viewer_api/integrations/.pi-map.index.md