From 8cbbb4b50d0fb5ab709240b9d489463328d9a96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kier=C3=A1n=20Meinhardt?= Date: Wed, 3 Feb 2021 11:13:31 +0100 Subject: [PATCH] feat(radio): serve html of current song --- configs/radio.nix | 132 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 18 deletions(-) diff --git a/configs/radio.nix b/configs/radio.nix index b22e0e2..968654d 100644 --- a/configs/radio.nix +++ b/configs/radio.nix @@ -1,19 +1,45 @@ { lib, pkgs, config, ... }: let - meddl = { - streamPort = 8000; - mpdPort = 6600; - }; - lyrikline = { - streamPort = 8001; - mpdPort = 6601; - }; - lyrik = { - streamPort = 8002; - mpdPort = 6602; - }; + radioStore = "/var/lib/radio"; + htgenPort = 8080; + meddl = { streamPort = 8000; mpdPort = 6600; }; + lyrikline = { streamPort = 8001; mpdPort = 6601; }; + lyrik = { streamPort = 8002; mpdPort = 6602; }; + mpd-add-with-tags = pkgs.writers.writeHaskell "mpd-add-with-tags" { + libraries = with pkgs.haskellPackages; [ optparse-generic libmpd ]; + } '' + {-# LANGUAGE DeriveGeneric, OverloadedStrings #-} + import Control.Monad (void) + import Data.String + import Network.MPD + import Options.Generic + + data Options = Options { url :: String, artist :: Maybe String, title :: Maybe String } + deriving (Generic) + + instance ParseRecord Options + + main :: IO () + main = do + options <- getRecord "Add to MPD with tags" + void $ withMPD $ do + songId <- addId (fromString $ url options) Nothing + maybe (pure ()) (addTagId songId Artist . fromString) $ artist options + maybe (pure ()) (addTagId songId Title . fromString) $ title options + ''; in { + imports = [ ]; + nixpkgs.overlays = [ + (self: super: { htgen = super.callPackage {}; }) + ]; + + systemd.tmpfiles.rules = [ + "d '${radioStore}' 0755 ${config.users.extraUsers.radio.name} - 1d -" + ]; + + users.extraUsers.radio.isSystemUser = true; + containers.lyrik = { autoStart = true; config = {config, pkgs, ...}: { @@ -38,6 +64,49 @@ in }; }; + krebs.htgen.radio = { + port = htgenPort; + user.name = "radio"; + script = ''. ${pkgs.writers.writeDash "meinskript" '' + case "$Method $Request_URI" in + "GET /lyrikline/status") + printf 'HTTP/1.1 200 OK\r\n' + printf 'Content-Type: text/html; charset=UTF-8\r\n' + printf 'Connection: close\r\n' + printf '\r\n' + + hash="$( + MPD_PORT=${toString lyrikline.mpdPort} ${pkgs.mpc_cli}/bin/mpc status -f '%file%' \ + | head -n 1 \ + | md5sum \ + | cut -d' ' -f 1 + )" + url="$(cat ${radioStore}/$hash)" + + echo "" + exit + ;; + "GET /meddl/status") + printf 'HTTP/1.1 200 OK\r\n' + printf 'Content-Type: text/html; charset=UTF-8\r\n' + printf 'Connection: close\r\n' + printf '\r\n' + + hash="$( + MPD_PORT=${toString meddl.mpdPort} ${pkgs.mpc_cli}/bin/mpc status -f '%file%' \ + | head -n 1 \ + | md5sum \ + | cut -d' ' -f 1 + )" + url="$(cat ${radioStore}/$hash)" + + echo "" + exit + ;; + esac + ''}''; + }; + containers.meddl = { autoStart = true; config = {config, pkgs, ...}: { @@ -92,15 +161,31 @@ in after = [ "container@lyrikline.service" ]; wantedBy = [ "container@lyrikline.service" ]; startAt = "*:00/5"; - environment.MPD_PORT = toString lyrikline.mpdPort; + environment = { + MPD_PORT = toString lyrikline.mpdPort; + MPD_HOST = "127.0.0.1"; + }; + serviceConfig.User = config.users.extraUsers.radio.name; + preStart = "${pkgs.mpc_cli}/bin/mpc crop"; script = '' set -efu lyrikline=https://www.lyrikline.org for _ in $(seq 1 10); do random_route="$(${pkgs.curl}/bin/curl -sSL "$lyrikline/index.php/tools/getrandompoem" --data-raw 'lang=de' --compressed | ${pkgs.jq}/bin/jq -r .link)" - poem_url="$(${pkgs.curl}/bin/curl -sSL "$lyrikline$random_route" | grep -o 'https://.*\.mp3' | head -n1)" - ${pkgs.mpc_cli}/bin/mpc add "$poem_url" + poem_url="$lyrikline$random_route" + + poem_file="$( + ${pkgs.curl}/bin/curl -sSL "$poem_url" \ + | grep -o 'https://.*\.mp3' \ + | head -n1 + )" + + hash="$(echo "$poem_file" | md5sum | cut -d' ' -f 1)" + echo "$poem_file ($hash) -> $poem_url" + echo "$poem_url" > "${radioStore}/$hash" + + ${pkgs.mpc_cli}/bin/mpc add "$poem_file" done ${pkgs.mpc_cli}/bin/mpc play @@ -113,6 +198,7 @@ in environment.MPD_PORT = toString lyrik.mpdPort; preStart = "${pkgs.mpc_cli}/bin/mpc crop"; restartIfChanged = true; + serviceConfig.User = config.users.extraUsers.radio.name; script = let videoIds = import ; @@ -120,7 +206,6 @@ in streamsFile = pkgs.writeText "hotrot" streams; in '' set -efu - ${pkgs.mpc_cli}/bin/mpc add < ${toString streamsFile} ${pkgs.mpc_cli}/bin/mpc crossfade 5 @@ -136,6 +221,8 @@ in wantedBy = [ "container@meddl.service" ]; startAt = "*:00/10"; environment.MPD_PORT = toString meddl.mpdPort; + serviceConfig.User = config.users.extraUsers.radio.name; + preStart = "${pkgs.mpc_cli}/bin/mpc crop"; script = '' set -efu host=http://antenne-asb.ga @@ -152,6 +239,11 @@ in | ${pkgs.pup}/bin/pup 'audio source attr{src}' \ | prepend_host )" + + hash="$(echo "$song_url" | md5sum | cut -d' ' -f 1)" + echo "$song_url ($hash) -> $song" + echo "$song" > "${radioStore}/$hash" + ${pkgs.mpc_cli}/bin/mpc add "$song_url" done @@ -172,8 +264,12 @@ in ]; services.nginx.virtualHosts."radio.xn--kiern-0qa.de".locations = { - "= /meddl.ogg".proxyPass = "http://127.0.0.1:${toString meddl.streamPort}"; - "= /lyrikline.ogg".proxyPass = "http://127.0.0.1:${toString lyrikline.streamPort}"; + "= /meddl/status".proxyPass = "http://127.0.0.1:${toString htgenPort}"; + "= /meddl/listen.ogg".proxyPass = "http://127.0.0.1:${toString meddl.streamPort}"; + "= /lyrikline/status".proxyPass = "http://127.0.0.1:${toString htgenPort}"; + "= /lyrikline/listen.ogg".proxyPass = "http://127.0.0.1:${toString lyrikline.streamPort}"; "= /lyrik.ogg".proxyPass = "http://127.0.0.1:${toString lyrik.streamPort}"; + "= /meddl.ogg".return = "301 http://radio.xn--kiern-0qa.de/meddl/listen.ogg"; + "= /lyrikline.ogg".return = "301 http://radio.xn--kiern-0qa.de/lyrikline/listen.ogg"; }; }