Leaguepedia | League of Legends Esports Wiki

Documentation for this module may be created at Module:TeamSchedule/doc

local util_args = require('Module:ArgsUtil')
local util_cargo = require('Module:CargoUtil')
local util_esports = require("Module:EsportsUtil")
local util_map = require("Module:MapUtil")
local util_time = require('Module:TimeUtil')
local util_vars = require("Module:VarsUtil")
local m_team = require('Module:Team')
local lang = mw.getLanguage('en')

local COLUMNS = { 'Date', 'Event', 'Round', 'Side', 'Opponent', 'Result', 'Score' }
local SIDES = { [1] = 'Blue', [2] = 'Red' }

local DEBUG = false

local h = {}

local p = {}
function p.main(frame)
	local args = util_args.merge()
	h.castArgs(args)
	h.setDebugStatus(args)
	h.setColumnsBasedOnDebugStatus()
	local team = args.team and m_team.teamlinkname(args.team) or mw.title.getCurrentTitle().baseText
	local query = h.query(team)
	local result = util_cargo.queryAndCast(query)
	local processed = h.processData(result, team)
	return h.printTable(processed)
end

function h.castArgs(args)
	args.debug = util_args.castAsBool(args.debug)
end

function h.setDebugStatus(args)
	DEBUG = args.debug
end

function h.setColumnsBasedOnDebugStatus()
	if not DEBUG then return end
	COLUMNS[#COLUMNS+1] = 'Team1'
	COLUMNS[#COLUMNS+1] = 'Team2'
	COLUMNS[#COLUMNS+1] = '_side'
	COLUMNS[#COLUMNS+1] = 'Winner'
	COLUMNS[#COLUMNS+1] = 'Team1Page'
	COLUMNS[#COLUMNS+1] = 'Team2Page'
end

function h.query(team)
	local baseQuery = {
		tables = {
			'MatchSchedule=MS',
			'MatchScheduleGame=MSG',
			'TeamRedirects=MTR1',
			'TeamRedirects=MTR2',
		},
		join = {
			'MS.MatchId=MSG.MatchId',
			'MS.Team1=MTR1.AllName',
			'MS.Team2=MTR2.AllName',
		},
		fields = {
			-- if game is null then we'll assume blue and red are done properly in the match
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Blue IS NOT NULL THEN MSG.Blue ELSE MS.Team1 END) = Team1',
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Red IS NOT NULL THEN MSG.Red ELSE MS.Team2 END) = Team2',
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Blue = MS.Team1 THEN MTR1._pageName WHEN MS.BestOf = "1" AND MSG.Red = MS.Team1 THEN MTR2._pageName ELSE MTR1._pageName END) = Team1Page',
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Red = MS.Team1 THEN MTR1._pageName WHEN MS.BestOf = "1" AND MSG.Blue = MS.Team1 THEN MTR2._pageName ELSE MTR2._pageName END) = Team2Page',
			'MS.DateTime_UTC',
			'MS.OverviewPage',
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Blue IS NOT NULL THEN MSG.Winner ELSE MS.Winner END) = Winner[number]',
			'MS.Tab',
			'MS.Round',
			
			'MSG.Blue',
			'MSG.Red',
			
			-- the following 2 cases auto fallback to MS when MSG is null
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Winner = "1" THEN "1" WHEN MS.BestOf = "1" AND MSG.Winner = "2" THEN "0" ELSE MS.Team1Score END) = Team1Score [number]',
			'CONCAT(CASE WHEN MS.BestOf = "1" AND MSG.Winner = "1" THEN "0" WHEN MS.BestOf = "1" AND MSG.Winner = "2" THEN "1" ELSE MS.Team2Score END) = Team2Score [number]',
			'MS.FF [number]',
			'MS.ShownName',
			'MS.BestOf [number]',
			'MS._pageName=DataPage',
			'MS.MatchId',
		},
		orderBy = 'DateTime_UTC DESC',
		groupBy = 'MS.MatchId',
		limit = 200,
	}
	local query1 = mw.clone(baseQuery)
	local query2 = mw.clone(baseQuery)
	query1.where = h.getWhere(team, 1)
	query2.where = h.getWhere(team, 2)
	local query = {
		query1, query2,
		union = true,
		sortKey = { 'DateTime_UTC' },
		sortOrder = { false },
		uniqueKey = 'MatchId',
	}
	return query
end

function h.getWhere(team, i)
	local where = {
		('(MTR%s._pageName="%s")'):format(i, team),
		'MS.Winner IS NOT NULL',
		'MS.IsNullified IS NULL OR MS.IsNullified = "0"',
	}
	return util_cargo.concatWhere(where)
end

function h.processData(result, team)
	util_map.rowsInPlace(result, h.processRow, team)
	local ret = {}
	for i = 1, 200 do
		ret[#ret+1] = result[i]
	end
	return ret
end

function h.processRow(row, team)
	-- coalesce in THIS fields list would just be, too much, so do it here
	row.Team1Page = row.Team1Page or row.Team1
	row.Team2Page = row.Team2Page or row.Team2
	row._side = h.getSide(team, row.Team1Page, row.Team2Page, row.DataPage)
	row._otherSide = util_esports.otherTeamN(row._side)
	local winner = h.getWinner(row.Winner, row._side)
	local result = winner == 'Draw' and 'Draw' or winner and 'Win' or 'Loss'
	local isBO1 = h.isBO1(row.Team1Score, row.Team2Score)
	util_esports.setScoreDisplays(row)
	row.Date = util_time.dateInLocal(row.DateTime_UTC)
	row.Event = ('[[%s|%s]]'):format(row.OverviewPage, row.ShownName or '')
	row.Round = row.Tab or row.Round or ''
	row['Team 1'] = m_team.rightmediumlinked(row.Team1)
	row['Team 2'] = m_team.rightmediumlinked(row.Team2)
	row.Opponent = row[('Team %s'):format(row._otherSide)]
	row.Side = isBO1 and SIDES[row._side] or 'Series'
	row.Result = result
	row.Score = h.getScore(row)
	row.classes = {
		('teamschedule-side-%s'):format(isBO1 and row._side or 'Series'),
		('teamschedule-result-%s'):format(result),
		Side = 'standings-mhside' .. (isBO1 and row._side or 'Series'),
		Result = 'standings-mhwl' .. (winner == 'Draw' and '' or winner and 1 or 0)
	}
	return row
end

function h.getSide(team, team1, team2, dataPage)
	if team1 and not team2 then return 1 end
	if team2 and not team1 then return 2 end
	if team1 and mw.ustring.lower(team1) == mw.ustring.lower(team) then
		return 1
	end
	if team2 and mw.ustring.lower(team2) == mw.ustring.lower(team) then
		return 2
	end
	error(("team %s seems not to be in match - page %s, %s vs %s"):format(
		team,
		dataPage,
		team1,
		team2
	))
end

function h.getWinner(winner, side)
	if winner == 0 then
		return 'Draw'
	end
	return winner == side
end

function h.isBO1(score1, score2)
	score1 = score1 or 0
	score2 = score2 or 0
	local max = math.max(score1, score2)
	local total = score1 + score2
	return max == 1 and total == 1
end

function h.getScore(row)
	return ('%s - %s'):format(
		row.Team1ScoreDisplay or 'Missing Data',
		row.Team2ScoreDisplay or 'Missing Data'
	)
end

function h.printTable(processed)
	local tbl = mw.html.create('table')
		:addClass('wikitable hoverable-rows')
		:attr('id', 'teamschedule-history-table')
	h.addHeading(tbl)
	for _, row in ipairs(processed) do
		local tr = tbl:tag('tr')
		for _, class in ipairs(row.classes) do
			tr:addClass(class)
		end
		for _, col in ipairs(COLUMNS) do
			tr:tag('td')
				:wikitext(row[col])
				:addClass(row.classes[col])
		end
	end
	return tbl
end

function h.addHeading(tbl)
	local tr = tbl:tag('tr')
	for _, col in ipairs(COLUMNS) do
		tbl:tag('th'):wikitext(col)
	end
	return
end

return p