Module:ElectionStats
Documentation for this module may be created at Module:ElectionStats/doc
local json = mw.text.jsonDecode
local p = {}
function p.generateCards(frame)
local dataPage = 'Data:Election Data.json'
local success, data = p.loadJson(dataPage)
if not success then
return "could not load JSON data from " .. dataPage .. "!"
end
local currentTime = os.time()
local counts = { Local = 0, General = 0, Statewide = 0, Referendum = 0 }
local total = 0
for _, elections in pairs(data) do
for _, election in ipairs(elections) do
local electionType = election.election_type
local electionDate = p.parseDate(election.date)
if electionDate and electionDate <= currentTime then
if counts[electionType] then
counts[electionType] = counts[electionType] + 1
total = total + 1
end
end
end
end
local result = {}
for electionType, count in pairs(counts) do
if count > 0 then
table.insert(result, p.generateCard(electionType, count))
end
end
table.insert(result, p.generateCard("Total", total))
return table.concat(result, "\n")
end
function p.loadJson(page)
local title = mw.title.new(page)
if not title or not title.exists then
return false, nil
end
local content = title:getContent()
return true, json(content)
end
function p.parseDate(dateString)
local pattern = "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)"
local year, month, day, hour, min, sec = dateString:match(pattern)
if year and month and day and hour and min and sec then
return os.time({
year = tonumber(year),
month = tonumber(month),
day = tonumber(day),
hour = tonumber(hour),
min = tonumber(min),
sec = tonumber(sec)
})
else
return nil
end
end
function p.generateCard(electionType, count)
return string.format(
[[
<div style="width: 200px; height: 250px; background-color: #1C408C; color: white; text-align: center; border: 1px solid #1C408C; padding: 10px; font-family: Arial, sans-serif; display: flex; flex-direction: column; justify-content: center; align-items: center;">
<div style="font-size: 2em; font-weight: bold; line-height: 1.5;">%d</div>
<div style="border-top: 2px solid white; width: 80%%; margin: 10px 0;"></div>
<div style="font-size: 1em; text-transform: uppercase; line-height: 1.5;">%s Elections</div>
</div>
]],
count,
electionType
)
end
return p