Last active
January 16, 2023 08:19
-
-
Save Castux/57330993c00b009b9184042eb0d66f94 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function parse_changes(meta_dir) | |
local find_cmd = string.format([[cat `find %s \( -name '*.changes' ! -name '_*' \)`]], meta_dir) | |
local months = {} | |
for line in io.popen(find_cmd):lines() do | |
local ts, kind = line:match "^(%d+)\t%S+\t(%w+)" | |
if line:match "Page moved" then | |
kind = "M" | |
elseif kind == "e" or kind == "R" then | |
kind = "E" | |
end | |
local t = os.date("*t", ts) | |
local key = string.format("%d-%02d", t.year, t.month) | |
if not months[key] then | |
months[key] = {} | |
end | |
if not months[key][kind] then | |
months[key][kind] = 0 | |
end | |
months[key][kind] = months[key][kind] + 1 | |
end | |
local flat = {} | |
for month, data in pairs(months) do | |
data.month = month | |
table.insert(flat, data) | |
end | |
table.sort(flat, function(a,b) return a.month < b.month end) | |
return flat | |
end | |
local kinds = { | |
C = "Pages created", | |
D = "Pages deleted", | |
M = "Pages moved", | |
E = "Page edits" | |
} | |
local kinds_short = {"C", "E", "M", "D"} | |
local function format_table(months) | |
local lines = {} | |
-- Headers | |
local header_line = "^ Month ^ " | |
for _,v in ipairs(kinds_short) do | |
header_line = header_line .. kinds[v] .. " ^ " | |
end | |
table.insert(lines, header_line) | |
-- Data | |
for _,data in ipairs(months) do | |
local line = "| " .. data.month .. " | " | |
for _,k in ipairs(kinds_short) do | |
line = line .. (data[k] or 0) .. " | " | |
end | |
table.insert(lines, line) | |
end | |
return table.concat(lines, "\n") | |
end | |
local function format_graph(months) | |
local json = require "json" | |
local labels = {} | |
local datasets = {} | |
for i,k in ipairs(kinds_short) do | |
datasets[i] = { | |
label = kinds[k], | |
data = {} | |
} | |
end | |
for _,month in ipairs(months) do | |
table.insert(labels, month.month) | |
for i,k in ipairs(kinds_short) do | |
table.insert(datasets[i].data, month[k] or 0) | |
end | |
end | |
local chart = { | |
type = "bar", | |
data = { | |
labels = labels, | |
datasets = datasets | |
}, | |
options = { | |
scales = { | |
y = { | |
beginAtZero = true, | |
stacked = true | |
}, | |
x = { | |
stacked = true | |
} | |
} | |
} | |
} | |
return json.encode(chart) | |
end | |
local template = [[ | |
====== Wiki contributions statistics ====== | |
<html> | |
<div> | |
<canvas id="myChart"></canvas> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
<script> | |
const ctx = document.getElementById('myChart'); | |
new Chart(ctx, %s); | |
</script> | |
</html> | |
%s | |
]] | |
local function write_page(meta_dir, out_path) | |
local data = parse_changes(meta_dir) | |
local table = format_table(data) | |
local chart = format_graph(data) | |
local f = io.open(out_path, "w") | |
f:write(string.format(template, chart, table)) | |
f:close() | |
end | |
local function main() | |
if #arg ~= 2 then | |
error "Usage: lua make_stats.lua <meta_dir> <out_path>" | |
end | |
local meta_dir = arg[1] | |
local out_path = arg[2] | |
print("Meta dir:", meta_dir) | |
print("Out path:", out_path) | |
write_page(meta_dir, out_path) | |
end | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment