#!/bin/bash # gen-djmix-playlist.sh — regenerate djmix.m3u8 from the configured album list. # # Reads ${ALEMBIC_CONFIG_DIR:-/config}/pipeline/djmix-albums.txt (one beets query per line), # collects all matching track paths, deduplicates, and writes # ${MUSIC_DATA_DIR:-/data/music}/playlists/djmix.m3u8. # # Azuracast imports this playlist so DJ mixes can be excluded from general # rotation. Navidrome also picks it up as a regular playlist. # # Runs daily from cron. Safe to run manually anytime. set -euo pipefail CONFIG=${ALEMBIC_CONFIG_DIR:-/config}/pipeline/djmix-albums.txt PLAYLIST_DIR=${MUSIC_DATA_DIR:-/data/music}/playlists OUT="${PLAYLIST_DIR}/djmix.m3u8" LOG_DIR=${ALEMBIC_CONFIG_DIR:-/config}/logs LOG="${LOG_DIR}/djmix-$(date +%Y%m%d).log" mkdir -p "$LOG_DIR" "$PLAYLIST_DIR" log() { echo "[$(date -Iseconds)] $*" | tee -a "$LOG"; } log "=== Regenerating djmix.m3u8 ===" if [[ ! -f "$CONFIG" ]]; then log "no djmix-albums.txt at $CONFIG — nothing to generate" exit 0 fi TRACKS=$(mktemp) while IFS= read -r query; do [[ -z "$query" || "$query" == "#"* ]] && continue # Split on | to support multi-field queries (e.g. "albumartist::Foo | album:Bar"). # Each |-separated part becomes a separate beet query term (ANDed together). # Single-field lines (no |) are passed as one arg so commas in album names # don't get misinterpreted by beet's query parser. IFS='|' read -ra _terms <<< "$query" _args=() for _t in "${_terms[@]}"; do # strip leading/trailing whitespace _t="${_t#"${_t%%[![:space:]]*}"}" _t="${_t%"${_t##*[![:space:]]}"}" [[ -n "$_t" ]] && _args+=("$_t") done # `|| true`: a malformed single query shouldn't abort the whole regen. beet ls -f '$path' "${_args[@]}" 2>>"$LOG" >> "$TRACKS" || true done < "$CONFIG" # Deduplicate and sort SORTED=$(sort -u "$TRACKS") rm -f "$TRACKS" COUNT=$(echo -n "$SORTED" | grep -c '^' || true) if [[ "$COUNT" -gt 0 ]]; then { echo "#EXTM3U" echo "$SORTED" } > "$OUT" log "djmix.m3u8 updated with $COUNT tracks" else log "WARNING: no tracks found — djmix.m3u8 not updated" fi log "=== Finished ==="