registrar

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 88fc57f349e126354685a00c87b7554cf7da9e06
parent 3ab4383573bd650af7925c64673174892ea72ad9
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date:   Fri,  1 Sep 2023 11:25:54 -0300

Port monthly and weekly scripts to Lua

Diffstat:
Alog.json | 1+
Mmonthly/history.m4 | 2+-
Mmonthly/monthly.m4 | 5++++-
Mmonthly/news.m4 | 3+--
Mregistrar.fish | 34----------------------------------
Aregistrar.lua | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dscripts/monthly.fish | 13-------------
Dscripts/weekly.fish | 47-----------------------------------------------
Mweekly/news.m4 | 3++-
Mweekly/players.m4 | 2+-
Mweekly/weekly.m4 | 6+++++-
11 files changed, 197 insertions(+), 101 deletions(-)

diff --git a/log.json b/log.json @@ -0,0 +1 @@ +{"when": 1693578212, "what": "monthly"} diff --git a/monthly/history.m4 b/monthly/history.m4 @@ -9,4 +9,4 @@ at least once (imperfect, corrections welcomed) e(x)iled (s)till registered (b)anned -esyscmd(`lua monthly/format.lua') +PLAYERS diff --git a/monthly/monthly.m4 b/monthly/monthly.m4 @@ -4,8 +4,11 @@ define(shl, `------------------------------------------------------------------- define(module, shl`$1 include($2)')dnl +Date: MAILDATE +`To: <agora-official@agoranomic.org>' +`Subject: [Registrar] Monthly report: Arrivals and Departures' dhl -`Registrar: juan Arrivals and Departures 'esyscmd(date +%Y-%m-%d | tr -d '\n') +`Registrar: juan Arrivals and Departures 'YEAR-MONTH-DAY dhl module(NEWS, monthly/news.m4) diff --git a/monthly/news.m4 b/monthly/news.m4 @@ -1 +1 @@ -No news. -\ No newline at end of file +# The news. diff --git a/registrar.fish b/registrar.fish @@ -5,48 +5,14 @@ argparse 'h/help' -- $argv function usage echo 'usage: ./registrar.fish COMMAND' echo 'commands:' - echo ' weekly' - echo ' monthly' echo ' birthday' end -function guessmonthly - # No monthly published this month - set cur_month (date +%Y-%m) - grep -q "\[$cur_month-..\] Published monthly report." log.txt - or echo monthly -end - -function guessweekly - test (date +%u) = 1 - and set reference (date -d '00:00' +%s) - or set reference (date -d 'last monday' +%s) - grep "\[....-..-..\] Published weekly report." log.txt | - grep -o "\[....-..-..\]" | - grep -o "....-..-.." | - while read d - set candidate (date -d $d +%s) - test $candidate -ge $reference - and return - end - echo weekly -end - -function guess - guessmonthly - guessweekly - # guessbirthday -end - test "$argv[1]" = guess -o -z "$argv[1]" and set argv (guess) for c in $argv switch $c - case weekly - source 'scripts/weekly.fish' - case monthly - source 'scripts/monthly.fish' case birthday source 'scripts/birthday.fish' end diff --git a/registrar.lua b/registrar.lua @@ -0,0 +1,182 @@ +#!/usr/bin/lua5.4 +local argparse = require "argparse" +local json = require "json" +local path = require "path" +-- local fs = require "path.fs" + +function die(err, msg) + msg = tostring(msg or err) + if err then + io.stderr:write(msg .. "\n") + os.exit(1) + end +end + +function yn(prompt) + meaning = {Y = true, y = true, n = false, N = false} + while meaning[ans] == nil do + io.write(prompt) + io.flush() -- For some reason, prompt doesn't show up without this + ans = io.read(1) + end + return ans +end + +function decodewith(decoder, fn) + die(not path.exists(fn), fn.." does not exist.") + die(not path.isfile(fn), fn.." is not a file.") + local f, err = io.open(fn, "r") + die(err) + status, res = xpcall(decoder, die, f:read("a")) + f:close() + die(not status, res) + return res +end + +function encodewith(encoder, fn, data) + local f, err = io.open(fn, "w") + die(not status, err) + status, err = f:write(encoder(data)) + die(not status, err) +end + +function format(fmt, dict, sett) + -- A identifier is + -- > any string of Latin letters, Arabic-Indic digits, and + -- > underscores, not beginning with a digit and not being a reserved + -- > word + res = fmt + for s in string.gmatch(fmt, "%{([_a-zA-Z][._a-zA-Z0-9]*)%}") do + local value = dict + local pref = sett + for k in string.gmatch(s, "([_a-zA-Z][_a-zA-Z0-9]*)") do + if type(value) == "table" then value = value[k] end + if type(pref) == "table" then pref = pref[k] end + end + if pref and value then string.format(pref, value) end + res = fmt.gsub(res, "{"..s.."}", value or "nil") + end + return res +end + +function m4flags(d) + flags = "" + for k, v in pairs(d) do + flags = flags .. string.format(" -D %s='%s'", k, v) + end + return flags +end + +local parser = argparse("registrar", "Manage Agora's registrar duties") + :command_target("command") + +parser:command("monthly", "Generate and send registrar monthly report") + :flag("-p", "Pretent: generate and print only.") +parser:command("weekly", "Generate and send registrar weekly report") + :flag("-p", "Pretent: generate and print only.") + +local birthday_cmd = parser:command("birthday", "Announce a player's birthday") +birthday_cmd:flag("-p", "Pretent: generate and print only.") +birthday_cmd:argument("name", "The name of the player") + +parser:command("register", "Register player") +parser:command("deregister", "Deregister player") +parser:command("activate", "Activate player") +parser:command("deactivate", "Deactivate player") +parser:command("rename", "Rename player") +parser:command("readdress", "Change player's address") + +-- Deserialize +local fns = { + players = "players.json", + log = "log.json", + tmp = ".tmp", + history = ".hist" +} +local args = parser:parse() +local players = decodewith(json.decode, fns.players) + +-- Process + +if args.command == "monthly" then + local hist = io.open(fns.history, "w") + + defs = { + YEAR = os.date("%Y"), + MONTH = os.date("%m"), + DAY = os.date("%d"), + MAILDATE = os.date("%a, %d %b %Y %T %z"), + PLAYERS = string.format("include(%s)", fns.history) + } + for n,h in pairs(players) do + hist:write("===============\n"..n.."\n") + for _,e in ipairs(h) do + if e.reason == "s" then + f = " ({reason}) {name} <{contact}> ({registration}--now)\n" + else + f = " ({reason}) {name} <{contact}> ({registration}--{deregistration})\n" + end + hist:write(format(f, e)) + if e.observations then + hist:write(format(" {observations}\n", e)) + end + end + hist:write("\n") + end + hist:close() + + os.execute(string.format("m4 %s monthly/monthly.m4 > %s", m4flags(defs), fns.tmp)) + + if args.p then + os.execute(string.format("cat %s", fns.tmp)) + os.remove(fns.tmp) + else + os.execute(string.format("vis %s", fns.tmp)) + os.execute(string.format("neomutt -H %s -E", fns.tmp)) + if yn("Archive report? [Yn] ") then + table.insert(log, { + when = os.time(), + what = "monthly" + }) + os.rename(tmpname, os.date("archive/%F-monthly.txt")) + else + os.remove(fns.tmp) + end + end + os.remove(fns.history) +elseif args.command == "weekly" then + defs = { + YEAR = os.date("%Y"), + MONTH = os.date("%m"), + DAY = os.date("%d"), + MAILDATE = os.date("%a, %d %b %Y %T %z"), + } + + os.execute(string.format("m4 %s weekly/weekly.m4 > %s", m4flags(defs), fns.tmp)) + if args.p then + os.execute(string.format("cat %s", fns.tmp)) + os.remove(fns.tmp) + else + os.execute(string.format("vis %s", fns.tmp)) + os.execute(string.format("neomutt -H %s -E", fns.tmp)) + if yn("Archive report? [Yn] ") then + table.insert(log, { + when = os.time(), + what = "weekly", + height = height, + }) + os.rename(tmpname, os.date("archive/%F-weekly.txt")) + else + os.remove(fns.tmp) + end + end + os.remove(fns.history) +elseif args.command == "birthday" then + io.write("Birthdays not implemented. Use registrar.fish\n") +else + io.write("Not implemented.") +end + +-- Serialize +encodewith(json.encode, fns.players, players) +encodewith(json.encode, fns.log, log) diff --git a/scripts/monthly.fish b/scripts/monthly.fish @@ -1,13 +0,0 @@ -#!/usr/bin/fish - -set tmp (mktemp) - -begin -echo 'Date: '(date -R) -echo 'From: juan <juan@juanmeleiro.mat.br>' -echo 'To: <agora-official@agoranomic.org>' -echo 'Subject: [Registrar] Monthly report: Arrivals and Departures' -m4 monthly/monthly.m4 -end > $tmp -neomutt -E -H $tmp -mv $tmp archive/(date --iso-8601=date)-monthly.txt diff --git a/scripts/weekly.fish b/scripts/weekly.fish @@ -1,47 +0,0 @@ -#!/usr/bin/fish - -set tmp (mktemp) - -begin -echo 'Date: '(date -R) -echo 'From: juan <juan@juanmeleiro.mat.br>' -echo 'To: <agora-official@agoranomic.org>' -echo 'Subject: [Registrar] Weekly report' -m4 weekly/weekly.m4 -end > $tmp -neomutt -E -H $tmp -set today (date --iso-8601=date) -read -n 1 -P 'Archive? [Yn] ' ans -contains "$ans" n N no No NO -or begin - mv $tmp archive/$today-weekly.txt - echo "[$today] Published weekly report." >> log.txt -end - -if jq -e '[.[][] | select(has("active") and (.active | not))] | length > 0' players.json > /dev/null - jq -r '.[][] | select(has("active") and (.active | not)) | .name' players.json - read -P 'This players are to be deregistered. Do it? [Yn]' -n 1 ans - if contains "$ans" n N no No NO - exit 0 - end -else - exit 0 -end - -set tmp (mktemp) - -begin -echo 'Date: '(date -R) -echo 'From: juan <juan@juanmeleiro.mat.br>' -echo 'To: <agora-official@agoranomic.org>' -echo 'Subject: [Registrar] Deregistration intents' -jq -rf scripts/deregistrations.jq players.json -end > $tmp -neomutt -E -H $tmp -rm $tmp -mv $tmp archive/(date --iso-8601=date)-deregistration.txt - -begin -echo 'TODO Deregister players in Agora' -date -d 'now + 4 days' +'SCHEDULED: <%Y-%m-%d %a>' -end | capture -i diff --git a/weekly/news.m4 b/weekly/news.m4 @@ -1 +1 @@ -No news. +# The news. +\ No newline at end of file diff --git a/weekly/players.m4 b/weekly/players.m4 @@ -1,6 +1,6 @@ Active players: esyscmd(jq -r '[.[][] | select(.reason == "s")] | "\([.[] | select(.active == true)] | length)/\(length)"' players.json)dnl -esyscmd(jq -r '[.[][] | select(.reason == "s")] | sort_by(.active | not)[] | "\(if .active then "+" else "-" end)=\(.name)=\(.registration)=\(.latest // " \" ")=\(.contact)"' players.json | columnate -s = -n a Player Registration Latest Contact)dnl +esyscmd(jq -r '[.[][] | select(.reason == "s")] | sort_by(.active | not)[] | "\(if .active then "+" else "-" end)\t\(.name)\t\(.registration)\t\(.latest // " \" ")\t\(.contact)"' players.json | columnate -n a Player Registration Latest Contact)dnl WARNING: Player name “blob” refers to the currently registered one, who became a player on 2023-05-18, and not blob the player from many diff --git a/weekly/weekly.m4 b/weekly/weekly.m4 @@ -4,8 +4,12 @@ define(shl, `------------------------------------------------------------------- define(module, shl`$1 include($2)')dnl +Date: MAILDATE +`To: <agora-official@agoranomic.org>' +`From: juan <juan@juanmeleiro.mat.br>' +`Subject: [Registrar] Weekly report' dhl -`Registrar: juan The Agoran Directory 'esyscmd(date +%Y-%m-%d | tr -d '\n') +`Registrar: juan The Agoran Directory 'YEAR-MONTH-DAY dhl module(NEWS, weekly/news.m4)