summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlassulus <lassulus@lassul.us>2021-07-29 15:37:06 +0200
committerlassulus <lassulus@lassul.us>2021-07-29 15:37:06 +0200
commita59ca4ac80248585facd8cc43d0a8b8d43e3735d (patch)
treeff4f4a77705eb30a09654d7feacc290998af0dbd
parentd14077b06e82d7e4beb078d781a312c84f0a16db (diff)
reaktor2: add agenda.r webinterface
-rw-r--r--krebs/2configs/reaktor2.nix141
1 files changed, 132 insertions, 9 deletions
diff --git a/krebs/2configs/reaktor2.nix b/krebs/2configs/reaktor2.nix
index 14e0a3d7..2fb7a54e 100644
--- a/krebs/2configs/reaktor2.nix
+++ b/krebs/2configs/reaktor2.nix
@@ -9,11 +9,11 @@ let
hooks = pkgs.reaktor2-plugins.hooks;
commands = pkgs.reaktor2-plugins.commands;
- task = name: let
- rcFile = builtins.toFile "taskrc" ''
- confirmation=no
- '';
- in {
+ taskRcFile = builtins.toFile "taskrc" ''
+ confirmation=no
+ '';
+
+ task = name: {
pattern = "^${name}-([a-z]+)(?::?\\s*(.*))?";
activate = "match";
command = 1;
@@ -21,19 +21,19 @@ let
env.TASKDATA = "${stateDir}/${name}";
commands = {
add.filename = pkgs.writeDash "${name}-task-add" ''
- ${pkgs.taskwarrior}/bin/task rc:${rcFile} add "$1"
+ ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} add "$1"
'';
list.filename = pkgs.writeDash "${name}-task-list" ''
- ${pkgs.taskwarrior}/bin/task rc:${rcFile} export \
+ ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export \
| ${pkgs.jq}/bin/jq -r '
.[] | select(.id != 0) | "\(.id) \(.description)"
'
'';
delete.filename = pkgs.writeDash "${name}-task-delete" ''
- ${pkgs.taskwarrior}/bin/task rc:${rcFile} delete "$1"
+ ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} delete "$1"
'';
done.filename = pkgs.writeDash "${name}-task-done" ''
- ${pkgs.taskwarrior}/bin/task rc:${rcFile} done "$1"
+ ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} done "$1"
'';
};
};
@@ -122,6 +122,129 @@ in {
isSystemUser = true;
};
+ 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" = {
+ 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")) {
+ fetch(params["style"])
+ .then((response) =>
+ response.text().then((css) => {
+ const title = document.getElementsByTagName("title")[0];
+ const style = document.createElement("style");
+ style.appendChild(document.createTextNode(css));
+ title.appendChild(style);
+ })
+ )
+ .catch(console.log);
+ }
+
+ 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 dd = document.createElement("dd");
+ dd.className = "description";
+ dd.appendChild(document.createTextNode(agendaItem.description));
+ 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';
+ '';
+ };
+ };
+
krebs.reaktor2 = {
hackint = {
hostname = "irc.hackint.org";