Module:RecentMatches

From TwogPedia
Revision as of 20:12, 12 November 2023 by Couchor (talk | contribs)

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

local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo
local Func = require('Module:Functions')
local getTeamLogo = Func.getTeamLogo
local makeFlag = require('Module:Person/Flag').makeFlag
local stringifyDate = Func.stringifyDate
local prizeToString = Func.prizeToString
local getTeamDisplaytitle = Func.getTeamDisplaytitle

local p = {}

function p.team(frame)
	local args = getArgs(frame)
	local currentPage = mw.title.getCurrentTitle().text

    -- RECENT MATCHES
	local tables = 'AllMatches'
	local fields = '_ID, _pageName, p1, p2, p1score, p2score, winner, date, bestof, stage'
	local cargoArgs = {
		where = '(p1 = "' .. currentPage .. '" OR p2="' .. currentPage .. '") AND winner IS NOT NULL AND winner != "0"',
		limit = args.limit or 1000,
		orderBy = 'date desc'
	}
	
	local results = cargo.query(tables, fields, cargoArgs)
	
	local container = mw.html.create('div')
	local types = 0

	local recentMatches = nil
	if #results > 0 then
		types = types + 1
	end
	
	-- Tournament placements
	tables = 'Prizes, Tournaments'
	fields = 'Prizes.prize=prize, Prizes.placement=placement, Tournaments._pageName=_pageName, Tournaments.type=type, Tournaments.start=start, Tournaments.end=end, Tournaments.country=country, Tournaments.participants=participants, Tournaments.formatFilter=formatFilter, Tournaments.logoAll=logoAll, Tournaments.logoLight=logoLight, Tournaments.logoDark=logoDark, Tournaments.iconAll=iconAll, Tournaments.iconLight=iconLight, Tournaments.iconDark=iconDark'
	cargoArgs = {
		join = 'Prizes._pageName=Tournaments._pageName',
		where = 'Prizes.teams HOLDS "' .. currentPage .. '" and Prizes.placement IS NOT NULL',
		orderBy = 'Tournaments.end desc'
	}
	tResults = cargo.query(tables, fields, cargoArgs)

	local tournaments = nil
	if #tResults > 0 then
		types = types + 1
	end

	if #results > 0 then
		recentMatches =	matchesHtml(results, currentPage)	
	end
	
	if #tResults > 0 then
		tournaments = tournamentResults(tResults)	
	end
	
	if types > 1 then
		local str = '<tabber>'
		if recentMatches then
			str = str .. '|-|Recent matches=' .. tostring(recentMatches)
		end
		if tournaments then
			str = str .. '|-|Tournament results=' .. tostring(tournaments)
		end
		str = str .. '</tabber>'
		container:node(frame:preprocess(str))
	else
		if recentMatches then
			container:node(mw.html.create('h2'):wikitext('Recent matches')):node(recentMatches)
		end
		if tournaments then
			container:node(mw.html.create('h2'):wikitext('Tournament results')):node(tournaments)
		end
	end
	
	if types > 0 then return container end
end

function p.person(frame)
	local args = getArgs(frame)
	local currentPage = mw.title.getCurrentTitle().text
	
	-- MATCHES IN 1v1
	local tables = 'AllMatches'
	local fields = '_ID, _pageName, p1, p2, p1score, p2score, winner, date, bestof, stage'
	local cargoArgs = {
		where = '(p1 = "' .. currentPage .. '" OR p2="' .. currentPage .. '") AND winner IS NOT NULL AND winner != "0"',
		limit = args.limit or 1000,
		orderBy = 'date desc'
	}
	
	local results = cargo.query(tables, fields, cargoArgs)
	local types = 0

	local container = mw.html.create('div')
	local soloMatches = nil
	if #results > 0 then
		types = types + 1
		soloMatches = matchesHtml(results)
	end
	
	-- MATCHES AS PART OF A TEAM
	tables = 'Participants, Tournaments'
	fields = 'Participants._pageName=_pageName, Participants.team=team'
	cargoArgs = {
		join = 'Participants._pageName=Tournaments._pageName',
		where = 'players HOLDS "' .. currentPage .. '"',
		orderBy = 'Tournaments.end DESC, Tournaments.start DESC'
	}
	results = cargo.query(tables, fields, cargoArgs)
	
	local teamMatches = nil 
	if #results > 0 then
		types = types + 1
		local team = results[1].team
		local tournamentsStr = '('
		for i = 1, #results do
			if i > 1 then tournamentsStr = tournamentsStr .. ' OR ' end
			tournamentsStr = tournamentsStr .. '_pageName LIKE "%' .. results[i]._pageName .. '%"'
		end
		tournamentsStr = tournamentsStr .. ') AND '
		tables = 'AllMatches'
		fields = '_ID, _pageName, p1, p2, p1score, p2score, winner, date, bestof, stage'
		local whereStr = '(p1 = "' .. team .. '" OR p2="' .. team .. '") AND winner IS NOT NULL AND winner != "0"'

		cargoArgs = {
			where = tournamentsStr .. whereStr,
			limit = args.limit or 1000,
			orderBy = 'date desc'
		}
		local matchResults = cargo.query(tables, fields, cargoArgs)
		
		if #matchResults > 0 then
			teamMatches = matchesHtml(matchResults, team)
		end

	end
	
	-- AS CASTERS
	tables = 'AllMatches'
	fields = '_ID, _pageName, p1, p2, p1score, p2score, winner, date, bestof, stage'
	cargoArgs = {
		where = 'casters HOLDS "' .. currentPage .. '" AND winner IS NOT NULL AND winner != "0"',
		limit = args.limit or 1000,
		orderBy = 'date desc'
	}
	local casterResults = cargo.query(tables, fields, cargoArgs)

	local casterMatches = nil
	if #casterResults > 0 then
		types = types + 1
		casterMatches = matchesHtml(casterResults, false, true)
	end
	
	-- AS OBSERVER
	tables = 'AllMatches'
	fields = '_ID, _pageName, p1, p2, p1score, p2score, winner, date, bestof, stage'
	cargoArgs = {
		where = 'observers HOLDS "' .. currentPage .. '" AND winner IS NOT NULL AND winner != "0"',
		limit = args.limit or 1000,
		orderBy = 'date desc'
	}
	local observerResults = cargo.query(tables, fields, cargoArgs)

	local observerMatches = nil
	if #observerResults > 0 then
		types = types + 1
		observerMatches = matchesHtml(observerResults, false, true)
	end
	
	-- TOURNAMENTS AS TALENT
	tables = 'Talent, Tournaments'
	fields = 'Talent.role=role, Talent.lang=lang, Tournaments.prize=prize, Tournaments._pageName=_pageName, Tournaments.type=type, Tournaments.start=start, Tournaments.end=end, Tournaments.country=country, Tournaments.participants=participants, Tournaments.formatFilter=formatFilter, Tournaments.logoAll=logoAll, Tournaments.logoLight=logoLight, Tournaments.logoDark=logoDark, Tournaments.iconAll=iconAll, Tournaments.iconLight=iconLight, Tournaments.iconDark=iconDark'
	cargoArgs = {
		join = 'Talent._pageName=Tournaments._pageName',
		where = 'Talent.people HOLDS "' .. currentPage .. '"',
		orderBy = 'Tournaments.end desc'
	}
	local talentResults = cargo.query(tables, fields, cargoArgs)
	
	local talentTournaments = nil
	if #talentResults > 0 then
		types = types + 1
		talentTournaments = tournamentResults(talentResults, true)
	end

	if types > 1 then
		local str = '<tabber>'
		if soloMatches then
			str = str .. '|-|Solo matches=' .. tostring(soloMatches)
		end
		if teamMatches then
			str = str .. '|-|Team matches=' .. tostring(teamMatches)
		end
		if casterMatches then
			str = str .. '|-|Commentated matches=' .. tostring(casterMatches)
		end
		if observerMatches then
			str = str .. '|-|Observed matches=' .. tostring(observerMatches)
		end
		if talentTournaments then
			str = str .. '|-|Talent at tournaments=' .. tostring(talentTournaments)
		end
		str = str .. '</tabber>'
		container:node(frame:preprocess(str))
	else
		if soloMatches then
			container:node(mw.html.create('h2'):wikitext('Solo matches')):node(soloMatches)
		end
		if teamMatches then
			container:node(mw.html.create('h2'):wikitext('Team matches')):node(teamMatches)
		end
		if casterMatches then
			container:node(mw.html.create('h2'):wikitext('Commentated matches')):node(casterMatches)
		end
		if observerMatches then
			container:node(mw.html.create('h2'):wikitext('Observed matches')):node(observerMatches)
		end
		if talentTournaments then
			container:node(mw.html.create('h2'):wikitext('Talent at tournaments')):node(talentTournaments)
		end
	end
	
	
	if types > 0 then return container end
end

function matchesHtml(results, team, talent)
	local game = mw.text.split(results[1]._pageName, '/')[1]
	local tournamentTh = mw.html.create('th'):wikitext('Tournament')
	local dateTh = mw.html.create('th'):wikitext('Date')
	local typeTh = mw.html.create('th'):wikitext('Type')
	local scoreTh = mw.html.create('th'):wikitext('Score')
	local vsTh = mw.html.create('th'):wikitext('Opponent')
	local vodTh = mw.html.create('th'):wikitext('VODs')
	local headerRow = mw.html.create('tr'):addClass('headerRow'):node(dateTh):node(tournamentTh):node(typeTh):node(scoreTh)
	if not talent then headerRow:node(vsTh) end
	headerRow:node(vodTh)
	local tbl = mw.html.create('table'):addClass('striped-table'):node(headerRow)
	
	local container = mw.html.create('div')
	container:node(tbl)
	
	for i = 1, #results do
		local result = results[i]
		local opponent
		local score
		local opponentScore

		if result.p1 == team or result.p1 == mw.title.getCurrentTitle().text then 
			score = result.p1score
			opponentScore = result.p2score
			opponent = result.p2
		else 
			score = result.p2score
			opponentScore = result.p1score
			opponent = result.p1
		end
	
		tables = 'Tournaments'
		fields = '_pageName, type, logoAll, logoLight, logoDark, iconAll, iconLight, iconDark'
		cargoArgs = {
			where = '(_pageName = "' .. result._pageName  .. '" OR _pageName = "' .. removeLastPart(result._pageName) .. '")'
		}
		tournaments = cargo.query(tables, fields, cargoArgs)

		local dateTd = mw.html.create('td'):wikitext(stringifyDate(result.date) .. ' '):node(mw.html.create('abbr'):attr('title', 'Coordinated Universal Time'):wikitext('UTC'))
		local tournamentTd = mw.html.create('td')
		local typeTd = mw.html.create('td')
		local scoreTd = mw.html.create('td'):addClass('tc')
		-- If caster or observer, then show both teams and score
		if talent then
			-- If a team
			if mw.text.split(result.p1, '/')[1] ~= 'People' then
				scoreTd:node(mw.html.create('div'):attr('style', 'display: flex; gap: 0.2rem; align-items: center;'):node(getTeamLogo(result.p1, game, '20x20px')):wikitext('[[' .. result.p1 .. '|' .. getTeamDisplaytitle(result.p1, result.date) .. ']]')):wikitext(' ' .. result.p1score .. ':' .. result.p2score .. ' '):node(mw.html.create('div'):attr('style', 'display: flex; gap: 0.2rem; align-items: center;'):node(getTeamLogo(result.p2, game, '20x20px')):wikitext('[[' .. result.p2 .. '|' .. getTeamDisplaytitle(result.p2, result.date) .. ']]'))
			else
				-- If 1v1
				scoreTd:node(mw.html.create('div'):attr('style', 'display: flex; gap: 0.2rem; align-items: center;'):node(makeFlag(nil, result.p1)):wikitext('[[' .. result.p1 .. '|' .. getTeamDisplaytitle(result.p1, result.date) .. ']]')):wikitext(' ' .. result.p1score .. ':' .. result.p2score .. ' '):node(mw.html.create('div'):attr('style', 'display: flex; gap: 0.2rem; align-items: center;'):node(makeFlag(nil, result.p2)):wikitext('[[' .. result.p2 .. '|' .. getTeamDisplaytitle(result.p2, result.date) .. ']]'))
			end
			
		else
			scoreTd:wikitext(score .. ':' .. opponentScore)
		end
	
		local opponentTd = mw.html.create('div'):attr('style', 'display: flex; gap: 0.2rem; align-items: center;')
		local vsTd = mw.html.create('td'):node(opponentTd)
		
		if team then
			opponentTd:node(getTeamLogo(opponent, game, '20x20px')):wikitext('[[' .. opponent .. '|' .. getTeamDisplaytitle(opponent, result.date) .. ']]')
		else
			opponentTd:wikitext(makeFlag(nil, opponent)):wikitext('[[' .. opponent .. ']]')
		end

		local vodTd = mw.html.create('td')
		local resultRow = mw.html.create('tr'):addClass('bodyRow'):node(dateTd):node(tournamentTd):node(typeTd):node(scoreTd)
		if not talent then resultRow:node(vsTd) end 
		resultRow:node(vodTd)
		if #tournaments > 0 then
			local tournament = tournaments[1]
			local icon = tournament.iconAll or tournament.iconLight or tournament.iconDark or tournament.logoAll or tournament.logoDark or tournament.logoLight or 'Tournament_placeholder.png'
			tournamentTd:wikitext('[[File:' .. icon .. '|25x25px]]'):wikitext('[[' .. result._pageName .. ']]')
			typeTd:wikitext(tournament.type)
		end
		
		-- Get VODs
		if game == 'Dota2' then
			tables = 'Maps_Dota'
			fields = 'yt, vod'
			cargoArgs = {
				where = 'matchID ="' .. result._ID .. '"',
				orderBy = 'map'
			}
			
			local vods = cargo.query(tables, fields, cargoArgs)
			if #vods > 0 then
				for j = 1, #vods do
					local vod = vods[j]
					if vod.yt then
						vodTd:wikitext('[[File:Youtube.png|20x20px|link=https://www.youtube.com/watch?v=' .. vod.yt .. '|Map ' .. j .. ']]')
					end
				end
			end
		end
		
		tbl:node(resultRow)
	end
	tbl:node(mw.html.create('tr'):node(mw.html.create('td'):addClass('tc'):attr('colspan', 10):wikitext('[[' .. mw.title.getCurrentTitle().text .. '/' .. (talent and 'Broadcasts' or 'Results') .. '|' .. (talent and 'All Broadcasts' or 'All Results') .. ']]')))
	
	return container
end

function tournamentResults(results, talent)
	local container = mw.html.create('div')

	if #results > 0 then
		local monthNames = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
		
		local roleTh = mw.html.create('th'):wikitext('Role')
		local typeTh = mw.html.create('th'):wikitext('Type')
		local nameTh = mw.html.create('th'):wikitext('Name')
		local dateTh = mw.html.create('th'):wikitext('Date')
		local prizeTh = mw.html.create('th'):wikitext(talent and 'Prize' or 'Winnings')
		local placementTh = mw.html.create('th'):wikitext(talent and 'Winner' or 'Placement')
		local tableHeader = mw.html.create('tr'):addClass('tournament__header')
		if talent then
			tableHeader:node(roleTh)
		else
			tableHeader:node(typeTh)
		end
		tableHeader:node(nameTh):node(dateTh):node(prizeTh):node(placementTh)
		
		local listTable = mw.html.create('table'):addClass('tournament__table'):attr('style', 'width: -webkit-fill-available;'):node(tableHeader)
		container:node(listTable)

		for i = 1, #results do
			local result = results[i]
			local icon = result.iconAll ~= '' and result.iconAll or result.iconLight ~= '' and result.iconLight or result.iconDark ~= '' and result.iconDark or result.logoAll ~= '' and result.logoAll or result.logoDark ~= '' and result.logoDark or result.logoLight ~= '' and result.logoLight
			if not icon then icon = 'Tournament_placeholder.png' end
			
			local roleTd = mw.html.create('td')
			local typeTd = mw.html.create('td')
			local nameTd = mw.html.create('td'):node(mw.html.create('div'):addClass('tournament__name'):wikitext('[[File:' .. icon .. '|25px]]'):wikitext('[[' .. result._pageName .. ']]'))
			local dateTd = mw.html.create('td')
			local prizeTd = mw.html.create('td'):wikitext('$' .. prizeToString(result.prize))
			local placementTd = mw.html.create('td'):addClass('tc')
			
			if talent then
				roleTd:wikitext(result.lang .. ' ' .. string.sub(result.role, 1, -2))
				tables = "Prizes"
			    fields = "teams"
			    cargoArgs = {
			    	where = 'placement="1" AND _pageName="' .. result._pageName .. '"'
			    }
			    local prizeResults = cargo.query(tables, fields, cargoArgs)
			    
			    if #prizeResults > 0 then
			    	placementTd:node(getTeamLogo(prizeResults[1].teams, mw.text.split(result._pageName, '/')[1], '30x30px'))
				else
					placementTd:wikitext('TBD')	
			    end
			else
				placementTd:wikitext(result.placement)
			end
			
			local tournamentType = result.type and mw.text.split(result.type, ',')
			for j = 1, #tournamentType do
				typeTd:node(mw.html.create('div'):wikitext(tournamentType[j]))
			end
			
			local startDate = 'TBD'
			if result.start then
				local year, month, day = result.start:match("(%d+)-(%d+)-(%d+)")
				local monthName = monthNames[tonumber(month)]
				startDate = monthName .. " " .. day .. ", " .. year
			end
			local endDate = 'TBD'
			if result['end'] then
				year, month, day = result['end']:match("(%d+)-(%d+)-(%d+)")
				monthName = monthNames[tonumber(month)]
				endDate = monthName .. " " .. day .. ", " .. year
			end
			dateTd:node(mw.html.create('div'):wikitext(startDate)):node(mw.html.create('div'):wikitext('-')):node(mw.html.create('div'):wikitext(endDate))
			
			local tournamentRow = mw.html.create('tr')
			if talent then
				tournamentRow:node(roleTd)
			else
				tournamentRow:node(typeTd)
			end
			tournamentRow:node(nameTd):node(dateTd):node(prizeTd):node(placementTd)
			
			local currentTime = os.time()
			
			local startTime = nil
			if result.start then
				startTime = mw.ustring.gsub(result.start, '(%d+)-(%d+)-(%d+)', function(year, month, day)
				    return os.time({year=tonumber(year), month=tonumber(month), day=tonumber(day)})
				end)	
			end
			local endTime = nil
			if result['end'] then
				endTime = mw.ustring.gsub(result['end'], '(%d+)-(%d+)-(%d+)', function(year, month, day)
				    return os.time({year=tonumber(year), month=tonumber(month), day=tonumber(day)})
				end)
			end

			local date = mw.html.create('div')
			-- If live
			if (startTime ~= nil and os.difftime(currentTime, startTime) > 0) and (endTime == nil or os.difftime(currentTime, endTime) <= 0) then
				date:wikitext('LIVE')
			else 
				local startDate = 'TBD'
				if result.start then
					local year, month, day = result.start:match("(%d+)-(%d+)-(%d+)")
					local monthName = monthNames[tonumber(month)]
					startDate = monthName .. " " .. day .. ", " .. year
				end
				local endDate = 'TBD'
				if result['end'] then
					year, month, day = result['end']:match("(%d+)-(%d+)-(%d+)")
					monthName = monthNames[tonumber(month)]
					endDate = monthName .. " " .. day .. ", " .. year
				end
				date:wikitext(startDate .. ' - ' .. endDate)
			end
		    
			listTable:node(tournamentRow)
		end
		listTable:node(mw.html.create('tr'):node(mw.html.create('td'):addClass('tc'):attr('colspan', 10):wikitext('[[' .. mw.title.getCurrentTitle().text .. '/' .. (talent and 'Broadcasts' or 'Results') .. '|' .. (talent and 'All Broadcasts' or 'All Results') .. ']]')))
		return container
	end
end

function removeLastPart(str)
	local parts = {}

	for part in str:gmatch("[^/]+") do
	    table.insert(parts, part)
	end
	
	table.remove(parts)
	
	return table.concat(parts, "/")
end

return p