Module:TopSchedule

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_table = require('Module:TableUtil') local util_text = require('Module:TextUtil') local util_time = require('Module:TimeUtil') local util_vars = require('Module:VarsUtil')

local m_team = require('Module:Team')

local MIN_EVENTS_COUNT_TO_GROUP = 5 local MIN_EVENTS_COUNT_TO_GROUP_WITH_UNKNOWN_TEAMS = 2 local SECONDS_IN_HOUR = 60 * 60

local FORM_INFO = { form = 'SpoilerFreeSchedule', template = 'SFS' }

local h = {}

local p = {} function p.main(frame) local args = util_args.merge(true) local result = h.doQuery local processed = h.processResult(result) h.formatResults(processed) return h.makeOutput(processed) end

function h.doQuery local query = h.makeQuery(where) return util_cargo.queryAndCast(query) end

function h.makeQuery(where) return { tables = 'MatchSchedule', fields = { 'Team1', 'Team2', 'DateTime_UTC=DateTime', 'OverviewPage', 'HasTime=TimeEntered', 'ShownName', 'Round', 'Tab', 'Stream' },		groupBy = 'UniqueMatch', orderBy = 'DateTime_UTC ASC', where = 'DateTime_UTC > NOW - INTERVAL 3 HOUR AND WINNER IS NULL', limit = 250, types = { TimeEntered = 'boolean' }	} end

function h.processResult(result) local eventCount = h.countEvents(result) local eventsWrittenToOutput = {} local processed = {} for _, row in ipairs(result) do		if not eventsWrittenToOutput[row.groupKey] then row.count = eventCount[row.groupKey] processed[#processed+1] = row end eventsWrittenToOutput[row.groupKey] = eventCount[row.groupKey] end local output = util_table.slice(processed, 1, 25) return output end

function h.countEvents(result) local tracker = {} local eventCount = {} for _, row in ipairs(result) do row.groupKey = row.OverviewPage .. row.DateTime h.updateTracker(tracker, row) if h.doWeGroup(row, tracker.counter) then eventCount[row.groupKey] = tracker.counter end end return eventCount end

function h.updateTracker(tracker, row) if tracker.groupKey == row.groupKey then tracker.counter = (tracker.counter or 0) + 1 else tracker.counter = 1 end tracker.groupKey = row.groupKey end

function h.doWeGroup(row, counter) if row.Team1 == 'TBD' and row.Team2 == 'TBD' then return counter >= MIN_EVENTS_COUNT_TO_GROUP_WITH_UNKNOWN_TEAMS end return counter >= MIN_EVENTS_COUNT_TO_GROUP end

function h.formatResults(result) for i, row in ipairs(result) do		h.addMatchup(row) h.addEventLinked(row) h.addCountdown(row, i)		h.addCalendar(row) end end

function h.addMatchup(row) if row.count then row.Matchup = ('%s Matches'):format(row.count) elseif not (row.Team1 or row.Team2) then row.Matchup = row.Round or row.Tab else Team1Formatted = h.formatTeamForMatchup(row.Team1) Team2Formatted = h.formatTeamForMatchup(row.Team2) row.Matchup = ('%s vs %s'):format(Team1Formatted, Team2Formatted) end end

function h.formatTeamForMatchup(team) if team == 'TBD' then return 'TBD' end return m_team.onlyimagelinked(team, {size = 45}) end

function h.addEventLinked(row) row.EventLinked = util_text.intLink(row.OverviewPage, row.ShownName or row.OverviewPage) end

function h.addCountdown(row, i)	local countdown = util_time.countdown(row.DateTime, {		data_end = 'toggle',		i = 'ts-' .. i,		default = 'LIVE'	}) row.Countdown = util_text.extLinkOrText(row.Stream, countdown) end

function h.addCalendar(row) row.Calendar = util_esports.calendarExtLink(util_form.fullURL(FORM_INFO, {row.OverviewPage})) end

function h.makeOutput(result) local output = mw.html.create('div'):addClass('topschedule') h.printContent(result, output) return output end

function h.printContent(result, div) for i, row in ipairs(result) do		local innerDiv = h.initializeInnerDiv(div, row, i)		h.printHeader(innerDiv, row.EventLinked) h.printVs(innerDiv, row.Matchup) h.printTime(innerDiv, row) end end

function h.initializeInnerDiv(div, row, i)	local expiration = util_time.unixNumber(row.DateTime) + SECONDS_IN_HOUR local innerDiv = div:tag('div') :addClass('topschedule-box') :attr('data-expiration', expiration) :attr('data-i',i) return innerDiv end

function h.printHeader(div, event) div:tag('div') :addClass('topschedule-header') :wikitext(event) end

function h.printVs(div, matchup) local vsOuter = div:tag('div') :addClass('topschedule-vs') :wikitext(matchup) end

function h.printTime(div, row) local timeOuter = div:tag('div') :addClass('topschedule-time plainlinks') :wikitext(row.Countdown, ' &bull; ', row.Calendar) end

return p