1
0
mirror of https://github.com/kmein/niveum synced 2026-03-19 11:31:09 +01:00

16 Commits

Author SHA1 Message Date
704f745f5e try out whether new krops fixes the nixpkgs rebuilding issue 2022-02-16 09:11:10 +01:00
93dd8bd702 fix: less unstable, nixpkgs via krops git, NIX_PATH on makanek
systems wanted to build glibc all the time when updated
2022-02-15 22:16:50 +01:00
6e995764d4 chore: update horoscopy 2022-02-14 21:21:36 +01:00
87b9fc49ea feat(radio): opus streams 2022-02-14 08:14:15 +01:00
b4e42e6b22 feat: add horoscopy website 2022-02-14 08:02:08 +01:00
87f73a8fc1 fix(radio): clean up files after 1h 2022-02-10 19:28:34 +01:00
db8c06364f feat: wikipedia radio 2022-02-10 19:28:34 +01:00
24b7044a3f chore: update retiolum 2022-02-09 08:35:55 +01:00
908667267b feat: radio powered by liquidsoap 2022-02-08 00:47:10 +01:00
b3090737fd feat(grocy): disable 2022-02-07 12:59:34 +01:00
f195351474 feat(urlwatch): run later 2022-02-07 12:52:46 +01:00
1cce7dc8df feat: #hsmr moinbot 2022-02-07 11:44:29 +01:00
894cc6efef feat(polkit): dont need password for systemctl 2022-02-02 18:07:08 +01:00
f1ed00fe40 fix(traadfri): module scripts 2022-01-31 19:46:59 +01:00
7d1e1e712f feat(monitoring): simplify telegram alert message format 2022-01-31 09:33:24 +01:00
fd1c36874a feat(traadfri): no aliases but scripts 2022-01-31 09:33:04 +01:00
20 changed files with 291 additions and 306 deletions

View File

@@ -228,6 +228,7 @@ in {
./flameshot-once.nix
./packages.nix
./stardict.nix
./polkit.nix
./power-action.nix
./printing.nix
./openweathermap.nix

View File

@@ -1,6 +1,5 @@
{ pkgs, lib, ... }: let
swallow = command: "${pkgs.scripts.swallow}/bin/swallow ${command}";
nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; };
in {
environment.shellAliases.smpv = swallow "mpv";
@@ -22,7 +21,7 @@ in {
"Alt+j" = "add video-pan-y -0.05";
};
scripts = [
nixpkgs-unstable.mpvScripts.youtube-quality
pkgs.mpvScripts.youtube-quality
];
};
};

View File

@@ -197,7 +197,7 @@ in {
(pkgs.writers.writeDashBin "ncmpcpp-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.ncmpcpp}/bin/ncmpcpp "$@"'')
(pkgs.writers.writeDashBin "mpc-zaatar" ''MPD_HOST=${(import <niveum/lib/local-network.nix>).zaatar} exec ${pkgs.mpc_cli}/bin/mpc "$@"'')
nixpkgs-unstable.spotify
spotify
ncspot
playerctl

13
configs/polkit.nix Normal file
View File

@@ -0,0 +1,13 @@
{ config, ... }:
let
user = config.users.users.me.name;
in
{
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.user == "${user}" && action.id == "org.freedesktop.systemd1.manage-units") {
return polkit.Result.YES;
}
});
'';
}

46
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"flake-utils": {
"locked": {
"lastModified": 1638122382,
"narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
"lastModified": 1644229661,
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "74f7e4319258e287b0f9cb95426c9853b282730b",
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
"type": "github"
},
"original": {
@@ -22,11 +22,11 @@
]
},
"locked": {
"lastModified": 1639871969,
"narHash": "sha256-6feWUnMygRzA9tzkrfAzpA5/NBYg75bkFxnqb1DtD7E=",
"lastModified": 1643933536,
"narHash": "sha256-yRmsWAG4DnLxLIUtlaZsl0kH7rN5xSoyNRlf0YZrcH4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "697cc8c68ed6a606296efbbe9614c32537078756",
"rev": "2860d7e3bb350f18f7477858f3513f9798896831",
"type": "github"
},
"original": {
@@ -46,11 +46,11 @@
]
},
"locked": {
"lastModified": 1632420452,
"narHash": "sha256-ncK6vABW/Ku9XI0kqj1otarUfblryoQzSaOCnaZ0oSs=",
"lastModified": 1644957911,
"narHash": "sha256-ggie/j7pdBqzDs4W7OiPmhqH9IGbXAbJxGqBdVxA8jA=",
"owner": "Mic92",
"repo": "krops",
"rev": "0388970c568905fedcbf429e5745aacd4f7a6633",
"rev": "86fb3d2ee94fd8306231853b323ed8804edf26ec",
"type": "github"
},
"original": {
@@ -109,27 +109,27 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1641829252,
"narHash": "sha256-CI0qi7k1Y4nFna+kdQtVCbN4ZEVwZcD/oIGgfTcUNrA=",
"lastModified": 1644837400,
"narHash": "sha256-treFS89w/xKzeTjJSJdYp/Ceddv6oqq7bL9mZMQDPi0=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5d3420c1285073d5061a5d88a533b347d1222750",
"rev": "a03ae0e6d078cfdbb8404c3bff3622bd4e2f1c57",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-21.11",
"ref": "nixos-21.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1641935776,
"narHash": "sha256-8q/V9EgzyW0KvGnBjbTfQ19qoTCFqsEd1mF9DheCukw=",
"lastModified": 1644951967,
"narHash": "sha256-j+l8bt++dsYTJSGABuqeBEom5aNpD4n0BsOTdewFYuU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "bd20b7f07fd337b2e85420edd642382a2cc0196d",
"rev": "05e1f8a2c7797b0d9f9e07ab2aaeccecdcf9b7da",
"type": "github"
},
"original": {
@@ -158,11 +158,11 @@
"retiolum": {
"flake": false,
"locked": {
"lastModified": 1643369411,
"narHash": "sha256-FRfEQdRJxVF6w41jgjQXDtK5YxIjDh5S4acA0FbwPyE=",
"lastModified": 1644849126,
"narHash": "sha256-iaRNvfQrUD+ZownDWWNdDwhVPgSsU5ojvVdswVq1IpY=",
"owner": "krebs",
"repo": "retiolum",
"rev": "23e04565a0360d31605a6c6cdc1becb5b9f76f32",
"rev": "6de359ef848dc1f38fb76731c35e712ee885fd88",
"type": "github"
},
"original": {
@@ -210,11 +210,11 @@
"stockholm": {
"flake": false,
"locked": {
"lastModified": 1641747862,
"narHash": "sha256-gAGM3sxCP//k83CUow3ZpeHQCeuW62YJ6kWvWd8D1vk=",
"lastModified": 1644865613,
"narHash": "sha256-z7hPtMYxoQuWyLujUs5vbdZOGbjFosh+/IX3GpCDlkc=",
"ref": "master",
"rev": "f67bd5783d6ed2be836c7714ea38cbb3f7ac7257",
"revCount": 10285,
"rev": "e3785b22b2c6cb173a58fd066c4eda80a67fb872",
"revCount": 10404,
"type": "git",
"url": "https://cgit.lassul.us/stockholm"
},

View File

@@ -2,7 +2,7 @@
description = "niveum: packages, modules, systems";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/master";
flake-utils.url = "github:numtide/flake-utils";
home-manager = {

View File

@@ -54,16 +54,22 @@ in [
stream = "https://c3lounge.de/radio/8000/radio.mp3";
}
{
stream = "https://radio.kmein.de/lyrik/listen.ogg";
stream = "https://radio.kmein.de/lyrik.ogg";
station = "Lyrik";
desc = "Lyrik-Lesung rund um die Uhr.";
}
{
stream = "https://radio.kmein.de/lyrikline/listen.ogg";
stream = "https://radio.kmein.de/lyrikline.ogg";
station = "Lyrikline";
logo = "https://www.lyrikline.org/themes/lyrik/svg/Logo_lyrikline_pure.svg";
desc = "24/7 zufällige Wiedergaben von lyrikline.org.";
}
{
stream = "https://radio.kmein.de/wikipedia.ogg";
station = "Wikipedia";
desc = "Zufällige Wikipedia-Artikel";
logo = "https://de.wikipedia.org/wiki/Wikipedia:Enzyklop%C3%A4die/Logo_von_Wikipedia#/media/Datei:Wikipedia-logo-v2.svg";
}
{
stream = "http://162.244.80.20:6948";
station = "Cool Jazz Florida";
@@ -1167,15 +1173,15 @@ importJSON ./radiorecord.json
station = "Dhol Radio";
desc = " ";
}
{ logo = bhaktiworld-logo; stream = bhaktiworld "2bhanuman"; station = bhaktiworld-name "Hanuman"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "djbeat"; station = bhaktiworld-name "Mantra Shakti"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "gurbani"; station = bhaktiworld-name "Sangam"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "hot"; station = bhaktiworld-name "Shiv"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "ibadat"; station = bhaktiworld-name "Devi Maa"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "iskon2b"; station = bhaktiworld-name "Om Sai"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "millenniumhits"; station = bhaktiworld-name "Krishna"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "dard"; station = bhaktiworld-name "Shri Ram"; }
{ logo = bhaktiworld-logo; stream = bhaktiworld "bhaktiworldindia"; station = bhaktiworld-name "Ganesh"; }
{ stream = bhaktiworld "2bhanuman"; station = bhaktiworld-name "Hanuman"; }
{ stream = bhaktiworld "djbeat"; station = bhaktiworld-name "Mantra Shakti"; }
{ stream = bhaktiworld "gurbani"; station = bhaktiworld-name "Sangam"; }
{ stream = bhaktiworld "hot"; station = bhaktiworld-name "Shiv"; }
{ stream = bhaktiworld "ibadat"; station = bhaktiworld-name "Devi Maa"; }
{ stream = bhaktiworld "iskon2b"; station = bhaktiworld-name "Om Sai"; }
{ stream = bhaktiworld "millenniumhits"; station = bhaktiworld-name "Krishna"; }
{ stream = bhaktiworld "dard"; station = bhaktiworld-name "Shri Ram"; }
{ stream = bhaktiworld "bhaktiworldindia"; station = bhaktiworld-name "Ganesh"; }
{
station = "Rockabilly Radio";
stream = "http://lin3.ash.fast-serv.com:6026/stream_96";

View File

@@ -22,12 +22,6 @@ in {
};
config = mkIf cfg.enable {
environment.shellAliases = lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "traadfri-${name}" "traadfri --target Bulb ${toString value}")
cfg.bulbs // lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "traadfri-${name}" "traadfri --target Room ${toString value}")
cfg.rooms;
environment.systemPackages = [
(pkgs.writers.writeDashBin "traadfri" ''
TRAADFRI_USER="${cfg.user}" \
@@ -35,6 +29,11 @@ in {
TRAADFRI_HUB="${cfg.host}" \
${traadfri}/bin/traadfri $@
'')
];
] ++ lib.mapAttrsToList (name: value: pkgs.writers.writeDashBin "traadfri-${name}" ''
exec traadfri --target Room ${toString value} "$@"
'') cfg.rooms
++ lib.mapAttrsToList (name: value: pkgs.writers.writeDashBin "traadfri-${name}" ''
exec traadfri --target Bulb ${toString value} "$@"
'') cfg.bulbs;
};
}

View File

@@ -0,0 +1,28 @@
regex: https://www.radioeins.de/musik/cd_der_woche/
selectors:
httpsettings:
cookie: {}
header: {}
useragent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/90.0.4430.72 Safari/537.36
insecure: false
feed:
title: .boxhead h2
description: .manualteaserShortText
authorname: ""
authoremail: ""
item:
container: .doctyperezension
title: h2 a.rezension
link: a.rezension
linkattr: href
created: .manualteaserDateTime
createdformat: 02.01.2006
description: .manualteaserShortText
content: ""
image: picture > img
imageattr: src
nextpage: ""
nextpageattr: href
nextpagecount: 0
sort: ""

View File

@@ -1,6 +1,5 @@
{ config, pkgs, lib, ... }:
let
nixpkgs-unstable = import <nixpkgs-unstable> { config.allowUnfree = true; };
inherit (import <niveum/lib>) retiolumAddresses;
in
{
@@ -22,7 +21,7 @@ in
maxJobs = 2;
};
environment.systemPackages = [ nixpkgs-unstable.minecraft ];
environment.systemPackages = [ pkgs.minecraft ];
networking = {
hostName = "kabsa";

View File

@@ -9,11 +9,13 @@ in
./hedgedoc.nix
./matterbridge.nix
./menstruation.nix
./moinbot.nix
./horoscopy.nix
./monitoring
./moodle-dl-borsfaye.nix
./names.nix
./nextcloud.nix
./radio
./radio.nix
./retiolum-map.nix
./tarot.nix
./urlwatch.nix
@@ -43,6 +45,8 @@ in
];
};
nix.nixPath = [ "/var/src" ];
networking = {
firewall.allowedTCPPorts = [ 80 443 ];
hostName = "makanek";

View File

@@ -0,0 +1,45 @@
{ pkgs, lib, ... }:
let
port = 5040;
punkt = pkgs.fetchzip {
url = "https://raw.githubusercontent.com/nltk/nltk_data/gh-pages/packages/tokenizers/punkt.zip";
sha256 = "113cv87dj5ml7g8pjm7psk4q1hrf0zqpmc945lmpdz91vp2wn1nc";
};
horoscopy-src = pkgs.fetchzip {
url = "http://c.krebsco.de/horoscopy.tar.gz";
stripRoot = false;
hash = "sha256-KBAbCvayTEr4+cOHnMXHCBA+8RWDMiQF65xzP4fOdaE=";
};
horoscopy = import horoscopy-src;
in
{
systemd.services.horoscopy = {
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
description = "AI astrologer";
serviceConfig = {
DynamicUser = true;
};
environment.NLTK_DATA = pkgs.linkFarm "punkt-tokenizers" [
{ name = "tokenizers/punkt"; path = punkt; }
];
script = ''
cd ${horoscopy-src}
${horoscopy.dependencyEnv}/bin/gunicorn wsgi:app -b :${toString port}
'';
};
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
};
services.nginx.virtualHosts."horoscopy.kmein.de" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${toString port}";
};
}

View File

@@ -0,0 +1,17 @@
{ pkgs, ... }:
{
systemd.services.moinbot = {
startAt = "7:00";
script = ''
echo moin | ${pkgs.ircaids}/bin/ircsink \
--nick moinbot \
--server irc.hackint.org \
--port 6697 \
--secure \
--target '#hsmr' >/dev/null 2>&1
'';
serviceConfig.DynamicUser = true;
};
systemd.timers.moinbot.timerConfig.RandomizedDelaySec = "14h";
}

View File

@@ -130,7 +130,7 @@ in
--template.paths=${pkgs.writeText "template.tmpl" ''
{{ define "telegram.default" }}
{{range .Alerts -}}
<b>{{.Status}}</b> {{ index .Annotations "summary"}}
{{.Status}}: {{ index .Annotations "summary"}}
{{end -}}
{{end}}
''}'';

127
systems/makanek/radio.nix Normal file
View File

@@ -0,0 +1,127 @@
{ lib, pkgs, config, ... }:
let
inherit (import <niveum/lib>) tmpfilesConfig;
liquidsoapDirectory = "/var/cache/liquidsoap";
icecastPassword = "hackme";
lyrikline-poem = pkgs.writers.writeDash "lyrikline.sh" ''
set -efu
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
lyrikline=https://www.lyrikline.org
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="$lyrikline$random_route"
${pkgs.curl}/bin/curl -sSL "$poem_url" > "$html"
poem_file="$(${pkgs.gnugrep}/bin/grep -o 'https://.*\.mp3' "$html" | head -n1)"
author="$(${pkgs.htmlq}/bin/htmlq -f "$html" --text '#gedicht-autor')"
title="$(${pkgs.htmlq}/bin/htmlq -f "$html" --text .gedicht-originaltitel)"
echo "annotate:title=\"$title | $poem_url\",artist=\"$author\":$poem_file"
'';
stavenhagen-poem = pkgs.writers.writeDash "stavenhagen.sh" ''
base=https://www.deutschelyrik.de
author=$(${pkgs.curl}/bin/curl -sSL "$base" | ${pkgs.htmlq}/bin/htmlq option --attribute value | shuf -n1)
poem=$(${pkgs.curl}/bin/curl -sSL "$base/$author" | ${pkgs.htmlq}/bin/htmlq '#mnav2 li > a' --attribute href | shuf -n1)
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
${pkgs.curl}/bin/curl -sSL "$base/$poem" > "$html"
printf "annotate:title=\"%s | %s\",artist=\"%s\":$base/%s\n" \
"$(${pkgs.htmlq}/bin/htmlq --text '.ce_text h1' -f "$html")" \
"$base/$poem" \
"$(${pkgs.htmlq}/bin/htmlq --text 'h1 + p em' -f "$html")" \
"$(${pkgs.htmlq}/bin/htmlq 'audio source' --attribute src -f "$html")"
'';
wikipedia-article = pkgs.writers.writeDash "wikipedia.sh" ''
set -efu
opus=$(mktemp ${liquidsoapDirectory}/wikipedia.XXX.opus)
html=$(mktemp)
trap clean EXIT
clean() {
rm "$html"
}
${pkgs.curl}/bin/curl -sSL https://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite > "$html"
${pkgs.htmlq}/bin/htmlq '.mw-parser-output p' --text -f "$html" \
| ${pkgs.gnused}/bin/sed 's/\[[0-9]\+]//g' \
| ${pkgs.espeak}/bin/espeak -v german-mbrola-6 -w /dev/stdout \
| ${pkgs.opusTools}/bin/opusenc --quiet - "$opus"
printf "annotate:title=\"%s\":%s" \
"$(${pkgs.htmlq}/bin/htmlq -f "$html" --text h1)" \
"$opus"
'';
in {
# https://github.com/savonet/liquidsoap/issues/1043#issuecomment-593354427
services.liquidsoap.streams.radio = pkgs.writeText "lyrikline.liq" ''
set("protocol.external.curl","${pkgs.curl}/bin/curl")
def random_url(script) =
mksafe(audio_to_stereo(request.dynamic.list(
fun () -> list.map(request.create, get_process_lines(script))
)))
end
def make_streams(name, audio, ~description, ~genre) =
output.icecast(%vorbis, audio, mount = name ^ ".ogg", genre = genre, description = description,
port = ${toString config.services.icecast.listen.port},
password = "${icecastPassword}",
)
output.icecast(%opus, audio, mount = name ^ ".opus", genre = genre, description = description,
port = ${toString config.services.icecast.listen.port},
password = "${icecastPassword}",
)
end
make_streams("lyrikline", random_url("${lyrikline-poem}"), description="lyrikline. listen to the poet (unofficial)", genre="poetry")
make_streams("lyrik", random_url("${stavenhagen-poem}"), description="Fritz Stavenhagen Lyrik für alle | www.deutschelyrik.de", genre="poetry")
make_streams("wikipedia", random_url("${wikipedia-article}"), description="Zufällige Artikel von Wikipedia", genre="useless knowledge")
'';
systemd.services.radio.environment.TMPDIR = liquidsoapDirectory;
systemd.tmpfiles.rules = [
(tmpfilesConfig {
type = "d";
path = liquidsoapDirectory;
mode = "0750";
user = "liquidsoap";
group = "liquidsoap";
age = "1h";
})
];
services.icecast = {
enable = true;
hostname = "radio.kmein.de";
admin.password = "hackme";
listen.port = 6457;
extraConf = ''
<authentication>
<source-password>${icecastPassword}</source-password>
</authentication>
'';
};
services.nginx.virtualHosts."radio.kmein.de" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://127.0.0.1:${toString config.services.icecast.listen.port}";
};
}

View File

@@ -1,212 +0,0 @@
{ lib, pkgs, config, ... }:
let
inherit (import <niveum/lib>) tmpfilesConfig serveHtml;
radioStore = "/var/lib/radio";
htgenPort = 8080;
stations = {
lyrikline = {
streamPort = 8001;
mpdPort = 6601;
description = ''
Weltklang. Welt als ewiges Gedicht, das seine Schallspuren durch Raum und Zeit jagt. Endlose Zufallswiedergabe von <a href="//lyrikline.org">lyrikline</a>. Listen to the sound of voices and poems permeating linguistic and geographic barriers, 24 hours per day.
'';
};
lyrik = {
streamPort = 8002;
mpdPort = 6602;
description = ''
Deutsche Lyrik, die du noch nicht gut genug kennst. Tritt in einen Fluss aus Reim und Maß; keine zwei Mal ist er derselbe.
'';
};
};
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
'';
mpcs = lib.mapAttrs (name: station: pkgs.writers.writeDashBin "mpc-${name}" ''
MPD_PORT=${toString station.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"
'') stations;
in
{
imports = [ <stockholm/krebs/3modules/htgen.nix> ];
nixpkgs.overlays = [
(self: super: { htgen = super.callPackage <stockholm/krebs/5pkgs/simple/htgen> {}; })
];
systemd.tmpfiles.rules = [
(tmpfilesConfig {
type = "d";
path = radioStore;
mode = "0755";
user = config.users.extraUsers.radio.name;
age = "1d";
})
];
users.extraUsers.radio = {
isSystemUser = true;
group = "radio";
};
users.groups.radio = {};
krebs.htgen.radio = {
port = htgenPort;
user.name = "radio";
script = ''. ${pkgs.writers.writeDash "meinskript" ''
send200() {
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'
}
case "$Method $Request_URI" in
"GET /lyrik/status")
send200
video_id="$(
${mpcs.lyrik}/bin/mpc-lyrik status -f %file% \
| head -n1 \
| grep -o 'id=[^&]*' \
| sed 's/^id=//g'
)"
${pkgs.youtube-dl}/bin/youtube-dl -j "https://www.youtube.com/watch?v=$video_id" \
| ${pkgs.jq}/bin/jq -r '"% [\(.title)](\(.webpage_url))\n\n\(.description)"' \
| sed 's/$/ /g' \
| ${pkgs.pandoc}/bin/pandoc -s
exit
;;
"GET /lyrikline/status")
send200
hash="$(
${mpcs.lyrikline}/bin/mpc-lyrikline status -f '%file%' \
| head -n 1 \
| md5sum \
| cut -d' ' -f 1
)"
url="$(cat ${radioStore}/$hash)"
echo "<html><body style='margin:0'><iframe style='width:100%;height:100%;border:0' src="$url"></iframe></body></html>"
exit
;;
esac
''}'';
};
containers = lib.mapAttrs (name: station: {
autoStart = true;
config = {config, pkgs, ...}: {
services.mpd = {
enable = true;
network.port = station.mpdPort;
extraConfig = ''
log_level "default"
audio_output {
name "${name}"
type "httpd"
encoder "vorbis"
port "${toString station.streamPort}"
bitrate "128"
format "44100:16:2"
always_on "yes"
tags "yes"
}
'';
};
};
}) stations;
environment.systemPackages = lib.attrValues mpcs;
systemd.services.lyrikline = {
after = [ "container@lyrikline.service" ];
wantedBy = [ "container@lyrikline.service" ];
startAt = "*:00/5";
serviceConfig.User = config.users.extraUsers.radio.name;
preStart = "${mpcs.lyrikline}/bin/mpc-lyrikline 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="$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"
${mpcs.lyrikline}/bin/mpc-lyrikline add "$poem_file"
done
${mpcs.lyrikline}/bin/mpc-lyrikline play
'';
};
systemd.services.lyrik = {
after = [ "container@lyrik.service" ];
wantedBy = [ "container@lyrik.service" ];
preStart = "${mpcs.lyrik}/bin/mpc-lyrik crop || :";
restartIfChanged = true;
serviceConfig.User = config.users.extraUsers.radio.name;
script =
let
invidious = "https://invidious.silkky.cloud";
videoIds = import <niveum/lib/hot-rotation/lyrik.nix>;
streams = lib.concatMapStringsSep "\n" (id: "${invidious}/latest_version?id=${id}&itag=251") videoIds;
streamsFile = pkgs.writeText "hotrot" streams;
in ''
set -efu
${mpcs.lyrik}/bin/mpc-lyrik add < ${toString streamsFile}
${mpcs.lyrik}/bin/mpc-lyrik crossfade 5
${mpcs.lyrik}/bin/mpc-lyrik random on
${mpcs.lyrik}/bin/mpc-lyrik repeat on
${mpcs.lyrik}/bin/mpc-lyrik play
'';
};
services.nginx.virtualHosts."radio.kmein.de" = {
enableACME = true;
forceSSL = true;
locations = lib.mkMerge (
[
{ "/".extraConfig = serveHtml (import ./station-list.nix { inherit pkgs lib stations; }) pkgs; }
] ++ (lib.mapAttrsToList (name: station: {
"= /${name}/status".proxyPass = "http://127.0.0.1:${toString htgenPort}";
"= /${name}/listen.ogg".proxyPass = "http://127.0.0.1:${toString station.streamPort}";
"= /${name}.ogg".return = "301 http://radio.xn--kiern-0qa.de/${name}/listen.ogg"; # legacy
}) stations)
);
};
}

View File

@@ -1,43 +0,0 @@
{ pkgs, lib, stations }:
let
theStations = lib.mapAttrsToList (name: value: value // {name = name;}) stations;
in
pkgs.writeText "index.html" ''
<!doctype html>
<html>
<head>
<title>radio.kierán</title>
<link
rel="stylesheet"
href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
</head>
<body>
<main class="section">
<div class="subtitle is-3">Welcome to</div>
<h1 class="title is-1">radio.kierán</h1>
<div class="columns is-multiline">
${lib.concatMapStringsSep "\n" (station: ''
<div class="column">
<div class="box">
<strong class="is-uppercase">${station.name}</strong>
(<a href="/${station.name}/status">status</a>, <a href="/${station.name}/listen.ogg">link</a>)
<p class="has-text-grey">${station.description}</p>
<hr/>
<audio style="width:100%" controls src="/${station.name}/listen.ogg"/>
</div>
</div>'') theStations
}
</div>
</main>
</body>
</html>
''

View File

@@ -12,6 +12,8 @@ let
};
in
{
imports = [ <stockholm/krebs/3modules/htgen.nix> ];
krebs.htgen.tarot = {
port = tarotPort;
user.name = "radio";

View File

@@ -140,7 +140,7 @@ in
systemd.services.urlwatch = {
enable = true;
startAt = "*-*-* 05:00:00";
startAt = "12:00";
script = ''
${urlwatch}/bin/urlwatch \
--config=${lib.escapeShellArg configFile} \

View File

@@ -1,6 +1,6 @@
{
services.grocy = {
enable = true;
enable = false;
hostName = "grocy.kmein.r";
nginx.enableSSL = false;
settings.calendar.firstDayOfWeek = 1;