aboutsummaryrefslogtreecommitdiff
path: root/strichliste.lua
blob: 6ad7d5f232f0f0a1760507af39fa23846f05583f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env luajit

local path = os.getenv("PATH_INFO")
local method = os.getenv("REQUEST_METHOD")

local function escape(s)
    return s:gsub("<", "&lt;"):gsub("<", "&lt;")
end

local function respond(status, title, body)
    print(string.format("Status: %d", status))
    print("Content-Type: text/html")
    print("")
    print(string.format([[
        <html><head>
            <title>%s</title>
            <meta charset="utf-8" />
        </head><body>
    ]], escape(title)))
    body()
    print("</body></html>")
end

local function respond_error(message)
    respond(400, "Error", function()
        print(string.format("<p>Error: %s</p>", escape(message)))
    end)
end

local function form_data()
    local data = {}
    for pair in string.gmatch(io.read(), "([^&]+)") do
        local key, value = string.match(pair, "([^=]+)=([^=]+)")
        if key == nil or value == nil then
            goto continue
        end
        data[key] = value
        ::continue::
    end
    return data
end

local function read_log()
    local log = io.open("log", "r")
    if log == nil then
        return function() return nil end
    end
    local lines = log:lines("l")
    return function()
        local l = lines()
        local time, username, amount, comment = string.match(l, "(%d+),([%w_-]+),(-?%d+),([%w_-]*)")
        return tonumber(time), username, tonumber(amount), comment
    end
end

if path == "/" then
    print("Status: 200 OK")
    print("Content-Type: text/plain")
    print("")
elseif path ~= nil then
    local username = path:sub(2)
    if username:match("^[%w_-]+$") == nil then
        return respond_error("username invalid")
    end

    if method == "POST" then
        local data = form_data()
        local amount = tonumber(data.amount)
        if amount == nil then
            return respond_error("amount invalid")
        end
        local comment = data.comment or ""
        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,%s,%s\n", time, username, amount, comment))
        log:flush()
        log:close()
    end

    respond(200, username, function()
        print(string.format("<h1>%s</h1>", username))
        print([[
            <form action="" method="POST">
                <label for="amount">Amount: </label>
                <input type="number" name="amount" id="amount" /><br/>
                <label for="comment">Comment: </label>
                <input type="text" name="comment" id="comment" /><br/>
                <input type="submit" value="Update" />
            </form>
        ]])
        for _, type in ipairs({ 1, -1 }) do
            for _, amount in ipairs({ 50, 100, 150, 200, 500, 1000 }) do
                print(string.format([[
                    <form action="" method="POST">
                        <input type="number" name="amount" id="amount" value="%d" hidden />
                        <input type="text" name="comment" id="comment" value="" hidden />
                        <input type="submit" value="%s%.02f€" />
                    </form>
                ]], amount * type, ({ [-1] = "-", [1] = "+" })[type], amount / 100))
            end
        end
    end)
end