collapsarr 0.1.3__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- collapsarr-0.2.0/.env.example +49 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/Dockerfile +4 -2
- {collapsarr-0.1.3 → collapsarr-0.2.0}/PKG-INFO +82 -28
- collapsarr-0.2.0/README.md +244 -0
- collapsarr-0.2.0/collapsarr/auth/__init__.py +20 -0
- collapsarr-0.2.0/collapsarr/auth/enforcement.py +245 -0
- collapsarr-0.2.0/collapsarr/auth/routes.py +220 -0
- collapsarr-0.2.0/collapsarr/auth/session.py +186 -0
- collapsarr-0.2.0/collapsarr/config.py +204 -0
- collapsarr-0.2.0/collapsarr/database.py +131 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/main.py +21 -3
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/settings/__init__.py +16 -2
- collapsarr-0.2.0/collapsarr/settings/env_seed.py +59 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/settings/models.py +68 -3
- collapsarr-0.2.0/collapsarr/settings/passwords.py +100 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/settings/routes.py +33 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/settings/service.py +69 -6
- collapsarr-0.2.0/frontend/dist/assets/index-CuYlNmcT.css +1 -0
- collapsarr-0.2.0/frontend/dist/assets/index-Dv5U12vj.js +68 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/dist/index.html +2 -2
- collapsarr-0.2.0/frontend/src/api/auth.ts +108 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/client.ts +42 -1
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/AppShell.tsx +6 -0
- collapsarr-0.2.0/frontend/src/components/OnboardingPanel.tsx +106 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/Sidebar.tsx +25 -1
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/settings/GeneralSection.tsx +190 -1
- collapsarr-0.2.0/frontend/src/pages/LoginPage.tsx +114 -0
- collapsarr-0.2.0/frontend/src/pages/SetupPage.tsx +114 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/routes/router.tsx +8 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/styles/global.css +103 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/apiClient.test.ts +67 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/fileDetailPage.test.tsx +2 -0
- collapsarr-0.2.0/frontend/src/test/loginPage.test.tsx +107 -0
- collapsarr-0.2.0/frontend/src/test/onboardingPanel.test.tsx +131 -0
- collapsarr-0.2.0/frontend/src/test/settingsGeneral.test.tsx +291 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/settingsPage.test.tsx +2 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/settingsTargets.test.tsx +2 -0
- collapsarr-0.2.0/frontend/src/test/setupPage.test.tsx +88 -0
- collapsarr-0.2.0/frontend/src/test/sidebarLogout.test.tsx +41 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/settings.ts +24 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/pyproject.toml +3 -1
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_routes.py +2 -1
- collapsarr-0.2.0/tests/test_auth.py +607 -0
- collapsarr-0.2.0/tests/test_config.py +174 -0
- collapsarr-0.2.0/tests/test_database.py +230 -0
- collapsarr-0.2.0/tests/test_env_seed.py +218 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_jobs_routes.py +7 -4
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_notify_routes.py +5 -2
- collapsarr-0.2.0/tests/test_passwords.py +66 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_settings_routes.py +33 -2
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_settings_service.py +207 -2
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_wanted_routes.py +3 -1
- collapsarr-0.1.3/.env.example +0 -16
- collapsarr-0.1.3/README.md +0 -192
- collapsarr-0.1.3/collapsarr/auth.py +0 -83
- collapsarr-0.1.3/collapsarr/config.py +0 -95
- collapsarr-0.1.3/collapsarr/database.py +0 -82
- collapsarr-0.1.3/frontend/dist/assets/index-Dfozi1oM.js +0 -68
- collapsarr-0.1.3/frontend/dist/assets/index-J2qCuzXj.css +0 -1
- collapsarr-0.1.3/frontend/src/test/settingsGeneral.test.tsx +0 -145
- collapsarr-0.1.3/tests/test_auth.py +0 -53
- collapsarr-0.1.3/tests/test_config.py +0 -51
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.dockerignore +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.gitattributes +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.github/brand/icon-512.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.github/brand/social-preview.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.github/brand/social-preview.svg +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.github/workflows/release.yml +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/.gitignore +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/LICENSE +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/__main__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/client.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/files.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/models.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/routes.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/service.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/arr/webhooks.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/apply.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/pipeline.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/probe.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/remux.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/downmix/targets.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/frontend.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/health.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/failure_notify.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/history.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/models.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/queue.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/routes.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/jobs/scheduler.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/media/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/media/models.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/media/routes.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/media/service.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/notify/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/notify/dispatch.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/notify/models.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/notify/routes.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/collapsarr/notify/service.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/docker-entrypoint.sh +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/README.md +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/dist/apple-touch-icon.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/dist/favicon-32.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/dist/favicon.svg +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/eslint.config.js +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/index.html +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/package-lock.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/package.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/public/apple-touch-icon.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/public/favicon-32.png +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/public/favicon.svg +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/activity.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/health.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/instances.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/notifiers.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/settings.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/api/wanted.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/HealthBanner.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/PlaceholderView.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/icons.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/settings/ConnectSection.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/settings/InstancesSection.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/settings/PathMappingsPanel.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/components/settings/TargetsSection.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/main.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/pages/ActivityPage.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/pages/FileDetailPage.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/pages/SettingsPage.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/pages/WantedPage.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/routes/nav.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/styles/theme.css +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/activityPage.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/appShell.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/healthBanner.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/settingsConnect.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/settingsInstances.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/setup.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/test/wantedPage.test.tsx +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/activity.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/health.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/instances.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/notifiers.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/types/wanted.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/src/vite-env.d.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/tsconfig.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/frontend/vite.config.ts +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/hatch_build.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/__init__.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/conftest.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/radarr_movie_list.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/radarr_status_ok.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/radarr_webhook_on_import.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/radarr_webhook_on_upgrade.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_episodefiles_series1.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_series_list.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_status_ok.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_webhook_on_import.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_webhook_on_upgrade.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/sonarr_webhook_test.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/arr/unauthorized.json +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/multi_lang.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/stereo_eng.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/surround_51.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/surround_71.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/untagged_language.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/fixtures/downmix/video_audio_subs.mkv +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_client.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_files.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_models.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_service.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_arr_webhooks.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_downmix_apply.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_downmix_pipeline.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_downmix_probe.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_downmix_remux.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_downmix_targets.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_frontend.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_health.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_health_check.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_jobs_failure_notify.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_jobs_history.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_jobs_queue.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_jobs_scheduler.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_main.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_media_service.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_notify_dispatch.py +0 -0
- {collapsarr-0.1.3 → collapsarr-0.2.0}/tests/test_notify_service.py +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Collapsarr configuration.
|
|
2
|
+
# Copy to `.env` and adjust as needed. All variables are optional — the values
|
|
3
|
+
# below are the built-in defaults. Environment variables take precedence.
|
|
4
|
+
#
|
|
5
|
+
# On a bare-metal/PyPI install, none of these need to be set: Collapsarr picks
|
|
6
|
+
# a writable, OS-appropriate data directory automatically (see
|
|
7
|
+
# COLLAPSARR_DATA_DIR below). The Docker image sets COLLAPSARR_DATA_DIR itself
|
|
8
|
+
# to point at the /config volume.
|
|
9
|
+
|
|
10
|
+
# Root directory for application data (the SQLite database today; logs and
|
|
11
|
+
# backups later). Created automatically if it doesn't exist. Defaults to the
|
|
12
|
+
# OS user-data directory, e.g. ~/.local/share/collapsarr on Linux,
|
|
13
|
+
# ~/Library/Application Support/collapsarr on macOS,
|
|
14
|
+
# %LOCALAPPDATA%\collapsarr on Windows.
|
|
15
|
+
# COLLAPSARR_DATA_DIR=/config
|
|
16
|
+
|
|
17
|
+
# Filesystem path to the SQLite database file. Defaults to
|
|
18
|
+
# <COLLAPSARR_DATA_DIR>/collapsarr.db; set this to override that location
|
|
19
|
+
# directly.
|
|
20
|
+
# COLLAPSARR_DATABASE_PATH=/config/collapsarr.db
|
|
21
|
+
|
|
22
|
+
# Full SQLAlchemy database URL. When set, overrides COLLAPSARR_DATABASE_PATH.
|
|
23
|
+
# COLLAPSARR_DATABASE_URL=sqlite:////config/collapsarr.db
|
|
24
|
+
|
|
25
|
+
# API server bind address and port.
|
|
26
|
+
COLLAPSARR_HOST=0.0.0.0
|
|
27
|
+
COLLAPSARR_PORT=8282
|
|
28
|
+
|
|
29
|
+
# Log level (DEBUG, INFO, WARNING, ERROR).
|
|
30
|
+
COLLAPSARR_LOG_LEVEL=INFO
|
|
31
|
+
|
|
32
|
+
# First-boot credential seed for headless/declarative deploys (Docker,
|
|
33
|
+
# automation): set BOTH together and a fresh install is seeded with this
|
|
34
|
+
# credential on first boot -- hashed before it's persisted, never stored or
|
|
35
|
+
# logged in plaintext -- and skips the interactive /setup page entirely.
|
|
36
|
+
# One-shot: this never overwrites a credential that already exists, even if
|
|
37
|
+
# left set on a later boot. This is also the supported password-recovery/
|
|
38
|
+
# lockout escape hatch, but only for a FRESH or already-locked-out install
|
|
39
|
+
# with no credential configured yet -- it does not help recover a forgotten
|
|
40
|
+
# password once a credential is already set (that takes clearing the
|
|
41
|
+
# existing one directly, e.g. in the database).
|
|
42
|
+
# COLLAPSARR_AUTH_USERNAME=admin
|
|
43
|
+
# COLLAPSARR_AUTH_PASSWORD=change-me
|
|
44
|
+
|
|
45
|
+
# Optional, only applied when the credential above is actually seeded.
|
|
46
|
+
# COLLAPSARR_AUTH_METHOD: forms (default) | basic
|
|
47
|
+
# COLLAPSARR_AUTH_REQUIRED: local_bypass (default) | enabled
|
|
48
|
+
# COLLAPSARR_AUTH_METHOD=forms
|
|
49
|
+
# COLLAPSARR_AUTH_REQUIRED=local_bypass
|
|
@@ -65,10 +65,12 @@ COPY docker-entrypoint.sh /docker-entrypoint.sh
|
|
|
65
65
|
RUN chmod +x /docker-entrypoint.sh
|
|
66
66
|
|
|
67
67
|
# Runtime configuration. COLLAPSARR_* mirror the app defaults (collapsarr/config.py);
|
|
68
|
-
# PUID/PGID are consumed by the entrypoint.
|
|
68
|
+
# PUID/PGID are consumed by the entrypoint. COLLAPSARR_DATA_DIR points at the
|
|
69
|
+
# /config volume; database_path derives to /config/collapsarr.db (COL-46), so
|
|
70
|
+
# existing /config volumes keep landing the DB at the same path on upgrade.
|
|
69
71
|
ENV COLLAPSARR_HOST=0.0.0.0 \
|
|
70
72
|
COLLAPSARR_PORT=8282 \
|
|
71
|
-
|
|
73
|
+
COLLAPSARR_DATA_DIR=/config \
|
|
72
74
|
PUID=1000 \
|
|
73
75
|
PGID=1000
|
|
74
76
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: collapsarr
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: An *arr-family companion app that adds downmixed (stereo/2.1/5.1) audio tracks to media missing them, via FFmpeg.
|
|
5
5
|
Project-URL: Homepage, https://github.com/JovinJovinsson/Collapsarr
|
|
6
6
|
Project-URL: Repository, https://github.com/JovinJovinsson/Collapsarr
|
|
@@ -14,6 +14,8 @@ Classifier: Topic :: Multimedia :: Sound/Audio
|
|
|
14
14
|
Requires-Python: >=3.12
|
|
15
15
|
Requires-Dist: fastapi>=0.110
|
|
16
16
|
Requires-Dist: httpx>=0.27
|
|
17
|
+
Requires-Dist: itsdangerous>=2.0
|
|
18
|
+
Requires-Dist: platformdirs>=4.0
|
|
17
19
|
Requires-Dist: pydantic-settings>=2.2
|
|
18
20
|
Requires-Dist: pydantic>=2.6
|
|
19
21
|
Requires-Dist: sqlalchemy>=2.0
|
|
@@ -30,28 +32,17 @@ Description-Content-Type: text/markdown
|
|
|
30
32
|
|
|
31
33
|
**Never get stuck without a downmix again.**
|
|
32
34
|
|
|
33
|
-
<!--
|
|
34
|
-
Stub row: static "pending" badges, deliberately not pointed at real
|
|
35
|
-
endpoints yet. Swap for live dynamic badges once COL-8 (Packaging &
|
|
36
|
-
Release) ships a release.yml workflow and the DockerHub repo is live:
|
|
37
|
-
CI -> https://github.com/JovinJovinsson/Collapsarr/actions/workflows/release.yml/badge.svg
|
|
38
|
-
Docker -> https://img.shields.io/docker/pulls/odxnsson/collapsarr
|
|
39
|
-
Release -> https://img.shields.io/github/v/release/JovinJovinsson/Collapsarr
|
|
40
|
-
-->
|
|
41
35
|
[](LICENSE)
|
|
42
|
-
[](https://github.com/JovinJovinsson/Collapsarr/actions/workflows/release.yml)
|
|
37
|
+
[](https://hub.docker.com/r/odxnsson/collapsarr)
|
|
38
|
+
[](https://pypi.org/project/collapsarr/)
|
|
39
|
+
[](https://github.com/JovinJovinsson/Collapsarr/releases)
|
|
45
40
|
|
|
46
41
|
Collapsarr is a companion application for Sonarr and Radarr. It watches your
|
|
47
42
|
library for media missing a lower-channel-count audio track — a 7.1 release
|
|
48
43
|
with no stereo fallback, a 5.1 file your soundbar can't decode — and adds one
|
|
49
44
|
automatically via FFmpeg, without touching the track that's already there.
|
|
50
45
|
|
|
51
|
-
> **Status:** core backend and Web UI are built; packaging (PyPI + Docker) is
|
|
52
|
-
> in progress. Until that ships, run from source — see
|
|
53
|
-
> [Development](#development) below.
|
|
54
|
-
|
|
55
46
|
## Why
|
|
56
47
|
|
|
57
48
|
- **No upmixing, ever.** Collapsarr only adds tracks the source can actually
|
|
@@ -84,11 +75,7 @@ automatically via FFmpeg, without touching the track that's already there.
|
|
|
84
75
|
|
|
85
76
|
## Quick start
|
|
86
77
|
|
|
87
|
-
|
|
88
|
-
Drafted now, finalized once COL-8 (Packaging & Release) ships: this image
|
|
89
|
-
isn't published to Docker Hub yet, so this is the target shape, not a
|
|
90
|
-
working pull today.
|
|
91
|
-
-->
|
|
78
|
+
**Docker (recommended):**
|
|
92
79
|
|
|
93
80
|
```yaml
|
|
94
81
|
services:
|
|
@@ -106,11 +93,30 @@ services:
|
|
|
106
93
|
restart: unless-stopped
|
|
107
94
|
```
|
|
108
95
|
|
|
109
|
-
Then open `http://localhost:8282
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
96
|
+
Then open `http://localhost:8282` — you'll land on a one-time credential setup
|
|
97
|
+
page (see [Authentication](#authentication) for how login is enforced,
|
|
98
|
+
including the caveat if you're putting Collapsarr behind a reverse proxy).
|
|
99
|
+
`restart: unless-stopped` above means the container comes back automatically
|
|
100
|
+
whenever it stops unexpectedly or the Docker daemon restarts (e.g. after a
|
|
101
|
+
host reboot) — see [Running on startup](#running-on-startup) if you need it
|
|
102
|
+
to survive a reboot on a bare-metal/PyPI install instead.
|
|
103
|
+
|
|
104
|
+
**PyPI (bare-metal):**
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
pipx install collapsarr
|
|
108
|
+
collapsarr
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
No flags, no config file needed — Collapsarr stores its SQLite database
|
|
112
|
+
under your platform's standard per-user data directory by default (e.g.
|
|
113
|
+
`~/.local/share/collapsarr/collapsarr.db` on Linux; native per-OS locations
|
|
114
|
+
on macOS/Windows), creating it automatically if it doesn't exist. Set
|
|
115
|
+
`COLLAPSARR_DATA_DIR` if you'd rather it live somewhere else — see
|
|
116
|
+
[Configuration](#configuration). Requires FFmpeg on `PATH` — see
|
|
117
|
+
[Requirements](#requirements) below. Open `http://localhost:8282`; see
|
|
118
|
+
[Configuration](#configuration) for the full list of environment variables,
|
|
119
|
+
and [Running on startup](#running-on-startup) for a systemd unit.
|
|
114
120
|
|
|
115
121
|
## Requirements
|
|
116
122
|
|
|
@@ -129,6 +135,49 @@ on a bare-metal/PyPI install instead.
|
|
|
129
135
|
|
|
130
136
|
Verify with `ffmpeg -version`. Official builds/source: [ffmpeg.org/download.html](https://ffmpeg.org/download.html).
|
|
131
137
|
|
|
138
|
+
## Authentication
|
|
139
|
+
|
|
140
|
+
Collapsarr requires a one-time credential setup (`/setup`, first run) and,
|
|
141
|
+
after that, logging in (`/login`) before the UI/API is usable — *except* from
|
|
142
|
+
a caller Collapsarr considers "local". The **Login requirement** setting
|
|
143
|
+
(Settings → General, `auth_required` in the API) controls this:
|
|
144
|
+
|
|
145
|
+
| Mode | Behaviour |
|
|
146
|
+
| --- | --- |
|
|
147
|
+
| **Disabled for local addresses** (`local_bypass`, default) | A caller connecting from a loopback (`127.0.0.1`/`::1`) or private-range (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, etc.) address reaches the UI and API with no setup and no login. Anyone connecting from a routable/public address still has to authenticate normally. |
|
|
148
|
+
| **Always required** (`enabled`) | Every caller is challenged, regardless of address. |
|
|
149
|
+
|
|
150
|
+
**Reverse-proxy limitation:** local-address classification looks only at the
|
|
151
|
+
*direct* TCP connection Collapsarr accepted — never an `X-Forwarded-For` (or
|
|
152
|
+
similar) header, since that's supplied by the client and trivially spoofable.
|
|
153
|
+
If Collapsarr sits behind a reverse proxy (nginx, Traefik, Cloudflare Tunnel,
|
|
154
|
+
etc.), every request's direct peer is the proxy itself, which usually *is*
|
|
155
|
+
local — meaning **every** client, including ones out on the internet, would
|
|
156
|
+
be classified as local and skip authentication entirely. **If you run
|
|
157
|
+
Collapsarr behind a reverse proxy, set the Login requirement to "Always
|
|
158
|
+
required" (`auth_required=enabled`)** until a future release adds
|
|
159
|
+
trusted-proxy support (a stubbed-out capability today).
|
|
160
|
+
|
|
161
|
+
**Headless deploys — seeding a credential without the setup page:** a
|
|
162
|
+
declarative/automated deploy (Docker Compose, Ansible, etc.) has no human
|
|
163
|
+
available to click through `/setup`. Set `COLLAPSARR_AUTH_USERNAME` and
|
|
164
|
+
`COLLAPSARR_AUTH_PASSWORD` (together — see
|
|
165
|
+
[Configuration](#configuration)) and a fresh install seeds that credential on
|
|
166
|
+
first boot instead — hashed before it's persisted, never stored or logged in
|
|
167
|
+
plaintext — and comes up already past the setup gate. `COLLAPSARR_AUTH_METHOD`
|
|
168
|
+
and `COLLAPSARR_AUTH_REQUIRED` are honoured at the same time if set, otherwise
|
|
169
|
+
the seeded credential gets the same defaults `/setup` would (`forms`,
|
|
170
|
+
`local_bypass`).
|
|
171
|
+
|
|
172
|
+
This doubles as the supported password-recovery/lockout escape hatch, but
|
|
173
|
+
**only for a fresh or already-locked-out install with no credential
|
|
174
|
+
configured yet** — seeding runs once and never overwrites a credential that
|
|
175
|
+
already exists, even if the environment variables are still set on a later
|
|
176
|
+
boot. It does **not** help recover a *forgotten* password once a credential
|
|
177
|
+
is already set; that requires clearing the existing `auth_username`/
|
|
178
|
+
`auth_password_hash` first (e.g. directly in the database) so the instance
|
|
179
|
+
has no credential again, at which point re-seeding (or `/setup`) applies.
|
|
180
|
+
|
|
132
181
|
## Development
|
|
133
182
|
|
|
134
183
|
```bash
|
|
@@ -157,11 +206,16 @@ directory. See [`.env.example`](.env.example).
|
|
|
157
206
|
|
|
158
207
|
| Variable | Default | Description |
|
|
159
208
|
| --- | --- | --- |
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
209
|
+
| `COLLAPSARR_DATA_DIR` | *(OS user-data dir)* | Root directory for application data — the SQLite database today, logs/backups later. Defaults to `platformdirs.user_data_dir("collapsarr")` (e.g. `~/.local/share/collapsarr` on Linux). Created automatically if missing. The Docker image sets this to `/config` (its mounted volume) — see [Quick start](#quick-start). |
|
|
210
|
+
| `COLLAPSARR_DATABASE_PATH` | *(derived from `COLLAPSARR_DATA_DIR`)* | SQLite database file path. Set this to override the location directly, independent of `COLLAPSARR_DATA_DIR`. |
|
|
211
|
+
| `COLLAPSARR_DATABASE_URL` | *(derived from path)* | Full SQLAlchemy URL override — takes precedence over both of the above. |
|
|
162
212
|
| `COLLAPSARR_HOST` | `0.0.0.0` | API server bind address. |
|
|
163
213
|
| `COLLAPSARR_PORT` | `8282` | API server bind port. |
|
|
164
214
|
| `COLLAPSARR_LOG_LEVEL` | `INFO` | Log level. |
|
|
215
|
+
| `COLLAPSARR_AUTH_USERNAME` | *(unset)* | First-boot credential seed: UI username. Set together with `COLLAPSARR_AUTH_PASSWORD` — see [Authentication](#authentication). |
|
|
216
|
+
| `COLLAPSARR_AUTH_PASSWORD` | *(unset)* | First-boot credential seed: UI password. Hashed before being persisted; never stored or logged in plaintext. |
|
|
217
|
+
| `COLLAPSARR_AUTH_METHOD` | *(unset — `forms`)* | Optional, only applied when the seed credential above is actually seeded: `forms` or `basic`. |
|
|
218
|
+
| `COLLAPSARR_AUTH_REQUIRED` | *(unset — `local_bypass`)* | Optional, only applied when the seed credential above is actually seeded: `enabled` or `local_bypass`. |
|
|
165
219
|
|
|
166
220
|
## Running on startup
|
|
167
221
|
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
<img src="frontend/public/favicon.svg" width="72" align="right" alt="Collapsarr logo" />
|
|
2
|
+
|
|
3
|
+
# Collapsarr
|
|
4
|
+
|
|
5
|
+
**Never get stuck without a downmix again.**
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://github.com/JovinJovinsson/Collapsarr/actions/workflows/release.yml)
|
|
9
|
+
[](https://hub.docker.com/r/odxnsson/collapsarr)
|
|
10
|
+
[](https://pypi.org/project/collapsarr/)
|
|
11
|
+
[](https://github.com/JovinJovinsson/Collapsarr/releases)
|
|
12
|
+
|
|
13
|
+
Collapsarr is a companion application for Sonarr and Radarr. It watches your
|
|
14
|
+
library for media missing a lower-channel-count audio track — a 7.1 release
|
|
15
|
+
with no stereo fallback, a 5.1 file your soundbar can't decode — and adds one
|
|
16
|
+
automatically via FFmpeg, without touching the track that's already there.
|
|
17
|
+
|
|
18
|
+
## Why
|
|
19
|
+
|
|
20
|
+
- **No upmixing, ever.** Collapsarr only adds tracks the source can actually
|
|
21
|
+
support (a stereo/2.1/5.1 downmix from a higher channel count) — it will
|
|
22
|
+
never fake a 5.1 track out of a stereo source.
|
|
23
|
+
- **Originals are never at risk.** The remux writes to a temp file, validates
|
|
24
|
+
duration and stream count, then atomically swaps it in. Any failure at any
|
|
25
|
+
stage leaves the original file completely untouched — no partial writes, no
|
|
26
|
+
orphaned backups.
|
|
27
|
+
- **Fits into the \*arr stack you already run.** Sonarr/Radarr integration
|
|
28
|
+
(webhooks + periodic scan), a dark UI in the same style as the rest of the
|
|
29
|
+
family, and a REST API following the same conventions.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Sonarr and Radarr integration — instance config, connectivity check, remote
|
|
34
|
+
path mapping, multiple concurrent instances
|
|
35
|
+
- Per-target, per-language detection that stacks additional targets without
|
|
36
|
+
duplicating what's already there
|
|
37
|
+
- FFmpeg remux: stream-copies existing tracks, encodes new audio (AAC for
|
|
38
|
+
Stereo, AC3 @ 448kbps for 2.1/5.1)
|
|
39
|
+
- Job queue with configurable concurrency — triggered by webhook, periodic
|
|
40
|
+
full-library scan, on-demand scan, or manual per-file trigger
|
|
41
|
+
- Full job history: status, timestamps, FFmpeg exit code, error text
|
|
42
|
+
- Web UI in the same dark theme as Sonarr/Radarr/Bazarr — Wanted view,
|
|
43
|
+
Activity/History, per-file detail view with a manual trigger
|
|
44
|
+
- Webhook + Discord notifications on job failure or app health issues (e.g.
|
|
45
|
+
FFmpeg missing)
|
|
46
|
+
- REST API with \*arr-convention auth (API key)
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
**Docker (recommended):**
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
services:
|
|
54
|
+
collapsarr:
|
|
55
|
+
image: odxnsson/collapsarr:latest
|
|
56
|
+
container_name: collapsarr
|
|
57
|
+
ports:
|
|
58
|
+
- "8282:8282"
|
|
59
|
+
volumes:
|
|
60
|
+
- ./config:/config
|
|
61
|
+
- /path/to/media:/media
|
|
62
|
+
environment:
|
|
63
|
+
- PUID=1000
|
|
64
|
+
- PGID=1000
|
|
65
|
+
restart: unless-stopped
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Then open `http://localhost:8282` — you'll land on a one-time credential setup
|
|
69
|
+
page (see [Authentication](#authentication) for how login is enforced,
|
|
70
|
+
including the caveat if you're putting Collapsarr behind a reverse proxy).
|
|
71
|
+
`restart: unless-stopped` above means the container comes back automatically
|
|
72
|
+
whenever it stops unexpectedly or the Docker daemon restarts (e.g. after a
|
|
73
|
+
host reboot) — see [Running on startup](#running-on-startup) if you need it
|
|
74
|
+
to survive a reboot on a bare-metal/PyPI install instead.
|
|
75
|
+
|
|
76
|
+
**PyPI (bare-metal):**
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pipx install collapsarr
|
|
80
|
+
collapsarr
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
No flags, no config file needed — Collapsarr stores its SQLite database
|
|
84
|
+
under your platform's standard per-user data directory by default (e.g.
|
|
85
|
+
`~/.local/share/collapsarr/collapsarr.db` on Linux; native per-OS locations
|
|
86
|
+
on macOS/Windows), creating it automatically if it doesn't exist. Set
|
|
87
|
+
`COLLAPSARR_DATA_DIR` if you'd rather it live somewhere else — see
|
|
88
|
+
[Configuration](#configuration). Requires FFmpeg on `PATH` — see
|
|
89
|
+
[Requirements](#requirements) below. Open `http://localhost:8282`; see
|
|
90
|
+
[Configuration](#configuration) for the full list of environment variables,
|
|
91
|
+
and [Running on startup](#running-on-startup) for a systemd unit.
|
|
92
|
+
|
|
93
|
+
## Requirements
|
|
94
|
+
|
|
95
|
+
- Python 3.12+
|
|
96
|
+
- FFmpeg — external system dependency, checked at startup and reported on the
|
|
97
|
+
health page if missing. Bundled in the Docker image; install it yourself
|
|
98
|
+
for a bare-metal/PyPI setup:
|
|
99
|
+
|
|
100
|
+
| OS | Command |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| Debian / Ubuntu | `sudo apt install ffmpeg` |
|
|
103
|
+
| Fedora | `sudo dnf install ffmpeg` |
|
|
104
|
+
| Arch | `sudo pacman -S ffmpeg` |
|
|
105
|
+
| macOS (Homebrew) | `brew install ffmpeg` |
|
|
106
|
+
| Windows (winget) | `winget install ffmpeg` |
|
|
107
|
+
|
|
108
|
+
Verify with `ffmpeg -version`. Official builds/source: [ffmpeg.org/download.html](https://ffmpeg.org/download.html).
|
|
109
|
+
|
|
110
|
+
## Authentication
|
|
111
|
+
|
|
112
|
+
Collapsarr requires a one-time credential setup (`/setup`, first run) and,
|
|
113
|
+
after that, logging in (`/login`) before the UI/API is usable — *except* from
|
|
114
|
+
a caller Collapsarr considers "local". The **Login requirement** setting
|
|
115
|
+
(Settings → General, `auth_required` in the API) controls this:
|
|
116
|
+
|
|
117
|
+
| Mode | Behaviour |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| **Disabled for local addresses** (`local_bypass`, default) | A caller connecting from a loopback (`127.0.0.1`/`::1`) or private-range (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, etc.) address reaches the UI and API with no setup and no login. Anyone connecting from a routable/public address still has to authenticate normally. |
|
|
120
|
+
| **Always required** (`enabled`) | Every caller is challenged, regardless of address. |
|
|
121
|
+
|
|
122
|
+
**Reverse-proxy limitation:** local-address classification looks only at the
|
|
123
|
+
*direct* TCP connection Collapsarr accepted — never an `X-Forwarded-For` (or
|
|
124
|
+
similar) header, since that's supplied by the client and trivially spoofable.
|
|
125
|
+
If Collapsarr sits behind a reverse proxy (nginx, Traefik, Cloudflare Tunnel,
|
|
126
|
+
etc.), every request's direct peer is the proxy itself, which usually *is*
|
|
127
|
+
local — meaning **every** client, including ones out on the internet, would
|
|
128
|
+
be classified as local and skip authentication entirely. **If you run
|
|
129
|
+
Collapsarr behind a reverse proxy, set the Login requirement to "Always
|
|
130
|
+
required" (`auth_required=enabled`)** until a future release adds
|
|
131
|
+
trusted-proxy support (a stubbed-out capability today).
|
|
132
|
+
|
|
133
|
+
**Headless deploys — seeding a credential without the setup page:** a
|
|
134
|
+
declarative/automated deploy (Docker Compose, Ansible, etc.) has no human
|
|
135
|
+
available to click through `/setup`. Set `COLLAPSARR_AUTH_USERNAME` and
|
|
136
|
+
`COLLAPSARR_AUTH_PASSWORD` (together — see
|
|
137
|
+
[Configuration](#configuration)) and a fresh install seeds that credential on
|
|
138
|
+
first boot instead — hashed before it's persisted, never stored or logged in
|
|
139
|
+
plaintext — and comes up already past the setup gate. `COLLAPSARR_AUTH_METHOD`
|
|
140
|
+
and `COLLAPSARR_AUTH_REQUIRED` are honoured at the same time if set, otherwise
|
|
141
|
+
the seeded credential gets the same defaults `/setup` would (`forms`,
|
|
142
|
+
`local_bypass`).
|
|
143
|
+
|
|
144
|
+
This doubles as the supported password-recovery/lockout escape hatch, but
|
|
145
|
+
**only for a fresh or already-locked-out install with no credential
|
|
146
|
+
configured yet** — seeding runs once and never overwrites a credential that
|
|
147
|
+
already exists, even if the environment variables are still set on a later
|
|
148
|
+
boot. It does **not** help recover a *forgotten* password once a credential
|
|
149
|
+
is already set; that requires clearing the existing `auth_username`/
|
|
150
|
+
`auth_password_hash` first (e.g. directly in the database) so the instance
|
|
151
|
+
has no credential again, at which point re-seeding (or `/setup`) applies.
|
|
152
|
+
|
|
153
|
+
## Development
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python -m venv .venv
|
|
157
|
+
source .venv/bin/activate
|
|
158
|
+
pip install -e ".[dev]"
|
|
159
|
+
|
|
160
|
+
# Run the checks
|
|
161
|
+
pytest
|
|
162
|
+
ruff check .
|
|
163
|
+
mypy
|
|
164
|
+
|
|
165
|
+
# Run the server (defaults to http://0.0.0.0:8282)
|
|
166
|
+
python -m collapsarr
|
|
167
|
+
# then: curl http://localhost:8282/health
|
|
168
|
+
# -> {"status":"ok","version":"...","warnings":[]}
|
|
169
|
+
# (or, if FFmpeg is missing: {"status":"degraded","version":"...",
|
|
170
|
+
# "warnings":[{"code":"ffmpeg_missing","message":"..."}]})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Configuration
|
|
174
|
+
|
|
175
|
+
All settings load from environment variables (prefixed `COLLAPSARR_`) with
|
|
176
|
+
sensible defaults, and an optional `.env` file is read from the working
|
|
177
|
+
directory. See [`.env.example`](.env.example).
|
|
178
|
+
|
|
179
|
+
| Variable | Default | Description |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| `COLLAPSARR_DATA_DIR` | *(OS user-data dir)* | Root directory for application data — the SQLite database today, logs/backups later. Defaults to `platformdirs.user_data_dir("collapsarr")` (e.g. `~/.local/share/collapsarr` on Linux). Created automatically if missing. The Docker image sets this to `/config` (its mounted volume) — see [Quick start](#quick-start). |
|
|
182
|
+
| `COLLAPSARR_DATABASE_PATH` | *(derived from `COLLAPSARR_DATA_DIR`)* | SQLite database file path. Set this to override the location directly, independent of `COLLAPSARR_DATA_DIR`. |
|
|
183
|
+
| `COLLAPSARR_DATABASE_URL` | *(derived from path)* | Full SQLAlchemy URL override — takes precedence over both of the above. |
|
|
184
|
+
| `COLLAPSARR_HOST` | `0.0.0.0` | API server bind address. |
|
|
185
|
+
| `COLLAPSARR_PORT` | `8282` | API server bind port. |
|
|
186
|
+
| `COLLAPSARR_LOG_LEVEL` | `INFO` | Log level. |
|
|
187
|
+
| `COLLAPSARR_AUTH_USERNAME` | *(unset)* | First-boot credential seed: UI username. Set together with `COLLAPSARR_AUTH_PASSWORD` — see [Authentication](#authentication). |
|
|
188
|
+
| `COLLAPSARR_AUTH_PASSWORD` | *(unset)* | First-boot credential seed: UI password. Hashed before being persisted; never stored or logged in plaintext. |
|
|
189
|
+
| `COLLAPSARR_AUTH_METHOD` | *(unset — `forms`)* | Optional, only applied when the seed credential above is actually seeded: `forms` or `basic`. |
|
|
190
|
+
| `COLLAPSARR_AUTH_REQUIRED` | *(unset — `local_bypass`)* | Optional, only applied when the seed credential above is actually seeded: `enabled` or `local_bypass`. |
|
|
191
|
+
|
|
192
|
+
## Running on startup
|
|
193
|
+
|
|
194
|
+
**Docker:** the `restart: unless-stopped` line in the [Quick start](#quick-start)
|
|
195
|
+
compose file already handles this — Docker restarts the container whenever it
|
|
196
|
+
stops unexpectedly or the Docker daemon itself restarts. On Linux this
|
|
197
|
+
happens automatically on boot, since `dockerd` runs as a systemd service
|
|
198
|
+
enabled by default (`systemctl is-enabled docker` to confirm). On
|
|
199
|
+
Docker Desktop (macOS/Windows), enable **Settings → General → Start Docker
|
|
200
|
+
Desktop when you log in** so the daemon — and in turn the container — comes
|
|
201
|
+
up after a reboot.
|
|
202
|
+
|
|
203
|
+
**Bare-metal / PyPI install:** run Collapsarr as a systemd service so it
|
|
204
|
+
starts on boot and restarts if it crashes. Create
|
|
205
|
+
`/etc/systemd/system/collapsarr.service`:
|
|
206
|
+
|
|
207
|
+
```ini
|
|
208
|
+
[Unit]
|
|
209
|
+
Description=Collapsarr
|
|
210
|
+
After=network.target
|
|
211
|
+
|
|
212
|
+
[Service]
|
|
213
|
+
Type=simple
|
|
214
|
+
User=collapsarr
|
|
215
|
+
Group=collapsarr
|
|
216
|
+
WorkingDirectory=/opt/collapsarr
|
|
217
|
+
EnvironmentFile=/opt/collapsarr/.env
|
|
218
|
+
ExecStart=/opt/collapsarr/.venv/bin/collapsarr
|
|
219
|
+
Restart=on-failure
|
|
220
|
+
RestartSec=5
|
|
221
|
+
|
|
222
|
+
[Install]
|
|
223
|
+
WantedBy=multi-user.target
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Adjust `User`/`Group`, `WorkingDirectory`, and the `.venv` path to match
|
|
227
|
+
where you installed it; `EnvironmentFile` should point at an `.env`
|
|
228
|
+
containing the `COLLAPSARR_*` variables from [Configuration](#configuration)
|
|
229
|
+
(see [`.env.example`](.env.example)). Then enable and start it:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
sudo systemctl daemon-reload
|
|
233
|
+
sudo systemctl enable --now collapsarr
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Check status/logs with `systemctl status collapsarr` and `journalctl -u collapsarr -f`.
|
|
237
|
+
|
|
238
|
+
## Docs
|
|
239
|
+
|
|
240
|
+
Fuller docs live on the [GitHub Wiki](https://github.com/JovinJovinsson/Collapsarr/wiki).
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
|
|
244
|
+
[GPLv3](LICENSE).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Authentication surface: first-run setup, Forms login, session enforcement.
|
|
2
|
+
|
|
3
|
+
The full auth model (COL-50): a single operator credential (COL-49) gates the
|
|
4
|
+
whole UI behind a signed-cookie session, while ``/api`` still accepts the
|
|
5
|
+
Sonarr/Radarr-style API key for webhooks and tooling. See the submodules:
|
|
6
|
+
|
|
7
|
+
* :mod:`~collapsarr.auth.session` -- the signed-cookie session middleware and
|
|
8
|
+
its login/logout helpers.
|
|
9
|
+
* :mod:`~collapsarr.auth.enforcement` -- the request-gating middleware that
|
|
10
|
+
supersedes the old opt-in ``api_key_middleware``.
|
|
11
|
+
* :mod:`~collapsarr.auth.routes` -- the ``/api/auth`` endpoints.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from .enforcement import enforce_auth_middleware
|
|
17
|
+
from .routes import router as auth_router
|
|
18
|
+
from .session import SessionMiddleware
|
|
19
|
+
|
|
20
|
+
__all__ = ["SessionMiddleware", "auth_router", "enforce_auth_middleware"]
|