commit 6f38e6d417536b97296b51572d1aa7170d43de44
parent 80e53b31df8cfd4788a927b3f726ccac82205b31
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date: Wed, 18 Dec 2024 16:18:24 -0300
Split script into files
Diffstat:
| M | absurdor | | | 137 | ++----------------------------------------------------------------------------- |
| A | lib/log.lua | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | lib/util.lua | | | 77 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 141 insertions(+), 134 deletions(-)
diff --git a/absurdor b/absurdor
@@ -1,144 +1,13 @@
#!/usr/bin/env lua5.4
+
local argparse = require "argparse"
local json = require "json"
local path = require "path"
local fs = require "path.fs"
-local date = require "date"
local pprint = require("pprint").pprint
-function die(err, msg, ...)
- msg = tostring(msg or err)
- if err then
- io.stderr:write(string.format(msg .. "\n", ...))
- os.exit(1)
- end
-end
-
-function maildate(s)
- local d = date(s)
- local sec = date.diff(d, date.epoch()):spanseconds()
- return sec
-end
-
-function yn(prompt)
- meaning = {Y = true, y = true, n = false, N = false}
- while meaning[ans] == nil do
- io.write(prompt)
- io.flush()
- ans = io.read(1)
- end
- return meaning[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
-
- -- local reserved = {
- -- "and", "break", "do", "else", "elseif", "end", "false", "for",
- -- "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat",
- -- "return", "then", "true", "until", "while"
- -- }
- 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 is_valid_entry(e)
- return (
- (e.what ~= nil) and
- (e.when ~= nil) and
- (e.what ~= "push" or e.who ~= nil) and
- (e.what ~= "report" or e.height ~= nil)
- )
-end
-
-function parse_jsonl(f)
- local log = {}
- for l in f:lines() do
- local e = json.decode(l)
- die(not is_valid_entry(e), string.format("Invalid log entry:\n %s", l))
- table.insert(log, e)
- end
- return log
-end
-
-function write_jsonl(l)
- local res = ""
- for _,v in ipairs(l) do
- res = res .. json.encode(v) .. "\n"
- end
- return res
-end
-
-function fmt_event(e)
- date = os.date("!%Y-%m-%d %H:%M:%S %z", e.when)
- args = {ts = date}
- if e.what == "report" then
- fmt = "[{ts}] Reported boulder at height {height}"
- args.height = e.height
- elseif e.what == "push" then
- fmt = "[{ts}] {who} pushed the boulder"
- args.who = e.who
- elseif e.what == "transfer" then
- fmt = "[{ts}] {who} transfered the Veblen for {payed}"
- args.who = e.who
- args.payed= e.payed
- elseif e.what == "devalue" then
- fmt = "[{ts}] {who} devalued the Veblen to {value}"
- args.who = e.who
- args.value = e.value
- else
- die(true, "Unknown event type '%s'", e.what)
- end
- return format(fmt, args)
-end
-
-function sec2week(s)
- return math.floor(s/(24 * 60 * 60 * 7))
-end
-
-function week2sec(w)
- return w*24*60*60*7
-end
-
-function is_duplicate(ts, log)
- for _,e in ipairs(log) do
- if e.when == ts then
- return true
- end
- end
- return false
-end
+require "lib.util"
+require "lib.log"
local parser = argparse("absurdor", "Manage Absurdor duties")
:command_target("command")
diff --git a/lib/log.lua b/lib/log.lua
@@ -0,0 +1,61 @@
+require "lib.util"
+
+function is_valid_entry(e)
+ return (
+ (e.what ~= nil) and
+ (e.when ~= nil) and
+ (e.what ~= "push" or e.who ~= nil) and
+ (e.what ~= "report" or e.height ~= nil)
+ )
+end
+
+function parse_jsonl(f)
+ local log = {}
+ for l in f:lines() do
+ local e = json.decode(l)
+ die(not is_valid_entry(e), string.format("Invalid log entry:\n %s", l))
+ table.insert(log, e)
+ end
+ return log
+end
+
+function write_jsonl(l)
+ local res = ""
+ for _,v in ipairs(l) do
+ res = res .. json.encode(v) .. "\n"
+ end
+ return res
+end
+
+function fmt_event(e)
+ date = os.date("!%Y-%m-%d %H:%M:%S %z", e.when)
+ args = {ts = date}
+ if e.what == "report" then
+ fmt = "[{ts}] Reported boulder at height {height}"
+ args.height = e.height
+ elseif e.what == "push" then
+ fmt = "[{ts}] {who} pushed the boulder"
+ args.who = e.who
+ elseif e.what == "transfer" then
+ fmt = "[{ts}] {who} transfered the Veblen for {payed}"
+ args.who = e.who
+ args.payed= e.payed
+ elseif e.what == "devalue" then
+ fmt = "[{ts}] {who} devalued the Veblen to {value}"
+ args.who = e.who
+ args.value = e.value
+ else
+ die(true, "Unknown event type '%s'", e.what)
+ end
+ return format(fmt, args)
+end
+
+function is_duplicate(ts, log)
+ for _,e in ipairs(log) do
+ if e.when == ts then
+ return true
+ end
+ end
+ return false
+end
+
diff --git a/lib/util.lua b/lib/util.lua
@@ -0,0 +1,77 @@
+local date = require "date"
+local path = require "path"
+
+function die(err, msg, ...)
+ msg = tostring(msg or err)
+ if err then
+ io.stderr:write(string.format(msg .. "\n", ...))
+ os.exit(1)
+ end
+end
+
+function maildate(s)
+ local d = date(s)
+ local sec = date.diff(d, date.epoch()):spanseconds()
+ return sec
+end
+
+function yn(prompt)
+ meaning = {Y = true, y = true, n = false, N = false}
+ while meaning[ans] == nil do
+ io.write(prompt)
+ io.flush()
+ ans = io.read(1)
+ end
+ return meaning[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
+
+ -- local reserved = {
+ -- "and", "break", "do", "else", "elseif", "end", "false", "for",
+ -- "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat",
+ -- "return", "then", "true", "until", "while"
+ -- }
+ 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 sec2week(s)
+ return math.floor(s/(24 * 60 * 60 * 7))
+end
+
+function week2sec(w)
+ return w*24*60*60*7
+end