reaktor2: add agenda.r webinterface
This commit is contained in:
parent
d14077b06e
commit
a59ca4ac80
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user