Module:Daily proofreading stats table
Appearance
Logic for {{Daily proofreading stats table}}
--[=[
Module description
]=]
require('strict')
local p = {} --p stands for package
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local lowerLimit = 100
local upperLimit = 200
local function get_days_in_month(month, year)
local days_in_month = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local d = days_in_month[month]
-- check for leap year
if (month == 2) then
if (math.mod(year,4) == 0) then
if (math.mod(year,100) == 0) then
if (math.mod(year,400) == 0) then
d = 29
end
else
d = 29
end
end
end
return d
end
-- calculate "processed" pages for a given stats dump
-- validated is double because it includes a prior proofread step
local function get_processed(t)
return t.q0 + t.q3 + (t.q4 * 2)
end
local function add_note_row(tab, colspan, content, classes)
local row = tab:tag('tr')
row:tag('td')
:attr('colspan', colspan)
:wikitext(content)
if classes then
row:addClass(classes)
end
row:addClass('wst-daily-stats-note-row')
end
local function add_col_header(tr, content, title)
local th = tr:tag('th')
:wikitext(content)
:attr('scope', 'col')
if title then
th:attr('title', title)
end
end
--[=[
Function docs
]=]
function p.table(frame)
local args = getArgs(frame)
local t = mw.html.create('table')
:addClass('wst-daily-stats')
local ok, data = pcall(mw.loadData, args.source)
local year = tonumber(args.year)
local month = tonumber(args.month)
local num_cols = 5
t:tag('caption')
:wikitext("Daily statistics")
add_note_row(t, num_cols,
"Day under " .. lowerLimit,
'wst-daily-stats-under-target')
add_note_row(t, num_cols,
"Day over " .. upperLimit,
'wst-daily-stats-over-target')
local tr = t:tag('tr')
add_col_header(t, 'Day')
add_col_header(t, 'P', 'Pages proofread on this day')
add_col_header(t, 'V', 'Pages validated on this day')
add_col_header(t, 'Pages', 'Pages proofread, validated or marked without text on this day')
add_col_header(t, 'Total', 'Pages proofread, validated or marked without text since the start of the month')
local now = os.date("!*t")
local max_day = now.day;
if yesno(args.include_today) then
max_day = max_day + 1
end
local totals = {
proofread = 0,
validated = 0,
processed = 0,
}
local avg_totals = {
proofread = 0,
validated = 0,
processed = 0,
num_days = 0,
}
if (now.year > year) or (now.year == year and now.month > month) then
-- the data is in the past, show all days
max_day = 100
elseif (now.year < year) or (now.month < month) then
-- in the future
max_day = 0;
end
local last;
if data and data.days then
-- data is present
last = data.days[0];
else
-- data is missing
max_day = 0
end
local day_data
for day = 1, get_days_in_month(month, year) do
if data.days then
day_data = data.days[day]
end
local processed = 0
local diff = 0
local proofread = 0
local validated = 0
local last_proc = 0
if last then
last_proc = get_processed(last)
end
if day_data then
processed = get_processed(day_data)
diff = processed - last_proc
validated = day_data.q4 - (last.q4 or 0)
-- every validated page also "steals" a proofread page
proofread = day_data.q3 - (last.q3 or 0) + validated
totals.proofread = totals.proofread + proofread
totals.validated = totals.validated + validated
end
totals.processed = totals.processed + diff
tr = t:tag('tr')
:addClass('wst-daily-stats-daydata')
tr:tag('td')
:wikitext(day)
:attr('data-day', day)
if day < max_day then
if args.include_today and day == max_day - 1 then
tr:addClass('wst-daily-stats-in-progress')
:attr('title', 'This day is not yet complete, these are the most recent statistics.')
else
-- include the day in the averages
avg_totals.processed = totals.processed
avg_totals.proofread = totals.proofread
avg_totals.validated = totals.validated
avg_totals.num_days = avg_totals.num_days + 1
end
tr:tag('td')
:wikitext(proofread)
tr:tag('td')
:wikitext(validated)
tr:tag('td')
:wikitext(diff)
-- month-to-date total
tr:tag('td')
:wikitext(totals.processed)
if day_data and diff < lowerLimit then
tr:addClass('wst-daily-stats-under-target')
elseif diff > upperLimit then
tr:addClass('wst-daily-stats-over-target')
end
if day_data == nil then
tr:addClass('wst-daily-stats-missing-data')
end
else
-- add dummy table cells
tr:tag('td')
tr:tag('td')
tr:addClass('wst-daily-stats-empty')
end
last = day_data
end
if avg_totals.num_days > 0 then
-- add the averages
tr = t:tag('tr')
:addClass('wst-daily-stats-average')
tr:tag( 'td' )
:wikitext( 'Avg.' )
:attr( 'title', 'The average page counts for whole days completed this month' )
tr:tag( 'td' )
:wikitext(string.format( '%d', ( avg_totals.proofread / avg_totals.num_days ) + 0.5 ) )
tr:tag( 'td' )
:wikitext(string.format( '%d', ( avg_totals.validated / avg_totals.num_days ) + 0.5 ) )
tr:tag( 'td' )
tr:tag( 'td' )
:wikitext(string.format( '%d', ( avg_totals.processed / avg_totals.num_days ) + 0.5 ) )
-- add the totals
tr = t:tag('tr')
:addClass( 'wst-daily-stats-total' )
tr:tag('td')
:wikitext('Total')
:attr( 'title', 'The total pages completed in each category this month' )
tr:tag('td')
:wikitext(totals.proofread)
tr:tag('td')
:wikitext(totals.validated)
tr:tag('td')
tr:tag('td')
:wikitext(totals.processed)
end
return t
end
return p