Documentation for this module may be created at Module:UserPredictionsLeaderboard/doc
local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require('Module:EsportsUtil')
local util_html = require('Module:HtmlUtil')
local util_math = require('Module:MathUtil')
local util_map = require('Module:MapUtil')
local util_predictions = require('Module:PredictionsUtil')
local util_sort = require('Module:SortUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_title = require('Module:TitleUtil')
local util_vars = require('Module:VarsUtil')
local m_team = require('Module:Team')
local i18n = require('Module:i18nUtil')
local ML = require('Module:MatchListAbstract'):extends()
local ColumnShowHide = require('Module:ColumnShowHide')
local OVERVIEW_PAGE
local MAX_MEMBERS_PER_GROUP = 15
local h = {}
local p = {}
function p.main(frame)
local args = util_args.merge()
i18n.init('MatchList', 'UserPredictions', 'UserPredictionsLeaderboard')
OVERVIEW_PAGE = util_predictions.getOverviewPage(args.page, args.type)
local predictionData = h.getPredictionData(args)
local resultData = ML:getAndRunMatchQuery(OVERVIEW_PAGE, args)
h.addOutcomesToPredictions(predictionData, resultData)
h.sortUsersByRank(predictionData)
h.storeGroupMetadataCargo(args)
return h.makeOutput(predictionData, resultData, args), util_predictions.displayTitle(OVERVIEW_PAGE)
end
function ML:processMatchRow(row, i, j, args, tab)
self:processFF(row)
end
function h.getPredictionData(args)
local query = h.getQuery(args)
local result = util_cargo.queryAndCast(query)
util_map.rowsInPlace(result, h.userPredictionListToTable)
util_sort.tablesByKeys(result, 'NumberCorrect')
return result
end
function h.getQuery(args)
local ret = {
tables = 'UserPredictions',
where = h.getPredictionWhere(args),
limit = h.getPredictionLimit(args),
orderBy = 'NumberCorrect DESC, NumberOfPredictions DESC, User ASC',
fields = {
'User',
'NumberOfPredictions [number]',
'NumberCorrect [number]',
'NumberOver [number]',
'PredictionList',
'_pageName',
},
groupBy = '_pageName',
}
return ret
end
function h.getPredictionWhere(args)
local tbl = {
('OverviewPage="%s"'):format(OVERVIEW_PAGE),
h.getListOfUsersWhereCondition(args.members)
}
return util_cargo.concatWhere(tbl)
end
function h.getListOfUsersWhereCondition(members)
if not members then return end
return util_cargo.concatWhereOr(util_map.split(members, nil, h.memberToWhereCondition))
end
function h.memberToWhereCondition(str)
return ('User="%s"'):format(str)
end
function h.getPredictionLimit(args)
if args.type == 'Leaderboard' then
return 100
else
return 20
end
end
function h.userPredictionListToTable(row)
row.PredictionList = util_map.split(row.PredictionList, ';', util_map.split, nil, tonumber)
end
function h.addOutcomesToPredictions(predictionData, resultData)
for _, userRow in ipairs(predictionData) do
userRow.PredictionList = h.getOneUserOutcomes(userRow.PredictionList, resultData)
util_predictions.addPredictionTotalsToData(userRow.PredictionList)
end
end
function h.getOneUserOutcomes(predictionList, resultData)
local ret = {}
for i, tab in ipairs(resultData) do
ret[i] = {}
for j, row in ipairs(tab) do
local index = tonumber(row.InitialN_MatchInTab or j)
local tbl = mw.clone(row)
if predictionList[i] then
tbl.Prediction = predictionList[i][index]
end
ret[i][j] = tbl
end
end
return ret
end
function h.sortUsersByRank(predictionData)
for _, user in ipairs(predictionData) do
user.right = user.PredictionList.predictionTotals.right
end
util_sort.tablesByKeys(predictionData, 'right')
end
-- store cargo if group
function h.storeGroupMetadataCargo(args)
if args.type ~= 'Group' then return end
local tbl = {
_table = 'UserPredictionGroups',
Members = args.members,
GroupName = h.getGroupFromTitle(),
NumberOfMembers = h.getNumberOfMembers(args),
OverviewPage = OVERVIEW_PAGE
}
util_cargo.store(tbl)
end
function h.getGroupFromTitle()
return util_title.titleparts(nil, 1, -1)
end
function h.getNumberOfMembers(args)
return #util_text.split(args.members)
end
-- output
function h.makeOutput(predictionData, resultData, args)
local output = mw.html.create('div')
:addClass('wide-content-scroll')
if args.type == 'Group' then
h.printGroupIntro(args, output)
h.printLeaderboard(output, predictionData, resultData, args)
h.printIndividualGamesTable(output, predictionData, resultData)
else
h.printLeaderboardIntro(output)
h.printLeaderboard(output, predictionData, resultData, args)
end
return output
end
function h.printGroupIntro(args, output)
local ul = output:tag('ul')
util_predictions.printRefreshThisPageButton(ul:tag('li'))
h.printUserRefreshButton(ul)
h.printOverviewPageLink(ul)
h.printLinkToLeaderboard(ul)
if h.getNumberOfMembers(args) == MAX_MEMBERS_PER_GROUP then
h.printGroupFull(ul)
else
h.printGroupJoin(args,ul)
end
output:tag('hr')
end
function h.printUserRefreshButton(ul)
ul:tag('li'):tag('div')
:attr('id', 'predictions-reload-user-data-from-leaderboard')
:addClass('user-predictions-action-link')
:wikitext(i18n.print('userPageDataRefresh'))
end
function h.printOverviewPageLink(ul)
ul:tag('li')
:wikitext(util_text.intLink(OVERVIEW_PAGE, i18n.print('eventOverview')))
end
function h.printLinkToLeaderboard(ul)
util_predictions.linkToGeneratedPage(ul:tag('li'), 'Leaderboard', OVERVIEW_PAGE)
end
function h.printGroupFull(ul)
ul:tag('li'):wikitext((i18n.print('fullGroup', MAX_MEMBERS_PER_GROUP)))
end
function h.printGroupJoin(args,ul)
ul:tag('li'):tag('div')
:attr('id', 'predictions-join-group')
:attr('data-current-member-list', args.members)
:addClass('user-predictions-action-link')
:wikitext(i18n.print('joinCommand'))
end
function h.printLeaderboardIntro(output)
local ul = output:tag('ul')
util_predictions.printRefreshThisPageButton(ul:tag('li'))
h.printUserRefreshButton(ul)
h.printOverviewPageLink(ul)
end
function h.printLeaderboard(output, predictionData, resultData, args)
local tbl = h.initTable(output)
h.printColumnHeaders(tbl, resultData)
h.printRows(tbl, predictionData)
end
function h.initTable(output)
local tbl = output:tag('table')
:addClass('wikitable')
:addClass('sortable')
:addClass('prediction-leaderboard')
return tbl
end
function h.printColumnHeaders(tbl, resultData)
local tr = tbl:tag('tr')
tr:tag('th'):wikitext(i18n.print('user'))
for _, tab in ipairs(resultData) do
tr:tag('th')
:wikitext(tab.name)
:attr('data-sort-type', 'number')
end
tr:tag('th')
:wikitext(i18n.print('total'))
:attr('data-sort-type', 'number')
end
function h.printRows(tbl, predictionData)
for _, userRow in ipairs(predictionData) do
h.printOneRow(tbl, userRow)
end
end
function h.printOneRow(tbl, userRow)
local tr = tbl:tag('tr')
h.printUserCell(tr, userRow)
for _, tab in ipairs(userRow.PredictionList) do
h.printTabCell(tr, tab.predictionTotals)
end
h.printTabCell(tr, userRow.PredictionList.predictionTotals)
end
function h.printUserCell(tr, userRow)
if not userRow.User then
error(i18n.print('error_missingUser', userRow._pageName))
end
local td = tr:tag('td'):wikitext(h.linkToUserPredictions(userRow.User))
util_predictions.printRefreshTargetButton(td, 'Predictions:' .. OVERVIEW_PAGE .. '/User/' .. userRow.User)
end
function h.linkToUserPredictions(user)
return util_text.intLink('Predictions:' .. OVERVIEW_PAGE .. '/User/' .. user, user)
end
function h.printTabCell(tr, list)
tr:tag('td')
:wikitext(('%s/%s'):format(list.right, list.over))
end
function h.printIndividualGamesTable(output, predictionData, resultData)
local numberOfColumns = h.getMaxGamesInATab(resultData)
local allHeadings = h.getAllHeadings(numberOfColumns)
ColumnShowHide.printToggles(output, allHeadings)
local tbl = output:tag('table')
:addClass('wikitable')
:addClass('prediction-results-table')
ColumnShowHide.printTableClass(tbl)
for i, tab in ipairs(resultData) do
util_html.printColspanHeader(tbl, tab.name, numberOfColumns + 2)
h.printHeaders(tbl, tab, numberOfColumns)
h.printTabOfTable(tbl, predictionData, i, numberOfColumns)
end
end
function h.getMaxGamesInATab(resultData)
local max = 0
for _, tab in ipairs(resultData) do
if #tab > max then max = #tab end
end
return max
end
function h.getAllHeadings(numberOfColumns)
local ret = { i18n.print('user') }
for i = 1, numberOfColumns do
ret[#ret+1] = i
end
ret[#ret+1] = i18n.print('total')
return ret
end
function h.printHeaders(tbl, tab, numberOfColumns)
local tr = tbl:tag('tr')
--:wikitext
tr:tag('th'):wikitext(i18n.print('user'))
for i = 1, numberOfColumns do
tr:tag('th'):wikitext(tab[i] and i or '')
end
tr:tag('th'):wikitext(i18n.print('total'))
end
function h.printTabOfTable(tbl, predictionData, i, numberOfColumns)
for _, user in ipairs(predictionData) do
h.printUserOfTab(tbl, user, i, numberOfColumns)
end
end
function h.printUserOfTab(tbl, user, i, numberOfColumns)
local tr = tbl:tag('tr')
tr:tag('td')
:wikitext(h.linkToUserPredictions(user.User))
:addClass('prediction-results-table-user')
for j = 1, numberOfColumns do
h.printUserTabCell(tr, user.PredictionList[i][j])
end
h.printTabCell(tr, user.PredictionList[i].predictionTotals)
end
function h.printUserTabCell(tr, row)
local td = tr:tag('td')
if not row then return end
td:wikitext(h.printPredictedWinner(row))
:addClass(h.getPredictionClass(row))
end
function h.printPredictedWinner(row)
if row.Prediction == 0 then
return 'TIE'
elseif not row.Prediction then
return ''
else
return m_team.onlyimage(row['Team' .. row.Prediction])
end
end
function h.getPredictionClass(row)
if not (row.Prediction and row.Winner) then return end
if row.Prediction == row.Winner then
return 'standings-up'
else
return 'standings-down'
end
end
return p