Documentation for this module may be created at Module:GroupedRosterChangesAbstract/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_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_vars = require("Module:VarsUtil")
local i18n = require('Module:i18nUtil')
local RoleList = require('Module:RoleList')
local lang = mw.getLanguage('en')
local LCS = require('Module:LuaClassSystem').class
local h = {}
local p = LCS.abstract()
function p:init(name)
self.CHANGES_TO_REMOVE = {}
if name then i18n.init(name) end
i18n.init('NewsUtil')
end
function p:run(args)
local changesData = self:makeAndRunQuery(args)
self:formatRawDataRows(changesData)
local changesByLine = self:getChangesByLine(changesData)
self:markUnwantedLinesForDeletion(changesByLine, args)
self:removeLinesToDelete(changesByLine)
self:formatForOutput(changesByLine)
self:storeCargo(changesByLine)
return self:makeOutput(changesByLine)
end
function p:makeAndRunQuery(args)
return util_cargo.queryAndCast(self:getQuery(args))
end
function p:getQuery(args, player)
local ret = {
tables = self:getTables(),
join = self:getJoin(),
fields = self:getFields(),
where = self:getWhere(args),
orderBy = self:getOrderBy(),
groupBy = self:getGroupBy(),
limit = self:getLimit(args),
offset = self:getOffset(args),
}
-- util_cargo.logQuery(ret)
return ret
end
function p:getTables() end
function p:getJoin() end
function p:getLimit() end
function p:getOffset() end
function p:getFields()
return {
'RC.Date_Sort',
'RC.Player',
'PR._pageName=PlayerLink',
'RC.Team',
'RC.Role',
'RC.Roles',
'RC.RoleModifier',
'RC.Source',
'RC.IsGCD',
'RC.Preload',
'RC.Direction',
'RC.Status',
'RC._pageName=RCPage',
'RC.RosterChangeId',
'RC.Tags__full=Tags',
'News.Date_Display',
'News.Region [region]',
'News.Sentence',
'News._pageName',
'News.NewsId',
'News.IsApproxDate [boolean]',
}
end
function p:getOrderBy()
return 'News.Date_Sort ASC, News.N_LineInDate ASC, RC.N_LineInNews ASC'
end
function p:getWhere() end
function p:getGroupBy() end
function p:formatRawDataRows(changesData)
-- ensure stuff is properly separated for start/end
-- this way later on we can simply merge the two rows and have a fluid start -> end
for _, row in ipairs(changesData) do
self:formatOneRawDataRow(row)
end
end
function p:formatOneRawDataRow(row)
if not row.RCPage then
self:formatOneNonRCRow(row)
return
end
row.Key = self:getKey(row)
row.Roles = RoleList(row.Roles, { modifier = row.RoleModifier })
row.RolesString = row.Roles:names()
row.Date_Sort = lang:formatDate('Y-m-d', row.Date_Sort)
row.Date = row.Date_Sort
row.RoleArgs = { sub = row.RoleModifier == 'Sub', trainee = row.RoleModifier == 'Trainee' }
if not row.Direction then error(('Missing direction: %s'):format(row.NewsId)) end
for _, v in ipairs(util_news.ALL_POSSIBLE_CHANGES) do
row[v .. (row.Direction or '')] = row[v]
end
h.copyConstantsToWhen(row, (row.Direction or ''))
row.PlayerLink = row.PlayerLink or row.Player
row.RosterChangeIds = { row.RosterChangeId }
if row.Tags then row.Tags = util_text.split(row.Tags) end
end
function p:formatOneNonRCRow(row) end
function p:getKey(row) end
function h.copyConstantsToWhen(row, when)
-- TODO: ditch the clone here somehow
-- this mw.clone could be a problem!!!!!!!!!
-- because of the Region object!!!!!!!!!!!!!
local row2 = mw.clone(row)
for k, _ in pairs(row2) do
row[k .. when] = row[k]
end
end
function p:getChangesByLine(changesData)
local index = {}
local changesByLine = {}
for _, row in ipairs(changesData) do
self:updatePlayerChangesAndIndex(changesByLine, row, index)
end
return changesByLine
end
function p:updatePlayerChangesAndIndex(changesByLine, row, fullIndex)
if not row.RCPage then
self:updateAncillaryInformation(changesByLine, row)
return
end
if not self:isOriginalNews(changesByLine, row, fullIndex[row.Key]) then
return
end
self:setEarlierRowNextTeamValues(changesByLine, row)
if not self:isAlreadyIndexed(fullIndex[row.Key], row) then
self:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex)
return
end
if self:doWeNeedANewLine(changesByLine, row, fullIndex[row.Key]) then
self:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex)
return
end
self:updatePlayerChangesForExistingLine(changesByLine, row, fullIndex[row.Key])
end
function p:updateAncillaryInformation(changesByLine, row) end
function p:isOriginalNews(changesByLine, row, index) end
function p:teamsAreIdentical(row, oldrow, when) end
function p:getOldRowFromIndex(changesByLine, row, info)
return changesByLine[info.changeNumber]
end
function p:isAlreadyIndexed(index, row)
return index
end
function p:doWeNeedANewLine(changesByLine, index) end
function p:updatePlayerChangesAndIndexNewEntry(changesByLine, row, fullIndex)
changesByLine[#changesByLine+1] = h.getNewChangeEntry(row)
row.changeIndex = #changesByLine
util_table.initTable(fullIndex, row.Key)
self:updateIndexNew(changesByLine, row, fullIndex[row.Key])
end
function p:updateIndexNew(changesByLine, row, index)
self:updateIndex(changesByLine, row, index)
end
function h.getNewChangeEntry(row)
-- we earlier split stuff into separate start/end so we should be fine to just use assignment here
-- can change this to a clone if we need to reuse data ever
return row
end
function p:updatePlayerChangesForExistingLine(changesByLine, row, index)
local oldIndex = self:getMostRecentLineNumberFromIndex(index)
self:updateExistingLineAtOldIndex(changesByLine, row, oldIndex)
self:updateIndexExisting(changesByLine, row, index)
end
function p:updateIndexExisting(changesByLine, row, index) end
function p:getMostRecentLineNumberFromIndex(index) end
function p:updateIndex(changesByLine, row, index) end
function p:updateExistingLineAtOldIndex(changesByLine, row, oldIndex)
self:addNewTeamToExistingLine(changesByLine[oldIndex], row)
self:moveExistingLine(changesByLine, oldIndex)
end
function p:addNewTeamToExistingLine(line, row)
-- we earlier split stuff into separate start/end so we should be fine to just merge now
util_table.merge(line, row)
line.RoleModifier = row.RoleModifier -- in case it's nil
end
function p:moveExistingLine(changesByLine, oldIndex) end
function p:setEarlierRowNextTeamValues(changesByLine, row) end
function p:markUnwantedLinesForDeletion(changesByLine, args)
for i, row in ipairs(changesByLine) do
if not self:isLineWanted(row, args) then
self.CHANGES_TO_REMOVE[#self.CHANGES_TO_REMOVE+1] = i
end
end
end
function p:isLineWanted(row, args)
return true
end
function p:removeLinesToDelete(changesByLine)
table.sort(self.CHANGES_TO_REMOVE)
for i = #self.CHANGES_TO_REMOVE, 1, -1 do
table.remove(changesByLine, self.CHANGES_TO_REMOVE[i])
end
end
function p:formatForOutput(changesByLine)
for i, row in ipairs(changesByLine) do
row.index = i
self:formatRowForOutput(row)
end
end
function p:formatRowForOutput(changesByLine) end
function p:storeCargo(changesByLine) end
function p:makeOutput(changesByLine) end
return p