• v0.6.9 62251d764e

    0.6.9 Stable

    andrew released this 2026-07-16 11:51:55 -06:00 | 0 commits to master since this release

    Completes the July 8 path rewrite cleanup that 0.6.8 started. Three more scripts still assumed the old /music path prefix that beets stopped displaying after the rewrite, and each failed silently.

    replace-with-better.sh could not find any library file it matched, so the mp3 to flac upgrade flow stopped replacing MP3s in place. Instead it imported each fetched FLAC as a brand new track, leaving flac and mp3 twins side by side in the library for the dedup queue to catch. fix-track-metadata.py stopped finding beets entries after a retag, so it silently skipped the beet update and move steps. export-laptop-playlists.py filtered out every track and produced empty exports.

    All three now use the real paths beets displays, keeping the old /music form only as a fallback for stale entries.

    Downloads
  • v0.6.8 d756aab7fc

    0.6.8 Stable

    andrew released this 2026-07-16 09:23:53 -06:00 | 1 commits to master since this release

    Fixes the duplicate download flood from the night of July 15 to 16.

    sldl keeps a per-playlist index of what it already downloaded, and it places that index in a folder named after the input. Switching the input from a Spotify URL to a CSV file in 0.6.2 changed that folder name, so sldl started over with an empty index and re-downloaded every playlist in full. The index path is now pinned in the rendered config, and run-playlist.sh seeds the pinned index from any stranded ones (new helper: merge-sldl-indexes.py), so download history survives future input changes.

    Separately, the nightly dedup scan had been reporting zero duplicates since the July 8 path rewrite because it still translated beets paths using the old /music prefix. It now passes modern paths through unchanged, so the scan actually sees the library again. Run a dedup scan after upgrading to surface any duplicates that slipped in.

    Downloads
  • v0.6.7 24738d815f

    0.6.7 Stable

    andrew released this 2026-07-15 13:50:20 -06:00 | 2 commits to master since this release

    Removes the slskd line from the daily Telegram digest's Services section. slskd is not part of the alembic pipeline (sldl connects to Soulseek directly), so its reachability is not alembic's to report on. If you run slskd for your own file sharing it is unaffected; alembic simply no longer checks it.

    Upgrade: change the version in your docker-compose.yml, then docker compose pull alembic && docker compose up -d alembic.

    Downloads
  • v0.6.6 900bbff8aa

    0.6.6 Stable

    andrew released this 2026-07-15 13:44:26 -06:00 | 3 commits to master since this release

    Redesigns the daily Telegram digest (covers 0.6.5, which was never published as a release, plus the final formatting pass).

    The digest is now formatted for Telegram instead of raw monospace text: a branded header with hostname and date, a green/orange tally line, a callout up top saying either all clear or how many items need attention, bold section headers, and one line per check with a colored status dot. Rows are plain text that reflows on a phone screen, no more fixed-width columns wrapping mid-word. Long content is truncated safely so a very long report can never break the send.

    Also included:

    • Two digest sections ("added today" and "Library by format") had been silently empty since the in-app scheduler took over from cron, because the status script could not find the beet command. They show real numbers again.
    • The weekly cover-art watermark job no longer fails its entire run when reading one file stalls; it skips that file with a warning and carries on.
    • notify-telegram.sh keeps sending plain text for any other use; the digest opts into the new formatting explicitly.

    Upgrade: change the version in your docker-compose.yml, then docker compose pull alembic && docker compose up -d alembic.

    (Note: the v0.6.5 tag exists in the repo but had no release; everything it contained is described above and included here.)

    Downloads
  • v0.6.4 7a49e2d507

    0.6.4 Stable

    andrew released this 2026-07-15 10:13:02 -06:00 | 5 commits to master since this release

    Fixes the daily Telegram digest wrongly reporting healthy maintenance jobs as "never run yet". The digest was looking for log files from the old cron setup that the in-app job runner no longer writes. It now reads the app's own job history, so each maintenance line shows the real last successful run, its result summary, and honestly calls out a newer attempt that failed or was skipped because another job held the pipeline lock.

    That history also exposed a real scheduling gap: the Sunday maintenance jobs run a few minutes apart, and when an earlier one runs long the later ones found the pipeline busy and silently skipped their only slot of the week. Scheduled jobs now wait up to 30 minutes for their turn instead of skipping, so the Sunday block runs back to back no matter how long each step takes. Clicking Run now in the UI still answers immediately if the pipeline is busy.

    Upgrade: change the version in your docker-compose.yml, then docker compose pull alembic && docker compose up -d alembic.

    Downloads
  • v0.6.3 8ecff44811

    0.6.3 Stable

    andrew released this 2026-07-15 09:50:57 -06:00 | 6 commits to master since this release

    Fixes playlists downloading nothing (and showing an empty tracklist in alembic) for Spotify apps created after Spotify's February 2026 API change, even on playlists the connected account owns.

    The cause: for new apps, Spotify renamed part of the playlist response. Each entry's song data moved from a field called track to one called item. Old (grandfathered) apps still get the old name, so this only hit new apps. alembic only looked for the old name, so every song in the playlist was silently skipped: runs finished "successfully" having downloaded nothing, and the playlist page showed no songs. alembic now reads both forms.

    Also in this release:

    • Spotify only gives new apps the contents of playlists the connected account owns or collaborates on. Being public is no longer enough. That case now shows a clear error explaining what to do, instead of looking like an empty playlist. The README's Spotify sections explain this too.
    • Every playlist run now logs how many tracks it fetched from Spotify, and warns loudly if the answer is zero.

    Upgrade: change the version in your docker-compose.yml, then docker compose pull alembic && docker compose up -d alembic.

    Downloads
  • v0.6.2 2e3210cc01

    0.6.2 Stable

    claude released this 2026-07-15 08:54:17 -06:00 | 8 commits to master since this release

    Fixes playlist loading for Spotify apps created after Spotify's February 2026 API change. Those apps get a hard 403 from the endpoint sldl's built-in Spotify client still uses, no matter how they authenticate, which crashed every run (exit 134) even after connecting Spotify via OAuth.

    alembic no longer lets sldl talk to Spotify at all. It reads the playlist itself through the current API, writes the track list to a CSV, and hands sldl that CSV to search from. Everything else (Soulseek login, download paths, quality settings) works exactly as before. This works the same for old grandfathered Spotify apps and brand new ones.

    Because of this, playlist config files no longer contain your Spotify credentials at all; they live only in one credentials file the pipeline scripts read. Existing config files are cleaned up automatically the first time the new version starts.

    Also in this release:

    • A playlist the connected Spotify account cannot see now produces a clear error message telling you to own, follow, or make the playlist public, instead of a crash dump.
    • Multi-artist tracks now search Soulseek with all artists listed, matching how sldl searched before.
    • Deleting a playlist cleans up its generated track-list file too.

    Upgrade: change the version in your docker-compose.yml, then docker compose pull alembic && docker compose up -d alembic.

    Downloads
  • v0.6.1 9976c430aa

    0.6.1 Stable

    andrew released this 2026-07-15 08:07:59 -06:00 | 9 commits to master since this release

    Fixes a bug where the Spotify OAuth connect flow (added in 0.6) requested a narrower permission scope than sldl's own login flow expects. This let the refresh token mint a valid access token, but Spotify then returned 403 Forbidden loading the playlist regardless of ownership -- which sldl turns into a hard crash (exit 134) instead of a clean error.

    If you connected Spotify under 0.6, click Connect Spotify again -- your existing connection carries the old, narrower scope and will not upgrade itself.

    Also improves the job log: a 134 crash now gets a pointed diagnostic hint instead of just a bare exit code.

    Downloads
  • v0.6 e5d9c7f043

    0.6 Stable

    andrew released this 2026-07-14 11:18:06 -06:00 | 11 commits to master since this release

    • Add a "Connect Spotify" OAuth flow so newly created Spotify apps can read playlists. Spotify now requires a user token for playlist reads; client-credentials alone is rejected for apps created after their 2025/2026 API change. The stored refresh token is handed to sldl (via spotify-refresh in the rendered .conf), which per sldl's own docs skips its interactive login flow entirely -- the actual cause of prior multi-hour stuck-sync hangs. Grandfathered apps keep working unchanged if no account is connected.
    • Add an AzuraCast base URL field alongside the API key in Settings -> Credentials, with a keyfile fallback so the scheduled buy-link enrichment job can actually reach AzuraCast (previously it had no way to receive a base URL when run from the scheduler, so the reprocess call was silently always skipped).
    • Fix build-fingerprint-index.py failing the whole job on a single fingerprint failure instead of only when nothing was written.
    • Guard enrich-buy-url.py's AzuraCast reprocess call against an empty base URL.

    See the README's Spotify and AzuraCast credentials sections for setup steps.

    Downloads
  • v0.5.2 97672ffdcd

    v0.5.2 Stable

    claude released this 2026-07-14 10:14:51 -06:00 | 13 commits to master since this release

    Bug-fix release. To update, set your image tag to 0.5.2 (or use latest), then docker compose pull and docker compose up -d. Your library, credentials, and settings are untouched.

    Fixes

    • Spotify playlists readable again on new apps. Spotify's February 2026 API changes removed GET /playlists/{id}/tracks in favor of /items, and newer Spotify apps are now blocked from the old endpoint (a 403). alembic now uses /items.
    • "Run now" works on unscheduled playlists. A playlist with no daily sync time returned "not found" when you clicked Run now; it now runs on demand like any other.
    • Clearer 403 message on the playlist page, and a new Troubleshooting section covering the Spotify app requirements.

    If downloads still 403 on a brand-new Spotify app

    The bundled Soulseek downloader reads Spotify through its own library. Since Spotify now grants "extended quota mode" only to organizations (not individuals), the reliable fix for a new personal app being blocked is to use the Client ID and Secret from an app created before the change. Keep your playlists public either way -- app-only access can't read private playlists.

    Downloads