Leaguepedia | League of Legends Esports Wiki
Advertisement
Leaguepedia | League of Legends Esports Wiki

Documentation for this module may be created at Module:MVPStandings/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_sort = require('Module:SortUtil')
local util_table = require('Module:TableUtil')
local util_text = require('Module:TextUtil')
local util_vars = require("Module:VarsUtil")
local i18n = require('Module:i18nUtil')

local Team = require('Module:TeamClass')

local lang = mw.getLanguage('en')

local HEADING_DATA = {
	both = { 'Rank', 'Times', 'Points', 'Player' },
	times = { 'Rank', 'Times', 'Player' },
	points = { 'Rank', 'Points', 'Player' },
}

local WIDTHS = {
	Rank = 45,
	Times = 50,
	Points = 60,
	Player = 200
}

local h = {}
local p = {}

function p.main(frame)
	local args = util_args.merge()
	i18n.init('MVPStandings')
	local showlimit = tonumber(args.showlimit) or 5
	local result = h.getTotals(args)
	h.processResult(result)
	local headings = h.pickHeadings(lang:lc(args.columns or 'both'))
	local displaytext = args.displaytext or i18n.print('defaultHeading')
	return h.printTable(result, showlimit, headings, displaytext)
end

function h.getTotals(args)
	local result_count = h.doPlayerCountQuery(args)
	local result_teams = h.doTeamQuery(args)
	local totals = h.countTotals(result_count, result_teams)
	return totals
end

function h.doPlayerCountQuery(args)
	-- an mvp can be either in a match or in a game
	-- therefore it can be stored in either of 2 tables
	-- so here we have to look at the columns MS.MVP and also MSG.MVP
	-- and treat them interchangeably, using COALESCE/CASE to achieve this
	
	-- yes a better solution would maybe be to have a standalone table just for MVPs
	-- but that would add too much extra save time to data pages
	local query = {
		tables = {
			'MatchSchedule=MS',
			'MatchScheduleGame=MSG',
			'PlayerRedirects=PR1',
			'PlayerRedirects=PR2',
		},
		join = {
			'MS.MatchId=MSG.MatchId',
			'MS.MVP=PR1.AllName',
			'MSG.MVP=PR2.AllName',
		},
		fields = {
			'COALESCE(MSG.MVP, MS.MVP)=MVP',
			'COALESCE(MSG.MVPPoints, MS.MVPPoints)=Points [number]',
			'COALESCE(PR1._pageName, PR2._pageName)=PlayerPage',
		},
		where = h.makePlayerCountWhere(args),
		groupBy = 'CASE WHEN MS.MVP IS NULL THEN MSG.GameId ELSE MS.MatchId END',
	}
	return util_cargo.queryAndCast(query)
end

function h.makePlayerCountWhere(args)
	local tbl = {
		('MS.OverviewPage="%s"'):format(util_esports.getOverviewPage(args.page)),
		'COALESCE(MSG.MVP, MS.MVP) IS NOT NULL AND COALESCE(MSG.MVP, MS.MVP) != "N/A"',
	}
	return util_table.concat(tbl, ' AND ')
end

function h.doTeamQuery(args)
	local query = {
		tables = { 'TournamentPlayers', 'PlayerRedirects=PR' },
		fields = {
			'TournamentPlayers.Link=MVP',
			'TournamentPlayers.Team',
			'PR._pageName=PlayerPage'
		},
		where = h.makeTeamWhere(args),
		join = 'TournamentPlayers.Player=PR.AllName',
		limit = 9999,
	}
	local result = util_cargo.queryAndCast(query)
	return h.makeTeamDict(result)
end

function h.makeTeamWhere(args)
	local tbl = {
		('TournamentPlayers.OverviewPage="%s"'):format(util_esports.getOverviewPage(args.page)),
	}
	return util_table.concat(tbl, ' AND ')
end

function h.makeTeamDict(result)
	local tbl = {}
	for _, row in ipairs(result) do
		if row.PlayerPage or row.MVP then
			tbl[util_text.ucfirst(row.PlayerPage or row.MVP)] = row.Team
		end
	end
	return tbl
end

function h.countTotals(data, data_teams)
	local tbl = {}
	for i, row in ipairs(data) do
		local player = row.PlayerPage or row.MVP
		local key = util_text.ucfirst(row.PlayerPage or row.MVP)
		if player and not tbl[key] then
			tbl[key] = mw.clone(row)
			tbl[key].Times = 1
			tbl[key].Team = data_teams[key]
			tbl[#tbl+1] = key
		elseif player then
			tbl[key].Times = tbl[key].Times + 1
			tbl[key].Points = tbl[key].Points + row.Points
		end
	end
	util_sort.dictByKeys(tbl, {'Points', 'MVP'}, { false, true })
	return tbl
end

-- process
function h.processResult(result)
	local cur_points
	local cur_rank = 1
	for i, player in ipairs(result) do
		local row = result[player]
		if row.Points ~= cur_points then
			cur_rank = i
			cur_points = row.Points
		end
		row.Rank = cur_rank
		if row.Team then
			row.Player = ('%s %s'):format(
				Team(row.Team):imagelink{len='medium'} or '',
				util_esports.playerLinked(row.MVP)
			)
		else
			util_vars.log(row)
			row.Player = util_esports.playerLinked(row.MVP)
		end
	end
end

function h.pickHeadings(columns)
	if not HEADING_DATA[columns] then
		error('Invalid columns argument')
	end
	local tbl = {
		names = HEADING_DATA[columns],
		widths = {}
	}
	for i, v in ipairs(tbl.names) do
		tbl.widths[i] = WIDTHS[v]
	end
	return tbl
end

function h.printTable(result, limit, headings, displaytext)
	local output = mw.html.create()
	local tbl = output:tag('table')
		:addClass('wikitable')
		:addClass('mvp-standings')
	util_html.printEmptyWidthRowPX(tbl, headings.widths)
	util_html.printColspanHeader(tbl, displaytext, #headings.names)
	util_html.printHeaderFromI18n(tbl, headings.names)
		:addClass('column-label-small')
	h.addRows(result, headings.names, tbl, 1, limit)
	if limit < #result then
		local tbl2 = output:tag('table')
			:addClass('wikitable mw-collapsible mw-collapsed')
			:addClass('mvp-standings-more')
		util_html.printColspanHeader(tbl2, i18n.print('expandText'), #headings.names, nil, util_math.sum(headings.widths))
		util_html.printEmptyWidthRowPX(tbl2, headings.widths)
		h.addRows(result, headings.names, tbl2, limit + 1, #result)
	end
	return output
end

function h.addRows(result, columns, tbl, i_start, i_end)
	for i = i_start, i_end do
		if result[i] then
			h.addRow(tbl, result[result[i]], columns)
		end
	end
	return
end

function h.addRow(tbl, row, columns)
	local tr = tbl:tag('tr')
	util_esports.addTeamHighlighter(tr, row.Team)
	for _, v in ipairs(columns) do
		tr:tag('td'):wikitext(row[v])
	end
end

return p
Advertisement