navidrome_bridge: add dropbox mode writing straight to the request spool

Reading radio_conjurer.liq shows request.playlist is not a Liquidsoap playlist
at all - it is a drop box. queue_processing() runs every 60s, reads every line,
pushes each into request.queue() as a URI, then deletes the file and recreates
it empty. That changes what writing to it means, so the mode is now named and
documented for what it is.

BRIDGE_MODE=dropbox (with "playlist" kept as an alias) appends the exact
translated path to that file. Because the lines are pushed as URIs it is an
exact hand-off - no keyword search - and it involves neither betoniarka nor the
bot, just the file and Liquidsoap. The liq also puts requests_queue first in the
fallback and does not apply the check_next replay guard to it, so a request
interrupts the rotation and plays even if the track ran recently; both are now
documented rather than left to be discovered.

Fixes found while wiring this up:
* the existence check was unconditional while the library mount was documented
  as optional, so a drop-box-only setup could never queue anything. It is now
  BRIDGE_VERIFY_FILE_EXISTS (auto|true|false), defaulting to checking only when
  the library is actually visible;
* a missing parent dir was silently created, which would swallow requests into
  the container's own filesystem when the radio's data dir was not mounted. It
  is now a hard error naming the likely cause.

Verified: alias resolves; append/drain/append cycle against a simulation of the
liq's read-remove-recreate; both misconfigurations raise instead of silently
succeeding; drop-box-only path works with the library absent; api mode
unchanged, still prepending the sentinel that wyszukaj() discards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Michal Tuszowski
2026-07-21 19:43:14 +02:00
parent 7f652aa9db
commit 298f4b111e
4 changed files with 165 additions and 42 deletions
+18 -6
View File
@@ -20,15 +20,27 @@ BETONIARKA_URL=http://radio-vm:5005
CONJURER_API_KEY=
# How the request reaches the radio:
# api - POST /request_radio_file over the network. No shared filesystem.
# The radio re-finds the track from keywords, so it is a fuzzy
# match (accurate in practice - full path tokens are very
# distinctive - but not guaranteed).
# playlist - append the exact translated path to the request playlist.
# Exact, but needs the radio's data dir mounted here.
# api - POST /request_radio_file over the network. No shared filesystem.
# betoniarka re-finds the track from keywords, so it is a fuzzy
# match (accurate in practice - full path tokens are very
# distinctive - but not guaranteed).
# dropbox - write the exact path straight into the file Liquidsoap drains.
# Exact hand-off, and it involves neither betoniarka nor the bot;
# needs that file reachable here. ("playlist" = same thing.)
BRIDGE_MODE=api
# dropbox mode only: the editable drop box radio_conjurer.liq reads every 60s.
# It pushes each line as a URI and then empties the file. Note the singular
# name - request.playlist, not requests.playlist.
BETONIARKA_REQUEST_PLAYLIST=/srv/betoniarka/data/request.playlist
# Confirm the translated path exists before queueing it.
# auto - check only when BETONIARKA_LIBRARY_ROOT is actually mounted here
# (so a drop-box-only setup need not mount the whole library)
# true - always check; refuse to queue what cannot be seen
# false - never check
BRIDGE_VERIFY_FILE_EXISTS=auto
# --- Behaviour -----------------------------------------------------------
# How often to look for newly starred tracks.
BRIDGE_POLL_SECONDS=15