- Rust 82.1%
- Just 14.2%
- Dockerfile 3.7%
| src | ||
| .containerignore | ||
| .env.sample | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Containerfile | ||
| Justfile | ||
| README.md | ||
| subsonic-shuffler.container | ||
Disclaimer: This project is completely AI generated.
subsonic-shuffler
A command-line tool that shuffles a Subsonic / OpenSubsonic playlist. It can shuffle a playlist in-place or write the shuffled result to a different playlist.
Requirements
- Rust toolchain (edition 2021, MSRV 1.85)
- just (optional, for the convenience recipes)
- A Subsonic-compatible server (Navidrome, Gonic, etc.)
Configuration
Credentials are read from environment variables:
| Variable | Description |
|---|---|
SUBSONIC_URL |
Server base URL |
SUBSONIC_USER |
Username |
SUBSONIC_PASSWORD |
Password |
Copy .env.sample to .env and fill in your values. The just recipes load .env automatically.
cp .env.sample .env
$EDITOR .env
Usage
subsonic-shuffler [OPTIONS] [PLAYLIST]
Source options
The source playlist can be specified as a positional argument (by name) or via a flag:
| Option | Description |
|---|---|
PLAYLIST |
Source playlist name (positional) |
--source <NAME> |
Source playlist by name |
--source-id <ID> |
Source playlist by ID |
If multiple playlists share the same name, the tool errors and lists each one with its ID so you can switch to --source-id.
Destination options
If no destination option is given, the source playlist is shuffled in-place.
| Option | Description |
|---|---|
| (none) | Shuffle the source playlist in-place |
--create <NAME> |
Create a new playlist; fails if a playlist with that name already exists |
--output <NAME> |
Write to a playlist by name; creates it if missing, overwrites if it exists |
--output-id <ID> |
Overwrite an existing playlist by ID |
--create, --output, and --output-id are mutually exclusive.
Examples
Shuffle a playlist in-place:
subsonic-shuffler "My Playlist"
subsonic-shuffler --source "My Playlist"
subsonic-shuffler --source-id 42
Create a new shuffled copy (fails if Shuffle Queue already exists):
subsonic-shuffler "My Playlist" --create "Shuffle Queue"
Write the shuffled result to an existing-or-new playlist:
subsonic-shuffler "My Playlist" --output "Shuffle Queue"
Overwrite a specific playlist by ID:
subsonic-shuffler "My Playlist" --output-id 99
Just recipes
just shuffle "My Playlist" # in-place by name
just shuffle-id 42 # in-place by ID
just shuffle-create "My Playlist" "Shuffle Queue" # create new (fails if exists)
just shuffle-output "My Playlist" "Shuffle Queue" # create or overwrite by name
just shuffle-output-id "My Playlist" 99 # overwrite by ID
just build # release build
Container
Pre-built images for x86_64 are published to the Forgejo registry:
forgejo.victorsavu.eu/victor/subsonic-shuffler:latest
forgejo.victorsavu.eu/victor/subsonic-shuffler:1.0.0
Pass credentials as environment variables and append arguments after the image name:
podman run --rm \
-e SUBSONIC_URL=https://your-server.example.com \
-e SUBSONIC_USER=your-username \
-e SUBSONIC_PASSWORD=your-password \
forgejo.victorsavu.eu/victor/subsonic-shuffler:latest \
"My Playlist"
Any option that works with the binary works the same way:
podman run --rm \
-e SUBSONIC_URL=... -e SUBSONIC_USER=... -e SUBSONIC_PASSWORD=... \
forgejo.victorsavu.eu/victor/subsonic-shuffler:latest \
--source "My Library" --output "Shuffle Queue"
Testing
This project has no unit tests. All meaningful logic is Subsonic API calls, so unit tests would require mocking the entire client and verify nothing real. Meaningful test coverage would require an integration test against a live server (e.g. a local Navidrome instance in a container), which is significant setup for a tool of this size.
Building
cargo build --release
# binary at target/release/subsonic-shuffler
To build and push the container image:
just image-build 1.0.0
just image-push 1.0.0