Module:RosterChangePortal

From Leaguepedia | League of Legends Esports Wiki
Jump to: navigation, search

To edit the documentation or categories for this module, click here. This module has an i18n file. Click here to edit it.


local util_args = require('Module:ArgsUtil')
local util_cargo = require("Module:CargoUtil")
local util_esports = require("Module:EsportsUtil")
local util_form = require("Module:FormUtil")
local util_html = require("Module:HtmlUtil")
local util_map = require("Module:MapUtil")
local util_news = require("Module:NewsUtil")
local util_source = require("Module:SourceUtil")
local util_table = require("Module:TableUtil")
local util_text = require("Module:TextUtil")
local util_title = require("Module:TitleUtil")
local util_toggle = require("Module:ToggleUtil")
local util_vars = require("Module:VarsUtil")
local i18n = require('Module:i18nUtil')

local m_team = require('Module:Team')
local m_region = require('Module:Region')
local m_role = require('Module:Role')

local GroupedRosterChangesAbstract = require('Module:GroupedRosterChangesAbstract')
local RosterChangePortal = GroupedRosterChangesAbstract:extends()

local lang = mw.getLanguage('en')

local PARTS = { 'Leave', 'Join' }

local PART_COLUMNS = { 'Region', 'Date', 'Team', 'Role', 'Ref' }

local FORM_INFO = { form = 'RosterChangeQuery', template = 'RCQ' }

local DEBUG = false

local PRELOADS_TO_IGNORE = {
	'opportunities', 'set_to_leave', 'remain', 'extended', 'gcd_remain', 'gcd_extended', 'loan_end_and_join',
	join = { 'set_to_leave_already_joined', 'to_academy_also_stay', 'to_main_also_stay' },
	leave = {},
}

local h = {}

local p = {}

function p.main(frame)
	local args = util_args.merge()
	i18n.init('RosterChangePortal')
	local formArgs = h.getFormArgs(args)
	h.castArgs(args)
	h.setConstants(args)
	args.listOfPlayersToQuery = h.makeAndRunListOfPlayersQuery(args)
	if #args.listOfPlayersToQuery == 0 then
		return (":''%s''"):format(i18n.print('noChanges'))
	end
	return h.makeIntro(args, formArgs), RosterChangePortal:init(args), h.makeOutro(args, formArgs)
end

function h.getFormArgs(args)
	local formArgs = mw.clone(args)
	formArgs.showformlink = nil
	return formArgs
end

function h.castArgs(args)
	args.region = args.region and m_region.medium(args.region)
	args.teams = args.teams and util_map.split(args.teams, nil, m_team.teamlinkname)
	args.debug = util_args.castAsBool(args.debug)
end

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

function h.makeAndRunListOfPlayersQuery(args)
	return util_cargo.getOrderedList(h.getListOfPlayersQuery(args), 'player')
end

function h.getListOfPlayersQuery(args)
	local ret = {
		tables = h.getListOfPlayersTables(),
		join = h.getListOfPlayersJoin(),
		where = h.getListOfPlayersWhere(args),
		fields = 'PR._pageName=player',
		groupBy = 'PR._pageName',
	}
	return ret
end

function h.getListOfPlayersTables()
	local ret = {
		'RosterChanges=RC',
		'NewsItems=News',
		'PlayerRedirects=PR',
		'RosterChangePortalDates=Dates',
	}
	return ret
end

function h.getListOfPlayersJoin()
	local ret = {
		'RC.NewsId=News.NewsId',
		'RC.Player=PR.AllName',
		'News.Region=Dates.Region'
	}
	return ret
end

function h.getListOfPlayersWhere(args)
	local argWhere = {
		util_cargo.whereFromArg('News.Region="%s"', args.region),
		h.getTeamsWhereCondition(args.teams),
		'News.ExcludePortal IS NULL OR News.ExcludePortal != "1"',
	}
	util_table.mergeArrays(argWhere, h.getDateWhereCondition(args))
	local where = util_cargo.concatWhere(argWhere)
	util_vars.setVar('where', where)
	return where
end

function h.getDateWhereCondition(args)
	return util_news.getRosterPortalDatesWhereCondition(args.period, 'RC.Date_Sort')
end

function h.getTeamsWhereCondition(teams)
	if not teams then return false end
	return util_map.formatAndConcat(teams, ' OR ', 'RC.Team="%s"')
end

function RosterChangePortal:getTables()
	local ret = {
		'RosterChanges=RC',
		'NewsItems=News',
		'PlayerRedirects=PR',
		'RosterChangePortalDates=Dates',
		'Retirements=R',
	}
	return ret
end

function RosterChangePortal:getJoin()
	local ret = {
		'News.NewsId=RC.NewsId',
		'News.Region=Dates.Region',
		'News.NewsId=R.NewsId',
		'RC.Player=PR.AllName',
	}
	return ret
end

function RosterChangePortal:getFields()
	-- super
	local fields = GroupedRosterChangesAbstract:getFields()
	local extraFields = {
		'R.Player=R_Player',
		'R.Unretires',
		'R._pageName=R_pageName',
	}
	return util_table.mergeArrays(fields, extraFields)
end

function RosterChangePortal:getWhere(args)
	local tbl = {
		'RC._pageName IS NOT NULL OR R._pageName IS NOT NULL',
		h.getMainWhereConditionFromListOfPlayers(args.listOfPlayersToQuery),
		'News.ExcludePortal IS NULL OR News.ExcludePortal != "1"',
		util_news.getExcludedPreloadsWhereCondition(PRELOADS_TO_IGNORE),
		util_cargo.fakeHolds('RC.Tags', args.tag),
	}
	util_table.mergeArrays(
		tbl,
		h.getDateWhereCondition(args)
	)
	return util_cargo.concatWhere(tbl)
end

function h.getMainWhereConditionFromListOfPlayers(listOfPlayers)
	return util_table.concat(listOfPlayers, ' OR ', h.playerToWhere)
end

function h.playerToWhere(player)
	return ('PR._pageName="%s"'):format(player)
end

function RosterChangePortal:getGroupBy()
	return 'News.NewsId, RC.Team, RC.Direction, RC.Player'
end

function RosterChangePortal:getKey(row)
	return row.PlayerLink
end

---------------------------------
-- make changesByLine
---------------------------------

function RosterChangePortal:formatOneRawDataRow(row)
	row.PlayerLink = row.PlayerLink or row.Player or row.R_Player
	self:super('formatOneRawDataRow', row)
end

function RosterChangePortal:isOriginalNews(changesByLine, row, index)
	-- check to see if this piece of news has already been reported (e.g. gcd then confirmation)
	-- if it has then we want to return out of updating based on this row completely
	--if not row.PlayerLink then return false end
	if not index then return true end
	if row.Preload and row.Preload:find('loan') then return h.getLoanNewsStatus(row) end
	for _, info in ipairs(index) do
		if self:teamsAreIdentical(row, self:getOldRowFromIndex(changesByLine, row, info), 'Leave') then
			return false
		elseif self:teamsAreIdentical(row, self:getOldRowFromIndex(changesByLine, row, info), 'Join') then
			return false
		end
	end
	return true
end

function RosterChangePortal:doWeNeedANewLine(changesByLine, row, index)
	return changesByLine[self:getMostRecentLineNumberFromIndex(index)].TeamJoin
end

function h.getLoanNewsStatus(row)
	if row.Preload:find('loaned_from') and row.TeamLeave then return false end
	if row.Preload:find('loan_return') and row.TeamLeave then return false end
	if row.Preload:find('loaned_to') and row.TeamJoin then return false end
	if row.Preload:find('loan_end') and row.TeamJoin then return false end
	return true
end

function RosterChangePortal:teamsAreIdentical(row, oldrow, when)
	if not row['Team' .. when] then return false end
	for _, key in ipairs({ 'Team', 'RoleModifier' }) do
		if not h.keyIsIdentical(row, oldrow, key, when) then
			return false
		end
	end
	return true
end

function h.keyIsIdentical(row, oldrow, key, when)
	return row[key .. when] == oldrow[key .. when]
end

function RosterChangePortal:getMostRecentLineNumberFromIndex(index)
	return index[#index].changeNumber
end

function RosterChangePortal:updateIndexExisting(changesByLine, row, index)
	self:updateIndex(changesByLine, row, index)
end

function RosterChangePortal:updateIndex(changesByLine, row, index)
	index[#index+1] = { changeNumber = #changesByLine }
end

function RosterChangePortal:moveExistingLine(changesByLine, oldIndex)
	changesByLine[#changesByLine+1] = changesByLine[oldIndex]
	self.CHANGES_TO_REMOVE[#self.CHANGES_TO_REMOVE+1] = oldIndex
end

function RosterChangePortal:formatRowForOutput(row)
	row.PlayerLinked = util_esports.playerLinked(row.Player)
	row.RoleLeave = h.getRoleDisplay(row, 'Leave')
	row.RoleJoin = h.getRoleDisplay(row, 'Join')
	row.TeamLeave = h.getTeamDisplay(row, 'Leave')
	row.TeamJoin = h.getTeamDisplay(row, 'Join')
	row.RefLeave = util_news.getSentenceAndRefDisplay(row, 'Leave')
	row.RefJoin = util_news.getSentenceAndRefDisplay(row, 'Join')
	row.RegionLeave = h.getRegionDisplay(row, 'Leave')
	row.RegionJoin = h.getRegionDisplay(row, 'Join')
end

function h.getRoleDisplay(row, when)
	if not row['Role' .. when] then return end
	return util_news.roleOrStaffImage(
		row['Role' .. when],
		row['RoleModifier' .. when] == 'Sub',
		row['RoleModifier' .. when] == 'Trainee'
	)
end

function h.getTeamDisplay(row, when)
	if DEBUG then return row['Team' .. when] end
	if not row['Team' .. when] then return end
	return m_team.onlyimagelinked(row['Team' .. when])
end

function h.getRegionDisplay(row, when)
	if DEBUG then return row ['Region' .. when] end
	return m_region.onlyimage(row['Region' .. when])
end

--------------------------------
-- filter
--------------------------------
function RosterChangePortal:markLineAsUnwanted(row, args)
	if h.isIncompleteAcademyMainTransitionLine(row) then return true end
	if not args.region then return false end
	return row.RegionLeave ~= args.region and row.RegionJoin ~= args.region
end

function h.isIncompleteAcademyMainTransitionLine(row)
	if not h.isAcademyMainTransitionLine(row) then return false end
	return not row.TeamJoin or not row.TeamLeave
end

function h.isAcademyMainTransitionLine(row)
	local academy_main_transfers = { 'to_academy', 'to_main', 'from_academy', 'from_main' }
	return util_table.keyOf(academy_main_transfers, row.PreloadJoin) or util_table.keyOf(academy_main_transfers, row.PreloadLeave)
end

-- output
function h.makeIntro(args, formArgs)
	return util_form.makeIntroSentence(FORM_INFO, args, formArgs)
end

function RosterChangePortal:makeOutput(changesByLine)
	util_table.reverseInPlace(changesByLine)
	local output = mw.html.create()
	local tbl = output:tag('table')
		:addClass('wikitable')
		:addClass('hoverable-rows')
	h.printHeading(tbl)
	h.printTable(tbl, changesByLine)
	return output
end

function h.printHeading(tbl)
	local tr = tbl:tag('tr')
	tr:tag('th')
		:attr('rowspan', 2)
		:wikitext(i18n.print('Player'))
	h.printPartHeadings(tr)
	h.printPartSubheadings(tbl)
end

function h.printPartHeadings(tr)
	for _, v in ipairs(PARTS) do
		tr:tag('th')
			:attr('colspan', #PART_COLUMNS)
			:wikitext(i18n.print(v))
	end
end

function h.printPartSubheadings(tbl)
	local tr = tbl:tag('tr')
	for _, _ in ipairs(PARTS) do
		h.printOnePartHeading(tr)
	end
end

function h.printOnePartHeading(tr)
	for _, v in ipairs(PART_COLUMNS) do
		tr:tag('th')
			:wikitext(i18n.print(v))
	end
end

function h.printTable(tbl, changesByLine)
	for _, row in ipairs(changesByLine) do
		h.printRow(tbl, row)
	end
end

function h.printRow(tbl, row)
	local tr = tbl:tag('tr')
		:addClass('roster-portal-row')
	h.printPlayer(tr, row)
	h.printRowParts(tr, row)
	h.printEditButtons(util_html.lastChild(tr), row)
end

function h.printPlayer(tr, row)
	local td = tr:tag('td'):wikitext(row.PlayerLinked)
end

function h.printRowParts(tr, row)
	for _, part in ipairs(PARTS) do
		h.printOneRowPart(tr, row, part)
	end
end

function h.printOneRowPart(tr, row, part)
	if not row['Team' .. part] then
		h.pickAndPrintNoTeamCell(tr, row)
		return
	end
	for _, v in ipairs(PART_COLUMNS) do
		tr:tag('td')
			:wikitext(row[v .. part])
	end
end

function h.pickAndPrintNoTeamCell(tr, row)
	if row.R_Player then
		h.printNoTeamCell(tr, 'retired')
		return
	end
	h.printNoTeamCell(tr, 'free agent')
end

function h.printNoTeamCell(tr, text)
	tr:tag('td')
		:attr('colspan', #PART_COLUMNS)
		:addClass('roster-portal-fa')
		:wikitext(m_team.rightmedium(text))
end

function h.printEditButtons(td, row)
	td:addClass('roster-portal-lastcell')
	local div = td:tag('div')
		:addClass('roster-portal-edit')
	h.printOneEditButton(div, row._pageNameLeave, 'el')
	h.printOneEditButton(div, row._pageNameJoin, 'ej')
end

function h.printOneEditButton(div, link, text)
	if not link then return end
	div:tag('span')
		:addClass('roster-portal-edit-' .. text)
		:wikitext(util_text.intLink(link, text))
end

function h.makeOutro(args, formArgs)
	if util_args.castAsBool(args.showformlink) then return '' end
	local output = mw.html.create()
	h.printPermalink(output, args, formArgs)
	h.printWhere(output)
	return output
end

function h.printPermalink(output, args, formArgs)
	output:wikitext(
		i18n.print('permalink', util_form.fullURL(FORM_INFO, formArgs))
	)
end

function h.printWhere(output)
	output:tag('br')
	output:wikitext(i18n.print('where', util_vars.getVar('where')))
end

return p