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:
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)