Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: save/load standings via wiki-vars in addition to lpdb #5342

Merged
merged 4 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 40 additions & 17 deletions components/standings/commons/standings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
local Array = require('Module:Array')
local Condition = require('Module:Condition')
local FnUtil = require('Module:FnUtil')
local Json = require('Module:Json')
local Lpdb = require('Module:Lpdb')
local Lua = require('Module:Lua')
local Operator = require('Module:Operator')
local Table = require('Module:Table')
local Variables = require('Module:Variables')

local MatchGroupUtil = Lua.import('Module:MatchGroup/Util')
local Tournament = Lua.import('Module:Tournament')
Expand All @@ -32,7 +34,8 @@ local Standings = {}
---@field matches MatchGroupUtilMatch[]
---@field config table
---@field rounds StandingsRound[]
---@field private lpdbdata standingstable
---@field private record standingstable
---@field private entryRecords standingsentry[]

---@class StandingsRound
---@field round integer
Expand All @@ -51,11 +54,22 @@ local Standings = {}
---@field positionChangeFromPreviousRound integer
---@field pointsChangeFromPreviousRound number

---Fetches a standings table from a page. Tries to read from page variables before fetching from LPDB.
---@param pagename string
---@param standingsIndex integer #0-index'd on per page
---@return StandingsModel?
function Standings.getStandingsTable(pagename, standingsIndex)
local pageNameInCorrectFormat = string.gsub(pagename, ' ', '_')
local myPageName = string.gsub(mw.title.getCurrentTitle().text , ' ', '_')

if pageNameInCorrectFormat == myPageName then
local varData = Variables.varDefault('standings2_' .. standingsIndex)
if varData then
local standings = Json.parseStringified(varData)
return Standings.standingsFromRecord(standings.standings, standings.entries)
end
end

local record = mw.ext.LiquipediaDB.lpdb('standingstable', {
conditions = '[[pagename::' .. pageNameInCorrectFormat .. ']] AND [[standingsindex::' .. standingsIndex .. ']]',
limit = 1,
Expand All @@ -70,29 +84,30 @@ local StandingsMT = {
__index = function(standings, property)
if property == 'tournament' then
standings[property] = Tournament.getTournament(standings.pageName)
end
if property == 'matches' then
elseif property == 'matches' then
standings[property] = Standings.fetchMatches(standings)
end
if property == 'rounds' then
elseif property == 'rounds' then
standings[property] = Standings.makeRounds(standings)
elseif property == 'entryRecords' then
standings[property] = Standings.fetchEntries(standings)
end
return rawget(standings, property)
end
}

---@param record standingstable
---@param entries standingsentry[]?
---@return StandingsModel
function Standings.standingsFromRecord(record)
function Standings.standingsFromRecord(record, entries)
local standings = {
pageName = record.pagename,
standingsIndex = record.standingsindex,
title = record.title,
section = record.section,
type = record.type,
config = record.config,
rounds = record.rounds,
lpdbdata = record,
record = record,
entryRecords = entries,
}

-- Some properties are derived from other properies and we can calculate them when accessed.
Expand Down Expand Up @@ -122,7 +137,7 @@ end
---@return MatchGroupUtilMatch[]
function Standings.fetchMatches(standings)
---@diagnostic disable-next-line: invisible
local matchids = standings.lpdbdata.matches
local matchids = standings.record.matches or {}
local bracketIds = Array.unique(Array.map(matchids, function(matchid)
return MatchGroupUtil.splitMatchId(matchid)
end))
Expand All @@ -134,15 +149,13 @@ function Standings.fetchMatches(standings)
end

---@param standings StandingsModel
---@return StandingsRound[]
function Standings.makeRounds(standings)
---@diagnostic disable-next-line: invisible
local lpdbdata = standings.lpdbdata
---@return standingsentry[]
function Standings.fetchEntries(standings)
local standingsEntries = {}
local conditions = Condition.Tree(Condition.BooleanOperator.all)
:add(Condition.Node(Condition.ColumnName('pagename'), Condition.Comparator.eq, standings.pageName))
:add(Condition.Node(Condition.ColumnName('standingsindex'), Condition.Comparator.eq, standings.standingsIndex))

local standingsEntries = {}
Lpdb.executeMassQuery(
'standingsentry',
{
Expand All @@ -153,6 +166,16 @@ function Standings.makeRounds(standings)
table.insert(standingsEntries, record)
end
)
return standingsEntries
end

---@param standings StandingsModel
---@return StandingsRound[]
function Standings.makeRounds(standings)
---@diagnostic disable-next-line: invisible
local record = standings.record
---@diagnostic disable-next-line: invisible
local standingsEntries = standings.entryRecords

local roundCount = Array.maxBy(Array.map(standingsEntries, Operator.property('roundindex')), FnUtil.identity)

Expand All @@ -164,9 +187,9 @@ function Standings.makeRounds(standings)
return {
round = roundIndex,
opponents = opponents,
finished = (lpdbdata.extradata.rounds[roundIndex] or {}).finished or false,
started = (lpdbdata.extradata.rounds[roundIndex] or {}).started or false,
title = (lpdbdata.extradata.rounds[roundIndex] or {}).title or ('Round ' .. roundIndex),
finished = (record.extradata.rounds[roundIndex] or {}).finished or false,
started = (record.extradata.rounds[roundIndex] or {}).started or false,
title = (record.extradata.rounds[roundIndex] or {}).title or ('Round ' .. roundIndex),
}
end)
end
Expand Down
103 changes: 69 additions & 34 deletions components/standings/commons/standings_storage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,16 @@ function StandingsStorage.run(data)
Array.map(data.entries, function (entry) return tonumber (entry.roundindex) end),
math.max)

StandingsStorage.table(data)

Array.forEach(data.entries, function (entry)
StandingsStorage.entry(entry, data.standingsindex)
local entries = Array.map(data.entries, function (entry)
return StandingsStorage.entry(entry, data.standingsindex)
end)

StandingsStorage.save(StandingsStorage.table(data), entries)
end

---@param data table
---@return table
function StandingsStorage.table(data)
if not StandingsStorage.shouldStore() then
return
end

local title = data.title or ''
local cleanedTitle = title:gsub('<.->.-</.->', '')

Expand All @@ -70,28 +67,23 @@ function StandingsStorage.table(data)
haspoints = data.haspoints,
}

mw.ext.LiquipediaDB.lpdb_standingstable('standingsTable_' .. data.standingsindex,
{
tournament = Variables.varDefault('tournament_name', ''),
parent = Variables.varDefault('tournament_parent', ''),
standingsindex = standingsIndex,
title = mw.text.trim(cleanedTitle),
section = Variables.varDefault('last_heading', ''):gsub('<.->', ''),
type = data.type,
matches = Json.stringify(data.matches or {}, {asArray = true}),
config = mw.ext.LiquipediaDB.lpdb_create_json(config),
extradata = mw.ext.LiquipediaDB.lpdb_create_json(Table.merge(extradata, data.extradata)),
}
)
return {
tournament = Variables.varDefault('tournament_name', ''),
parent = Variables.varDefault('tournament_parent', ''),
standingsindex = standingsIndex,
title = mw.text.trim(cleanedTitle),
section = Variables.varDefault('last_heading', ''):gsub('<.->', ''),
type = data.type,
matches = Json.stringify(data.matches or {}, {asArray = true}),
config = config,
extradata = Table.merge(extradata, data.extradata),
}
end

---@param entry table
---@param standingsIndex number
---@return table?
function StandingsStorage.entry(entry, standingsIndex)
if not StandingsStorage.shouldStore() then
return
end

local roundIndex = tonumber(entry.roundindex)
local slotIndex = tonumber(entry.slotindex)
local standingsIndexNumber = tonumber(standingsIndex)
Expand All @@ -114,7 +106,7 @@ function StandingsStorage.entry(entry, standingsIndex)
definitestatus = entry.definitestatus or entry.bg,
currentstatus = entry.currentstatus or entry.pbg,
placementchange = entry.placementchange or entry.change,
scoreboard = mw.ext.LiquipediaDB.lpdb_create_json{
scoreboard = {
match = StandingsStorage.toScoreBoardEntry(entry.match),
overtime = StandingsStorage.toScoreBoardEntry(entry.overtime),
game = StandingsStorage.toScoreBoardEntry(entry.game),
Expand All @@ -124,19 +116,62 @@ function StandingsStorage.entry(entry, standingsIndex)
},
roundindex = roundIndex,
slotindex = slotIndex,
extradata = mw.ext.LiquipediaDB.lpdb_create_json(Table.merge(extradata, entry.extradata)),
extradata = Table.merge(extradata, entry.extradata),
}

lpdbEntry.currentstatus = lpdbEntry.currentstatus or lpdbEntry.definitestatus

mw.ext.LiquipediaDB.lpdb_standingsentry(
'standing_' .. standingsIndexNumber .. '_' .. roundIndex .. '_' .. slotIndex,
Table.merge(lpdbEntry, Opponent.toLpdbStruct(entry.opponent))
)
return Table.merge(lpdbEntry, Opponent.toLpdbStruct(entry.opponent))
end

---@param standingsTable table?
---@param standingsEntries table[]?
function StandingsStorage.save(standingsTable, standingsEntries)
if StandingsStorage.shouldStoreLpdb() then
if standingsTable then
mw.ext.LiquipediaDB.lpdb_standingstable(
'standingsTable_' .. standingsTable.standingsindex,
Json.stringifySubTables(standingsTable)
)
end

Array.forEach(standingsEntries or {}, function(entry)
mw.ext.LiquipediaDB.lpdb_standingsentry(
'standing_' .. entry.standingsindex .. '_' .. entry.roundindex .. '_' .. entry.slotindex,
Json.stringifySubTables(entry)
)
end)
end

if standingsTable then
-- We have a full standings here for storage, very simple
-- Entries may be supplied later
local wikiVariable = 'standings2_' .. standingsTable.standingsindex
Variables.varDefine(wikiVariable, Json.stringify({
standings = standingsTable,
entries = standingsEntries or {},
}))
elseif standingsEntries and standingsEntries[1] then
-- Entry that was supplied later on
local wikiVariable = 'standings2_' .. standingsEntries[1].standingsindex
local standings = Json.parseIfString(Variables.varDefault(wikiVariable))
if not standings then
mw.log('Could not store standings entry in wiki variables, unable to locate the standings table')
return
end
if not standings.entries then
mw.log('Could not store standings entry in wiki variables, invalid format')
return
end
for _, entry in ipairs(standingsEntries) do
table.insert(standings.entries, entry)
end
Variables.varDefine(wikiVariable, Json.stringify(standings))
end
end

---@return boolean
function StandingsStorage.shouldStore()
function StandingsStorage.shouldStoreLpdb()
return Namespace.isMain() and not Logic.readBool(Variables.varDefault('disable_LPDB_storage'))
end

Expand Down Expand Up @@ -172,7 +207,7 @@ function StandingsStorage.fromTemplateHeader(frame)
data.roundcount = tonumber(data.roundcount) or 1
data.finished = Logic.readBool(data.finished)

StandingsStorage.table(data)
StandingsStorage.save(StandingsStorage.table(data))
end

---@param frame table
Expand Down Expand Up @@ -256,7 +291,7 @@ function StandingsStorage.fromTemplateEntry(frame)

data.match = {w = data.win_m, d = data.tie_m, l = data.lose_m}
data.game = {w = data.win_g, d = data.tie_g, l = data.lose_g}
StandingsStorage.entry(data, data.standingsindex)
StandingsStorage.save(nil, {StandingsStorage.entry(data, data.standingsindex)})
end

-- Legacy input method
Expand Down
Loading