stockholm/krebs/2configs/reaktor2.nix

507 lines
14 KiB
Nix
Raw Normal View History

2019-01-27 02:34:47 +00:00
with import <stockholm/lib>;
{ config, pkgs, ... }:
let
#for shared state directory
2019-01-27 02:34:47 +00:00
stateDir = config.krebs.reaktor2.r.stateDir;
generators = pkgs.reaktor2-plugins.generators;
hooks = pkgs.reaktor2-plugins.hooks;
commands = pkgs.reaktor2-plugins.commands;
# bedger - the bier ledger
#
# logo: http://c.r/bedger2
#
bedger-add = {
pattern = ''^([\H-]*?):?\s+([+-][1-9][0-9]*)\s+(\S+)$'';
activate = "match";
arguments = [1 2 3];
command = {
env = {
# TODO; get state as argument
state_file = "${stateDir}/ledger";
};
filename = pkgs.writeDash "bedger-add" ''
set -x
tonick=$1
amt=$2
unit=$3
printf '%s\n %s %d %s\n %s %d %s\n' "$(date -Id)" "$tonick" "$amt" "$unit" "$_from" "$(expr 0 - "''${amt#+}")" "$unit" >> $state_file
${pkgs.hledger}/bin/hledger -f $state_file bal -N -O csv \
| ${pkgs.coreutils}/bin/tail +2 \
| ${pkgs.miller}/bin/mlr --icsv --opprint cat \
| ${pkgs.gnugrep}/bin/grep "$_from"
'';
};
};
bedger-balance = {
pattern = "^bier (ballern|bal(an(ce)?)?)$";
activate = "match";
command = {
env = {
state_file = "${stateDir}/ledger";
};
filename = pkgs.writeDash "bedger-balance" ''
${pkgs.hledger}/bin/hledger -f $state_file bal -N -O csv \
| ${pkgs.coreutils}/bin/tail +2 \
| ${pkgs.miller}/bin/mlr --icsv --opprint cat \
| ${pkgs.gnused}/bin/sed 's/^\(.\)/\1/'
'';
};
};
2022-11-21 14:29:07 +00:00
confuse = {
pattern = "^!confuse (.*)$";
activate = "match";
arguments = [1];
command = {
filename = pkgs.writeDash "confuse" ''
set -efux
export PATH=${makeBinPath [
pkgs.coreutils
pkgs.curl
pkgs.stable-generate
]}
paste_url=$(stable-generate "$@" |
curl -Ss http://p.r --data-binary @- |
tail -1
)
echo "$_from: $paste_url"
'';
};
};
confuse_hackint = {
2022-11-21 14:29:07 +00:00
pattern = "^!confuse (.*)$";
activate = "match";
arguments = [1];
command = {
filename = pkgs.writeDash "confuse" ''
set -efu
export PATH=${makeBinPath [
pkgs.coreutils
pkgs.curl
pkgs.stable-generate
]}
case $_msgtarget in \#*)
paste_url=$(stable-generate "$@" |
curl -Ss https://p.krebsco.de --data-binary @- |
tail -1
)
echo "$_from: $paste_url"
esac
2022-11-21 14:29:07 +00:00
'';
};
};
2022-11-27 23:20:34 +00:00
say = {
pattern = "^!say (.*)$";
activate = "match";
arguments = [1];
command = {
filename = pkgs.writeDash "say" ''
set -efu
export PATH=${makeBinPath [
pkgs.coreutils
pkgs.curl
pkgs.opusTools
]}
paste_url=$(printf '%s' "$1" |
curl -fSsG http://tts.r/api/tts --data-urlencode 'text@-' |
opusenc - - |
curl -Ss https://p.krebsco.de --data-binary @- |
tail -1
)
echo "$_from: $paste_url"
'';
};
};
2021-07-29 13:37:06 +00:00
taskRcFile = builtins.toFile "taskrc" ''
confirmation=no
'';
task = name: {
2020-06-23 07:53:21 +00:00
pattern = "^${name}-([a-z]+)(?::?\\s*(.*))?";
activate = "match";
command = 1;
arguments = [2];
2019-01-27 19:32:04 +00:00
env.TASKDATA = "${stateDir}/${name}";
commands = {
2019-01-27 19:32:04 +00:00
add.filename = pkgs.writeDash "${name}-task-add" ''
2021-07-29 13:37:06 +00:00
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} add "$1"
2019-01-27 19:32:04 +00:00
'';
list.filename = pkgs.writeDash "${name}-task-list" ''
2021-07-29 13:37:06 +00:00
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export \
2019-01-27 19:32:04 +00:00
| ${pkgs.jq}/bin/jq -r '
.[] | select(.id != 0) | "\(.id) \(.description)"
'
'';
delete.filename = pkgs.writeDash "${name}-task-delete" ''
2021-07-29 13:37:06 +00:00
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} delete "$1"
2019-01-27 19:32:04 +00:00
'';
done.filename = pkgs.writeDash "${name}-task-done" ''
2021-07-29 13:37:06 +00:00
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} done "$1"
2019-01-27 19:32:04 +00:00
'';
2019-01-27 02:34:47 +00:00
};
};
2022-10-18 21:44:02 +00:00
locationsLib = pkgs.writeText "locations.sh" ''
ENDPOINT=http://c.r/poi.json
get_locations() {
curl -fsS "$ENDPOINT"
}
set_locations() {
curl -fSs --data-binary @- "$ENDPOINT"
}
set_location() {
[ $# -eq 3 ] || return 1
get_locations \
| jq \
--arg name "$1" \
--arg latitude "$2" \
--arg longitude "$3" \
'.[$name] = { $latitude, $longitude }' \
| set_locations
}
get_location() {
[ $# -eq 1 ] || return 1
get_locations | jq --arg name "$1" '.[$name]'
}
delete_location() {
[ $# -eq 1 ] || return 1
get_locations | jq --arg name "$1" 'del(.[$name])' | set_locations
}
'';
systemPlugin = { extra_privmsg_hooks ? [] }: {
2019-01-27 02:34:47 +00:00
plugin = "system";
config = {
workdir = stateDir;
hooks.JOIN = [
{
activate = "always";
command = {
filename =
2021-09-14 17:10:16 +00:00
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_join.sh>;
2019-01-27 02:34:47 +00:00
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX env, touch
pkgs.jq # XXX sed
2022-09-27 10:26:37 +00:00
pkgs.util-linux # XXX flock
2019-01-27 02:34:47 +00:00
];
state_file = "${stateDir}/tell.json";
};
};
}
];
hooks.PRIVMSG = [
2022-10-18 21:44:02 +00:00
{
pattern = "^list-locations";
activate = "match";
command = {
filename = pkgs.writeDash "list-locations" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
]}
set -efu
set -x
. ${locationsLib}
get_locations | jq -r 'to_entries[]|"\(.key) \(.value.latitude),\(.value.longitude)"'
'';
};
}
{
pattern = ''^add-location (\S+) ([0-9.]+),([0-9.]+)$'';
activate = "match";
arguments = [1 2 3];
command = {
filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
]}
set -efu
set -x
. ${locationsLib}
set_location "$1" $2 $3
'';
};
}
{
pattern = ''^delete-location (\S+)$'';
activate = "match";
arguments = [1];
command = {
filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [
pkgs.curl
pkgs.jq
]}
set -efu
set -x
. ${locationsLib}
delete_location "$1"
'';
};
}
2022-10-04 09:34:40 +00:00
{
pattern = ''^18@p\s+(\S+)\s+(\d+)m$'';
2022-10-04 09:34:40 +00:00
activate = "match";
arguments = [1 2];
2022-10-04 09:34:40 +00:00
command = {
2022-10-04 17:16:58 +00:00
env = {
CACHE_DIR = "${stateDir}/krebsfood";
2022-10-04 17:16:58 +00:00
};
filename =
let
osm-restaurants-src = pkgs.fetchFromGitHub {
owner = "kmein";
repo = "scripts";
rev = "dda381be26abff73a0cf364c6dfff6e1701f41ee";
sha256 = "sha256-J7jGWZeAULDA1EkO50qx+hjl+5IsUj389pUUMreKeNE=";
};
osm-restaurants = pkgs.callPackage "${osm-restaurants-src}/osm-restaurants" {};
in pkgs.writeDash "krebsfood" ''
2022-10-04 09:34:40 +00:00
set -efu
2022-11-21 15:02:33 +00:00
export PATH=${makeBinPath [
osm-restaurants
pkgs.coreutils
pkgs.curl
pkgs.jq
]}
poi=$(curl -fsS http://c.r/poi.json | jq --arg name "$1" '.[$name]')
if [ "$poi" = null ]; then
latitude=52.51252
longitude=13.41740
else
latitude=$(echo "$poi" | jq -r .latitude)
longitude=$(echo "$poi" | jq -r .longitude)
fi
restaurant=$(osm-restaurants --radius "$2" --latitude "$latitude" --longitude "$longitude")
printf '%s' "$restaurant" | tail -1 | jq -r '"How about \(.tags.name) (https://www.openstreetmap.org/\(.type)/\(.id)), open \(.tags.opening_hours)?"'
2022-10-04 09:34:40 +00:00
'';
};
}
bedger-add
bedger-balance
2019-01-27 02:34:47 +00:00
hooks.sed
2022-11-27 23:20:34 +00:00
say
2019-01-27 02:34:47 +00:00
(generators.command_hook {
2022-01-25 20:47:23 +00:00
inherit (commands) dance random-emoji nixos-version;
2019-01-27 02:34:47 +00:00
tell = {
filename =
2021-09-14 17:10:16 +00:00
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh>;
2019-01-27 02:34:47 +00:00
env = {
PATH = makeBinPath [
pkgs.coreutils # XXX date, env
pkgs.jq # XXX sed
2022-09-27 10:26:37 +00:00
pkgs.util-linux # XXX flock
2019-01-27 02:34:47 +00:00
];
state_file = "${stateDir}/tell.txt";
};
};
})
(task "agenda")
] ++ extra_privmsg_hooks;
2019-01-27 02:34:47 +00:00
};
};
in {
2019-04-23 18:05:03 +00:00
users.users.reaktor2 = {
uid = genid_uint31 "reaktor2";
home = stateDir;
2021-06-05 12:14:56 +00:00
isSystemUser = true;
extraGroups = [ "reaktor2" ];
2019-04-23 18:05:03 +00:00
};
users.groups.reaktor2 = {};
2021-07-29 13:37:06 +00:00
systemd.services.htgen-agenda.serviceConfig.StateDirectory = "reaktor2";
krebs.htgen.agenda = {
port = 8009;
user = {
name = "reaktor2";
home = stateDir;
};
script = ''. ${pkgs.writeDash "agenda" ''
echo "$Method $Request_URI" >&2
case "$Method" in
"GET")
printf 'HTTP/1.1 200 OK\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
TASKDATA=/var/lib/reaktor2/agenda ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export
exit
;;
esac
''}'';
};
services.nginx = {
virtualHosts."agenda.r" = {
2022-05-28 14:20:56 +00:00
serverAliases = [ "kri.r" ];
2021-07-29 13:37:06 +00:00
locations."= /index.html".extraConfig = ''
alias ${pkgs.writeText "agenda.html" ''
<!DOCTYPE html>
<html>
<head>
<title>Agenda</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
html {
font-family: monospace;
}
dt {
float: left;
clear: left;
width: 30px;
text-align: right;
font-weight: bold;
}
dd {
margin: 0 0 0 40px;
padding: 0 0 0.5em 0;
}
.date {
color: grey;
font-style: italic;
}
</style>
</head>
<body>
<dl id="agenda"></dl>
<script>
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
if (params.hasOwnProperty("style")) {
const cssUrls = params["style"].split(" ").filter((x) => x.length > 0);
for (const cssUrl of cssUrls)
fetch(cssUrl)
.then((response) =>
response.text().then((css) => {
const title = document.getElementsByTagName("head")[0];
const style = document.createElement("style");
style.appendChild(document.createTextNode(css));
title.appendChild(style);
})
)
.catch(console.log);
2021-07-29 13:37:06 +00:00
}
fetch("/agenda.json")
.then((response) => {
response.json().then((agenda) => {
const dl = document.getElementById("agenda");
for (const agendaItem of agenda) {
if (agendaItem.status !== "pending") continue;
// task warrior date format to ISO
const entryDate = agendaItem.entry.replace(
/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z/,
"$1-$2-$3T$4:$5:$6Z"
);
const dt = document.createElement("dt");
dt.className = "id";
dt.appendChild(document.createTextNode(agendaItem.id.toString()));
dl.appendChild(dt);
const spanDate = document.createElement("span");
spanDate.className = "date";
spanDate.title = new Date(entryDate).toString();
spanDate.appendChild(document.createTextNode(entryDate));
const link = document.createElement("a");
link.href = "http://wiki.r/agenda/" + encodeURIComponent(agendaItem.description.replaceAll("/", "\u29F8")); // we use big solidus instead of slash because gollum will create directories
link.appendChild(document.createTextNode(agendaItem.description));
2021-07-29 13:37:06 +00:00
const dd = document.createElement("dd");
dd.className = "description";
dd.appendChild(link);
2021-07-29 13:37:06 +00:00
dd.appendChild(document.createTextNode(" "));
dd.appendChild(spanDate);
dl.appendChild(dd);
}
});
})
.then((data) => console.log(data));
</script>
</body>
</html>
''};
'';
locations."/agenda.json".extraConfig = ''
proxy_set_header Host $host;
proxy_pass http://localhost:8009;
'';
extraConfig = ''
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
'';
};
};
systemd.services.reaktor2-r.serviceConfig.DynamicUser = mkForce false;
systemd.services.reaktor2-hackint.serviceConfig.DynamicUser = mkForce false;
2019-01-27 02:34:47 +00:00
krebs.reaktor2 = {
2021-05-20 08:57:27 +00:00
hackint = {
hostname = "irc.hackint.org";
nick = "reaktor2|krebs";
plugins = [
{
plugin = "register";
config = {
channels = [
"#krebs"
];
};
}
(systemPlugin {
extra_privmsg_hooks = [
confuse_hackint
];
})
2021-05-20 08:57:27 +00:00
];
2021-05-20 10:54:30 +00:00
username = "reaktor2";
2021-05-20 08:57:27 +00:00
port = "6697";
};
2019-01-27 02:34:47 +00:00
r = {
nick = "reaktor2|krebs";
2019-01-29 20:39:16 +00:00
sendDelaySec = null;
2019-01-27 02:34:47 +00:00
plugins = [
{
plugin = "register";
config = {
channels = [
"#noise"
"#xxx"
];
};
}
(systemPlugin {
extra_privmsg_hooks = [
confuse
];
})
2019-01-27 02:34:47 +00:00
];
username = "reaktor2";
2019-01-27 02:34:47 +00:00
};
};
}