diff --git a/strichliste.lua b/strichliste.lua
index 927a08a..4e941b9 100755
--- a/strichliste.lua
+++ b/strichliste.lua
@@ -41,13 +41,22 @@ local stylesheet = [[
.amount-neg { color: red; }
nav h2 { display: inline-block }
.notif { padding: 0.5em; margin: 0.5em; background-color: #ddd; }
+ .notif.error { background-color: #faa; }
.notif p { margin: 5px; }
form.box { border: 2px solid grey; padding: 0.5em; margin: 0.5em; display: inline-block; }
form h3 { margin: 5px; }
]]
+-- local script = io.open("main.js"):read("a")
local script = [[
-
+ document.addEventListener("keypress", ev => {
+ if (!(document.activeElement instanceof HTMLInputElement)) {
+ if (ev.code.startsWith("Digit"))
+ document.forms.buy_product.product.value += ev.code.substring(5)
+ if (ev.code == "Enter")
+ document.forms.buy_product.submit()
+ }
+ })
]]
local function respond(status, title, body)
@@ -55,6 +64,7 @@ local function respond(status, title, body)
print("Content-Type: text/html")
print("")
print(string.format([[
+
%s
@@ -88,6 +98,13 @@ local function form_data()
return parse_query(io.read())
end
+local function format_duration(t)
+ if t > 86400 then return string.format("%d days", t / 86400) end
+ if t > 3600 then return string.format("%d hours", t / 3600) end
+ if t > 60 then return string.format("%d minutes", t / 60) end
+ return string.format("%d seconds", t)
+end
+
local function read_log()
local log = io.open("log", "r")
if log == nil then
@@ -126,54 +143,65 @@ local function balances()
end
return users
end
+local function last_txns()
+ local users = {}
+ for time, username, _, _ in read_log() do
+ users[username] = time
+ end
+ return users
+end
-local function r_user()
- if path == nil then
- return respond_error("no path")
- end
- local username = urldecode(path:sub(2))
- if username == nil or username:match("^([%w_ -]+)$") == nil then
- return respond_error("username invalid")
- end
- local notif = nil
- if method == "POST" then
- local data = form_data()
- local amount = nil
- local comment = ""
- if data.barcode then
- for p_barcode, p_amount, p_name in read_products() do
- if p_barcode == data.barcode then
- amount = p_amount
- comment = p_name
- end
+local function error_box(message)
+ return string.format([[]], message)
+end
+
+local function r_user_post(username)
+ local data = form_data()
+ local amount = nil
+ local comment = ""
+ if data.product then
+ for p_barcode, p_amount, p_name in read_products() do
+ if p_barcode == data.product then
+ amount = p_amount
+ comment = p_name
end
- else
- amount = tonumber(data.amount)
- comment = data.comment or ""
end
if amount == nil then
- return respond_error("amount invalid")
+ return error_box("unknown product")
end
- if comment:match("^[%w_ -]*$") == nil then
- return respond_error("comment invalid")
- end
- local log = io.open("log", "a+")
- if log == nil then
- return respond_error("failed to open log")
- end
- local time = os.time()
- log:write(string.format("%d,%s,%d,%s\n", time, username, amount, comment))
- log:flush()
- log:close()
- notif = string.format(
- "Transaction successful: %.02f€ (%s)
",
- amount >= 0 and "pos" or "neg", amount / 100, escape(comment)
- )
+ else
+ amount = tonumber(data.amount)
+ comment = data.comment or ""
end
+ if amount == nil then
+ return error_box("amount invalid")
+ end
+ if comment:match("^[%w_ -]*$") == nil then
+ return error_box("comment invalid")
+ end
+ local log = io.open("log", "a+")
+ if log == nil then
+ return error_box("failed to open log")
+ end
+ local time = os.time()
+ log:write(string.format("%d,%s,%d,%s\n", time, username, amount, comment))
+ log:flush()
+ log:close()
+ return string.format(
+ "Transaction successful: %.02f€ (%s)
",
+ amount >= 0 and "pos" or "neg", amount / 100, escape(comment)
+ )
+end
+local function r_user(username)
+ local notif = nil
+ if method == "POST" then
+ notif = r_user_post(username)
+ end
return respond(200, username, function()
print(string.format("%s
", username))
local balance = balances()[username]
+ local last_txn = last_txns()[username]
local new_user = balance == nil
balance = balance or 0
if new_user then
@@ -181,11 +209,13 @@ local function r_user()
This user account does not exist yet. It will only be created after the first transaction.
]])
end
- if notif then
- print(notif)
- end
- print(string.format("Current balance: %.02f€
", balance >= 0 and "pos" or "neg",
- balance / 100))
+ if notif then print(notif) end
+ print(string.format([[
+ Current balance: %.02f€
+ ]], balance >= 0 and "pos" or "neg", balance / 100))
+ print(string.format([[
+ Last transaction added %s ago. View user log
+ ]], format_duration(os.time() - last_txn), username))
print([[
+
]])
print("")
for _, type in ipairs({ 1, -1 }) do
@@ -214,14 +250,20 @@ local function r_user()
end)
end
-local function r_log()
+local function r_log(filter)
return respond(200, "Log", function()
print("
")
print("Time | Username | Amount | Comment |
")
for time, username, amount, comment in read_log() do
- print(string.format("%d | %s | %.02f€ | %s |
", time,
- escape(username),
- amount >= 0 and "pos" or "neg", amount / 100, escape(comment)))
+ if filter == nil or filter == username then
+ print(string.format(
+ "%d (%s ago) | %s | %.02f€ | %s |
",
+ time, format_duration(os.time() - time),
+ escape(username),
+ amount >= 0 and "pos" or "neg", amount / 100,
+ escape(comment)
+ ))
+ end
end
print("
")
end)
@@ -254,6 +296,17 @@ local function r_create_user()
return redirect(string.format("/%s", urlencode(username)))
end
+local function extract_username()
+ if path == nil then
+ return respond_error("no path")
+ end
+ local username = urldecode(path:sub(2))
+ if username == nil or username:match("^([%w_ -]+)$") == nil then
+ return nil
+ end
+ return username
+end
+
if path == "/" then
if query.log then
return r_log()
@@ -263,5 +316,12 @@ if path == "/" then
return r_index()
end
else
- return r_user()
+ local username = extract_username()
+ if username == nil then
+ return respond_error("username invalid")
+ elseif query.log then
+ return r_log(username)
+ else
+ return r_user(username)
+ end
end