Documentation for this module may be created at Module:TournamentResults/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_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_toggle = require('Module:ToggleUtil')
local util_vars = require('Module:VarsUtil')
local i18n = require('Module:i18nUtil')
local m_currency = require('Module:Currency')
local m_team = require('Module:Team')
local ROWSPANS = {
place = true,
prize_display = true,
usd = true,
eur = true,
prizepct = true,
qual = true,
points = true
}
local CLASSES = {
place = 'tournament-results-place',
team = 'tournament-results-team',
player = 'tournament-results-player',
prize_display = 'tournament-results-prize',
}
local CURRENCY_ORDER = { 'USD', 'Euros' }
local LINE_ARG_ORDER = { 'place', 'forcenewplace', 'sameplaces', 'date', 'prize', 'otherprize', 'prizepct', 'prizeunit', 'points', 'qual', 'quallink', 'qual2', 'qual2link', 'team', 'nocargo', 'date', 'rosterpage', 'groupstage', 'group', 'lastresult', 'lastopponent', 'lastopponentlink', 'lastopponentteam', 'lastoutcome', 'lastresultpoints', 'player', 'playerlink', 'hide', 'qualified' }
local TOGGLES = {
class = 'TRL_toggle%s',
}
local PRIZE_TOGGLE_DATA = {
order = {},
sep = ' • ',
section = 'prizepool-togglers-currency',
all = 'prizepool-currency-all',
hiddenclass = 'prizepool-currency-hidden',
}
local HAS_TOGGLES = false
local h = {}
local p = {}
function p.main(frame)
i18n.initGlobalFromFile('TournamentResults')
local args = util_args.merge(true)
local processedArgs = h.getProcessedArgs(args)
h.initCurrencyToggle(processedArgs)
local cols = h.getCols(args, processedArgs)
local linesData = h.getLinesData(args, processedArgs)
h.storeCargo(linesData)
return h.makeOutput(args, processedArgs, cols, linesData)
end
function h.getProcessedArgs(args)
h.checkConversions({ args.usdrate, args.eurorate })
local processedArgs = {
prizeunit = args.prizeunit or 'USD',
totalprize = util_math.formatNumber(args.totalprize),
totalprizenum = args.totalprize and util_math.tonumber(args.totalprize),
usdrate = tonumber(args.usdrate),
eurorate = tonumber(args.eurorate),
phase = args.phase,
nocargo = util_args.castAsBool(args.nocargo),
preload = args.preload or 'Team',
showprize = util_args.castAsBool(args.prize),
showusd = util_args.castAsBool(args.usdrate),
showeuro = util_args.castAsBool(args.eurorate),
showpoints = util_args.castAsBool(args.points),
showqual = util_args.castAsBool(args.qual),
showteam = util_args.castAsBool(args.showteam),
showplayer = util_args.castAsBool(args.showplayer),
combinequal = util_args.castAsBool(args.combinequal),
}
processedArgs.hasconversion = processedArgs.usdrate or processedArgs.eurorate
return processedArgs
end
function h.checkConversions(tbl)
for _, v in ipairs(tbl) do
if v and not tonumber(v) then
error(i18n.print('invalid_currency', i18n.print('conversion_rate')))
end
end
end
function h.initCurrencyToggle(processedArgs)
local rates = {
USD = processedArgs.usdrate,
Euros = processedArgs.eurorate,
}
for _, v in ipairs(CURRENCY_ORDER) do
if rates[v] then
PRIZE_TOGGLE_DATA.order[#PRIZE_TOGGLE_DATA.order+1] = v
end
end
if next(PRIZE_TOGGLE_DATA.order) then
table.insert(PRIZE_TOGGLE_DATA.order, 1, 'prize')
HAS_TOGGLES = true
end
util_toggle.oflInit(PRIZE_TOGGLE_DATA)
end
function h.getCols(args, processedArgs)
local cols = {
'place',
processedArgs.showprize and 'prize_display',
h.pctCol(args),
processedArgs.showpoints and 'points',
processedArgs.showqual and 'qual',
(processedArgs.showteam or processedArgs.preload == 'Team') and 'team',
(processedArgs.showplayer or processedArgs.preload == 'Player') and 'player',
}
util_table.removeFalseEntries(cols)
local names = h.getNames(args)
cols.displays = {}
for i, v in ipairs(cols) do
cols.displays[i] = names[v] or i18n.print('col_' .. v)
end
return cols
end
function h.pctCol(args)
if util_args.castAsBool(args.prize) and not util_args.castAsBool(args.nomoney) then
return 'prizepct'
else
return false
end
end
function h.getNames(args)
return {
points = args.pointstitle,
team = args.teamtitle
}
end
function h.getLinesData(args, processedArgs)
local rowData = {}
for i, v in ipairs(args) do
rowData[i] = h.processArgRow(v, processedArgs)
end
h.determineRowspans(rowData)
return rowData
end
function h.processArgRow(str, processedArgs)
local lineArgs = util_args.splitArgs(str, LINE_ARG_ORDER)
local lineDisplay = h.makeDisplayLineFromArgs(lineArgs, processedArgs)
lineDisplay.cargo = h.argsToCargoLine(lineArgs, processedArgs, lineDisplay)
return lineDisplay
end
function h.makeDisplayLineFromArgs(lineArgs, processedArgs)
local lineDisplay = {
place = lineArgs.place and util_esports.placementIcon(lineArgs.place),
placeraw = lineArgs.place,
team = m_team.rightmediumlinked(lineArgs.team),
player = h.getPlayerDisplay(lineArgs, processedArgs),
points = lineArgs.points,
qual = h.getQual(lineArgs),
forcenewplace = util_args.castAsBool(lineArgs.forcenewplace),
hide = util_args.castAsBool(lineArgs.hide),
}
local prizes = h.getPrizeDisplay(lineArgs, processedArgs)
prizes.prize_display = prizes.prize_toggle or prizes.prize
util_table.merge(lineDisplay, prizes)
if processedArgs.combinequal then
lineDisplay.points = lineDisplay.points or lineDisplay.qual or ''
end
return lineDisplay
end
function h.getPlayerDisplay(lineArgs, processedArgs)
local output = {
lineArgs.team and m_team.onlyimagelinkedshort(lineArgs.team),
util_text.intLink(lineArgs.playerlink, lineArgs.player)
}
util_table.removeFalseEntries(output, 2)
return util_table.concat(output, ' ')
end
function h.getQual(lineArgs)
local quals = util_args.numberedArgsToTable(lineArgs, 'qual') or {}
lineArgs.qual1link = lineArgs.quallink
for i, qual in ipairs(quals) do
local link = lineArgs['qual' .. i .. 'link']
quals[i] = util_text.intLink(link, qual)
end
return util_table.concat(quals,'<br>')
end
function h.getPrizeDisplay(lineArgs, processedArgs)
if not (lineArgs.prize or lineArgs.prizepct) then
return { prize = lineArgs.otherprize }
end
local prizeNum = h.getPrizeNum(lineArgs, processedArgs)
if not prizeNum then
return { prize = lineArgs.otherprize, prizepct = lineArgs.prizepct .. '%' }
end
local prizes = {
prize = h.getPrize(prizeNum, lineArgs, processedArgs),
usd_number = h.getPrizeConverted(prizeNum, processedArgs.prizeunit, processedArgs.usdrate, 'USD'),
eur_number = h.getPrizeConverted(prizeNum, processedArgs.prizeunit, processedArgs.eurorate, 'Euro'),
prizepct = h.getPrizePct(prizeNum, lineArgs, processedArgs),
}
prizes.USD = m_currency.short(prizes.usd_number, 'usd')
prizes.Euros = m_currency.short(prizes.eur_number, 'euro')
prizes.prize_toggle = h.getPrizeToggle(prizes, processedArgs.prizeunit)
return prizes
end
function h.getPrizeNum(lineArgs, processedArgs)
local prize = lineArgs.prize
if prize then
if not util_math.tonumber(prize) then
error(i18n.print('invalid_currency',i18n.print('prize')))
end
return util_math.tonumber(prize)
end
local prizepct = lineArgs.prizepct
local totalprize = processedArgs.totalprizenum
if totalprize then
return util_math.roundnum(prizepct / 100 * totalprize, .01)
end
return nil
end
function h.getPrize(prizeNum, lineArgs, processedArgs)
local fullPrize = {
m_currency.short(prizeNum, processedArgs.prizeunit),
lineArgs.otherprize
}
return util_table.concat(fullPrize, ' + ',nil,2)
end
function h.getPrizeConverted(prize, prizeunit, rate, unitToGet)
if prizeunit == unitToGet then
return prize
elseif prize and rate then
return util_math.roundnum(prize * tonumber(rate), .01)
else
return nil
end
end
function h.getPrizePct(prizeNum, lineArgs, processedArgs)
if lineArgs.prizepct then
return lineArgs.prizepct .. '%'
elseif processedArgs.totalprizenum then
return util_math.roundnum(prizeNum / processedArgs.totalprizenum * 100, .01) .. '%'
else
return nil
end
end
function h.getPrizeToggle(prizes, prizeunit)
if not HAS_TOGGLES then return nil end
local tbl = mw.html.create()
for _, v in ipairs(PRIZE_TOGGLE_DATA.order) do
util_toggle.oflCellClasses(tbl:tag('span'):wikitext(prizes[v]), PRIZE_TOGGLE_DATA, v)
end
return tostring(tbl)
end
function h.argsToCargoLine(lineArgs, processedArgs, lineDisplay)
if processedArgs.nocargo or lineArgs.nocargo then return end
local cargoData = {
Event = util_vars.getVar('Event Name'),
Tier = util_vars.getVar('Event Tier'),
Date = lineArgs.date or util_vars.getVar('Event Date'),
Place = util_math.deserialize(lineArgs.place) or lineArgs.place,
Prize = lineArgs.prize,
PrizeUnit = processedArgs.prizeunit,
Prize_Markup = lineArgs.prize and m_currency.short(lineArgs.prize, processedArgs.prizeunit),
Prize_USD = lineDisplay.usd_number,
Prize_Euro = lineDisplay.eur_number,
Prize_Other = lineArgs.otherprize,
Team = lineArgs.team and m_team.teamlinkname(lineArgs.team),
UniqueLine = mw.title.getCurrentTitle().text .. '_' .. util_vars.setGlobalIndex('TRL_line'),
Phase = processedArgs.phase,
OverviewPage = mw.title.getCurrentTitle().text,
ForceNewPlace = lineArgs.forcenewplace,
}
local extraCargoData
if processedArgs.preload == 'Player' then
extraCargoData = h.getPlayerSpecificCargo(lineArgs, processedArgs, lineDisplay)
elseif processedArgs.preload == 'Team' then
extraCargoData = h.getTeamSpecificCargo(lineArgs, processedArgs, lineDisplay)
end
util_table.merge(cargoData, extraCargoData)
-- return a table containing the table because maybe we want 2 dif cargo tables
-- storing per line, e.g. TournamentResults & TournamentRosters
return { cargoData }
end
function h.getPlayerSpecificCargo(lineArgs, processedArgs, lineDisplay)
local playerData = {
_table = 'TournamentResults1v1',
Player = lineArgs.player,
PlayerLink = lineArgs.playerlink or lineArgs.player,
}
local lastResult = h.playerLastResultCargo(lineArgs)
util_table.merge(playerData, lastResult)
return playerData
end
function h.playerLastResultCargo(lineArgs)
local lastResult = {
LastResult = lineArgs.lastresult,
LastOpponent = lineArgs.lastopponent,
LastOpponentLink = lineArgs.lastopponentlink or lineArgs.lastopponent,
LastOutcome = lineArgs.lastoutcome and util_esports.outcomes[lineArgs.lastoutcome:lower()],
LastOpponentTeam = lineArgs.lastopponentteam and m_team.teamlinkname(lineArgs.lastopponentteam),
OverviewPage = mw.title.getCurrentTitle().text,
}
return lastResult
end
function h.getTeamSpecificCargo(lineArgs, processedArgs, lineDisplay)
local teamData = {
_table = 'TournamentResults',
Place_Number = util_math.deserialize(lineArgs.place),
Qualified = h.determineQualified(lineArgs),
RosterPage = lineArgs.rosterpage or mw.title.getCurrentTitle().text,
}
local teamlink = lineArgs.team and m_team.teamlinkname(lineArgs.team) or ''
teamData.PageAndTeam = teamData.RosterPage .. '_' .. teamlink
local lastResult = h.teamLastResultCargo(lineArgs)
util_table.merge(teamData, lastResult)
return teamData
end
function h.determineQualified(lineArgs)
if util_args.castAsBool(lineArgs.qualified) then
return 'Yes'
end
return lineArgs.place == 'Q' and 'Yes'
end
function h.teamLastResultCargo(lineArgs)
if lineArgs.groupstage then
return h.lastResultGroupstage(lineArgs)
elseif lineArgs.lastresultpoints then
return h.lastResultPoints(lineArgs)
else
return h.lastResultDefault(lineArgs)
end
end
function h.lastResultGroupstage(lineArgs)
return {
LastResult = lineArgs.lastresult or lineArgs.groupstage,
GroupName = lineArgs.group or 'Group Stage',
LastOpponent_Markup = m_team.rightshortlinked('group stage')
}
end
function h.lastResultPoints(lineArgs)
return {
LastResult = lineArgs.lastresultpoints,
LastOpponent_Markup = m_team.rightshortlinked('points')
}
end
function h.lastResultDefault(lineArgs)
local lastResult = {
LastResult = lineArgs.lastresult,
LastOutcome = util_esports.getOutcomeName(lineArgs.lastoutcome)
}
if lineArgs.lastopponent then
lastResult.LastTeam = m_team.teamlinkname(lineArgs.lastopponent)
lastResult.LastOpponent_Markup = m_team.rightshortlinked(lineArgs.lastopponent)
end
return lastResult
end
function h.determineRowspans(rowData)
local curPlace, curRow, count
for _, row in ipairs(rowData) do
if curPlace ~= row.placeraw or row.forcenewplace then
if curRow then
curRow.rowspan = count
end
curRow = row
count = 1
curPlace = row.placeraw
else
count = count + 1
end
end
if count or 0 > 1 then
curRow.rowspan = count
end
end
-- cargo
function h.storeCargo(linesData)
if h.doWeStoreCargo() then
for _, line in ipairs(linesData) do
local cargoData = line.cargo
if cargoData then
for _, tbl in ipairs(cargoData) do
util_cargo.store(tbl)
end
end
end
end
end
function h.doWeStoreCargo()
return mw.title.getCurrentTitle().nsText == ''
end
-- make output
function h.makeOutput(args, processedArgs, cols, linesData)
h.initializeToggleData()
local output = mw.html.create()
output:wikitext(h.introSentence(args, processedArgs))
h.printCurrencyToggles(output)
h.printTable(output, cols, linesData)
h.creditCurrencyRates(output, args, processedArgs)
return output
end
function h.initializeToggleData()
local i = util_vars.setGlobalIndex('TRL_i')
TOGGLES.class = TOGGLES.class:format(i)
end
function h.introSentence(args, processedArgs)
if not args.totalprize then return '' end
local tempdate = util_args.nilToFalse(args.tempprizedate)
local sentenceParts = {
m_currency.long(processedArgs.totalprize, processedArgs.prizeunit),
tempdate and i18n.print('temp_date', tempdate),
i18n.print('intro'),
}
return util_table.concat(sentenceParts, ' ')
end
function h.printCurrencyToggles(output)
if not HAS_TOGGLES then return end
local div = output:tag('div'):addClass('toggle-button')
util_toggle.printOptionFromListTogglers(div, PRIZE_TOGGLE_DATA)
end
function h.printTable(output, cols, linesData)
local tbl = output:tag('table')
:addClass('wikitable2')
:addClass('tournament-results')
:addClass('zebra-manual')
h.printStartCols(tbl, cols)
local hidden = h.printLines(tbl, cols, linesData)
if hidden then
h.endHiddenResults(tbl, #cols)
end
end
function h.printStartCols(tbl, cols)
local tr = tbl:tag('tr')
for i, v in ipairs(cols) do
tr:tag('th')
:wikitext(cols.displays[i])
end
end
function h.printLines(tbl, cols, linesData)
local hidden = false
local rowspanLeft = 0
local odd = false
for _, line in ipairs(linesData) do
if line.hide then
hidden = true
h.printShowButton(tbl, #cols)
end
local tr = tbl:tag('tr')
if hidden then
util_toggle.sepCellClasses(tr, TOGGLES)
end
local isFullRow = h.printOneLine(tr, cols, line, rowspanLeft, odd)
if rowspanLeft == 1 then odd = not odd end
if odd then
tr:addClass('zebra-manual-odd')
end
if line.rowspan then
rowspanLeft = line.rowspan
else
rowspanLeft = rowspanLeft - 1
end
end
return hidden
end
function h.printShowButton(tbl, colspan)
local tr = tbl:tag('tr')
local th = tr:tag('th')
:attr('colspan', colspan)
util_toggle.printSepToggler(th, TOGGLES)
util_toggle.sepCellClasses(tr, TOGGLES, true)
end
function h.printOneLine(tr, cols, lineDisplay, rowspanLeft, odd)
local isFullRow = false
for _, col in ipairs(cols) do
if rowspanLeft > 1 and ROWSPANS[col] then
-- pass
else
local td = tr:tag('td')
:wikitext(lineDisplay[col])
:addClass(CLASSES[col])
if ROWSPANS[col] then
td:attr('rowspan', lineDisplay.rowspan)
end
end
end
end
function h.endHiddenResults(tbl, colspan)
local tr = tbl:tag('tr')
local th = tr:tag('th')
:attr('colspan', colspan)
util_toggle.sepCellClasses(tr, TOGGLES, false)
util_toggle.printSepToggler(th, TOGGLES, true)
end
function h.creditCurrencyRates(output, args, processedArgs)
if not (args.conversionsource and processedArgs.hasconversion) then
return nil
end
local source = args.conversionsource:lower()
local date = args.conversiondate
local rates = {
USD = processedArgs.usdrate,
Euros = processedArgs.eurorate,
}
local originalUnit = processedArgs.prizeunit
output:wikitext(i18n.print('credit_' .. source,date or i18n.print('unknown_date')))
local ul = output:tag('ul')
for _, v in ipairs(CURRENCY_ORDER) do
if rates[v] then
util_vars.log(v)
ul:tag('li')
:wikitext(m_currency.long(1, originalUnit))
:wikitext(' = ')
:wikitext(m_currency.long(rates[v], v))
end
end
return output
end
return p