Updated monochrome and votify

This commit is contained in:
2026-08-16 23:29:15 +02:00
parent d136ef26c5
commit 1319121a4f
7 changed files with 130 additions and 64 deletions
+40 -5
View File
@@ -2,7 +2,9 @@
## Overview
Votify is the primary Spotify download backend. It invokes the `votify-fix` CLI tool (a third-party Python package) as a subprocess, streams its output to the job log, and post-processes the resulting files.
Votify is the primary Spotify download backend. It invokes the `votify` CLI tool (a third-party Python package) as a subprocess, streams its output to the job log, and post-processes the resulting files.
Upstream is the official [glomatico/votify](https://github.com/glomatico/votify) project, installed from git in the Dockerfile. It previously used the `GladistonXD/votify-fix` fork; the fork's CLI flag names differ from upstream's, so `run_download()` was remapped when the swap was made (see [CLI flag mapping](#cli-flag-mapping)).
---
@@ -24,6 +26,8 @@ Votify is the primary Spotify download backend. It invokes the `votify-fix` CLI
Votify authenticates with Spotify using a `cookies.txt` file in Netscape format. This file must be uploaded by an admin via the Settings page before any downloads will succeed.
Upstream supports three session types (`--session-type`: `librespot`, `desktop`, `web`), defaulting to `librespot`. The app does not pass the flag, so the default applies — which is why the Dockerfile installs the `[librespot]` extra. Installing plain `votify` without the extra will fail at runtime under the default session type.
Path: `/config/cookies.txt` (configurable via `COOKIES_PATH` env var)
A Widevine device certificate (`device.wvd`) may also be required depending on the content. It is uploaded separately via Settings.
@@ -42,11 +46,40 @@ Path: `/config/device.wvd` (configurable via `WVD_PATH` env var)
| `save_cover` | bool | Save cover art as a separate image file |
| `save_playlist` | bool | Save playlist metadata file |
| `overwrite` | bool | Re-download if file already exists |
| `download_music_videos` | bool | Include music video downloads |
| `download_music_videos` | bool | Prefer video streams where available |
| `no_lrc` | bool | Skip LRC (lyrics) file generation |
| `save_lrc` | bool | Download *only* the synced-lyrics file |
| `video_format` | `mp4`, `webm` | Format for music videos |
| `cover_size` | `small`, `medium`, `large`, `extra-large` | Cover art resolution |
| `truncate` | int (optional) | Limit number of tracks to download |
| `truncate` | int (optional) | Max file/folder **name length** (not a track-count limit) |
These are the app-level option names sent to `POST /api/download`; they are stable and unchanged by the upstream swap. The CLI flags they translate into are not — see below.
Upstream also accepts `curl` for `--audio-download-mode` and the FLAC qualities `flac-flac`, `flac-mp4`, `flac-flac-24`, `flac-mp4-24` (premium accounts only). Neither is exposed in the UI; the values above are what the frontend offers.
---
## CLI Flag Mapping
`run_download()` builds the argv. Most flags were renamed between the old fork and upstream:
| App option | Old (`votify-fix`) flag | Current (official) flag |
|------------|------------------------|-------------------------|
| output dir | `--output-path` | `--output` |
| temp dir | `--temp-path` | `--temp` |
| `download_mode` | `--download-mode` | `--audio-download-mode` |
| `save_cover` | `--save-cover` | `--save-cover-file` |
| `save_playlist` | `--save-playlist` | `--save-playlist-file` |
| `download_music_videos` | `--download-music-videos` | `--prefer-video` |
| `save_lrc` | `--lrc-only` | `--synced-lyrics-only` |
| `no_lrc` | `--no-lrc` | `--no-synced-lyrics-file` |
| folder flattening | `--template-folder-{album,compilation,episode,music-video}` | `--album-folder-template`, `--compilation-folder-template`, `--podcast-folder-template`, `--no-album-folder-template` |
Unchanged: `--cookies-path`, `--wvd-path`, `--audio-quality`, `--video-format`, `--cover-size`, `--overwrite`, `--truncate`.
All four folder templates are set to `.` so downloads land flat in the job's output directory; `post_process_votify_files()` then imposes the final layout. Upstream has no music-video folder template — `--no-album-folder-template` (used for albumless tracks) took that slot.
`--no-config-file` is always passed so a stray `~/.votify/config.ini` cannot silently override these flags.
---
@@ -78,7 +111,7 @@ After the subprocess exits, `post_process_votify_files()` runs:
| Dependency | Purpose |
|------------|---------|
| `votify-fix` (GitHub: GladistonXD/votify-fix) | Spotify download CLI |
| `votify` (GitHub: glomatico/votify, `[librespot]` extra) | Spotify download CLI |
| `ffmpeg` | MP3 conversion |
| `aria2c` | Optional download manager |
| `yt-dlp` | Default download manager |
@@ -91,6 +124,8 @@ After the subprocess exits, `post_process_votify_files()` runs:
- Requires valid Spotify cookies (must be refreshed periodically when they expire).
- DRM-protected content requires a Widevine device certificate.
- Quality options are limited to what Votify and the Spotify API expose.
- Upstream warns that some users have had their Spotify accounts suspended for using it.
- **Interactive prompts can break jobs.** Upstream uses `inquirerpy` and will prompt on stdin for artist URLs (unless `--auto-media-option` is passed) and for `--video-format ask`. The subprocess has no usable stdin under Gunicorn, so such a job fails rather than completing. The UI only offers `mp4`/`webm`, so in practice this is reachable only via artist URLs or direct API calls.
---
@@ -100,4 +135,4 @@ After the subprocess exits, `post_process_votify_files()` runs:
|------|-----------|
| [app.py](../app.py) | `run_download()`, `post_process_votify_files()`, route `/api/download` |
| [utils.py](../utils.py) | `rename_from_metadata()`, `cleanup_empty_dirs()` |
| [Dockerfile](../Dockerfile) | Installation of votify-fix, ffmpeg, aria2, Bento4 |
| [Dockerfile](../Dockerfile) | Installation of votify, ffmpeg, aria2, Bento4 |