Module:Project statistics
Module documentation
[create]
local p = {}
local dataByWiki = require("Module:Project portal/wikis")
local contentLang = mw.getContentLanguage()
local datePattern = "Last update: ... (%d%d ... %d%d%d%d)"
-- Returns a title object for the page that contains statistics about the given
-- project.
function p.statsTitleForProject(project)
if project == "wikipedia" then
return mw.title.new("List of Wikipedias/Table", 0)
end
return mw.title.new(project .. "/Table", 0)
end
function p.getStatistics(project)
project = project or "wikipedia"
local statsTable = mw.ext.data.get("Wikipedia statistics/data.tab")
-- Metadata
local timestamp = mw.ustring.match(statsTable.description, datePattern)
local date = mw.text.split(contentLang:formatDate("Y-m-d", timestamp), "-")
local wikis = {}
local totals = {}
for i, row in ipairs(statsTable.data) do
local wiki = mw.ustring.match(row[1], "(.+)%." .. project)
if wiki ~= nil then
local stats = {
wiki = wiki,
articles = row[4],
pages = row[7],
edits = row[5],
admins = row[3],
users = row[8],
activeUsers = row[2],
files = row[6],
}
local data = dataByWiki[wiki] and dataByWiki[wiki][project]
if data and data.closed then
stats.closed = true
end
-- [[Wikipedia article depth]]
stats.depth = stats.edits / stats.pages * ((stats.pages - stats.articles) / stats.articles) ^ 2
if wiki == "total" or wiki == "totalactive" or wiki == "totalclosed" then
totals[wiki] = stats
else
wikis[wiki] = stats
end
end
end
-- Sometimes the statistics pages don’t get updated right after a wiki is
-- created. The workaround is to temporarily set [project].numArticles in
-- /wikis to the number of articles.
for wiki, data in pairs(dataByWiki) do
local data = dataByWiki[wiki] and dataByWiki[wiki][project]
if not wikis[wiki] and data and not data.closed then
wikis[wiki] = {
manual = true,
wiki = wiki,
articles = data.numArticles,
pages = data.numPages,
edits = data.numEdits,
admins = data.numAdmins,
users = data.numUsers,
activeUsers = data.numActiveUsers,
files = data.numFiles,
}
end
end
return {
project = project,
source = title,
date = date,
wikis = wikis,
totals = totals,
}
end
function round(x)
if x > 0 then
return math.floor(x + 0.5)
else
return math.ceil(x - 0.5)
end
end
function p.wikitable(frame)
local language = mw.getLanguage(frame.args.language or "en")
local project = frame.args.project
local stats = p.getStatistics(project)
local lines = {}
local headerCells = {
frame.args.rank or "№",
frame.args.linguonym or "Language",
frame.args.autonym or "Language (local)",
frame.args.articles or "Articles",
frame.args.code or "Wiki",
frame.args.pages or "All pages",
frame.args.edits or "Edits",
frame.args.admins or "Admins",
frame.args.users or "Users",
frame.args.activeUsers or "Active users",
frame.args.files or "Files",
}
if project == "wikipedia" then
table.insert(headerCells, mw.ustring.format("[[Wikipedia article depth|%s]]", frame.args.depth or "Depth"))
end
local header = "|-\n! " .. table.concat(headerCells, " !! ")
table.insert(lines, header)
local sortedStats = {}
for wiki, row in pairs(stats.wikis) do
table.insert(sortedStats, row)
end
table.sort(sortedStats, function(a, b)
return a.articles > b.articles
end)
-- Repeat the rank in case of a tie.
for i, row in ipairs(sortedStats) do
row.rank = i
if i > 1 and row.articles == sortedStats[i - 1].articles then
row.rank = sortedStats[i - 1].rank
end
end
local languageNames = mw.language.fetchLanguageNames(frame.args.language)
local autonyms = mw.language.fetchLanguageNames()
local articleFormat = frame.args.articleFormat or "%s language"
for rank, row in ipairs(sortedStats) do
local wiki = row.wiki
if not row.closed then
local languageName
if languageNames[wiki] then
languageName = mw.ustring.format("[[w:%s:%s|%s]]",
frame.args.language or "en",
mw.ustring.format(articleFormat, languageNames[wiki]),
languageNames[wiki])
else
-- Akan is not a language and thus has no language name anymore,
-- but ak.wikipedia.org still exists (same for the autonym);
-- cf. [[Proposals for closing projects/Closure of Akan Wikipedia 2]]
languageName = '?'
end
local cells = {
"align='right' | " .. language:formatNum(rank),
languageName,
autonyms[wiki] or '?',
mw.ustring.format("[[%s:%s:|%s]]", project, wiki, wiki),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:Statistics|%s]]", project, wiki, language:formatNum(row.articles)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:AllPages|%s]]", project, wiki, language:formatNum(row.pages)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:RecentChanges|%s]]", project, wiki, language:formatNum(row.edits)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:ListUsers/sysop|%s]]", project, wiki, language:formatNum(row.admins)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:ListUsers|%s]]", project, wiki, language:formatNum(row.users)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:ActiveUsers|%s]]", project, wiki, language:formatNum(row.activeUsers)),
"align='right' | " .. mw.ustring.format("[[%s:%s:Special:NewFiles|%s]]", project, wiki, language:formatNum(row.files)),
}
if project == "wikipedia" then
-- row.depth will be the positive infinity if there are no articles (division by zero)
table.insert(cells, "align='right' | " .. (row.depth == math.huge and '–' or language:formatNum(round(row.depth))))
end
local line = "|-\n| " .. table.concat(cells, " || ")
table.insert(lines, line)
end
end
return "{| class='wikitable sortable'\n" .. table.concat(lines, "\n") .. "\n|}"
end
return p