From 6b3fd8f20b8c0efb8283414abea0a74d5efa8424 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Fri, 17 Jan 2025 16:11:27 +0200 Subject: [PATCH 1/4] feat: save/load standings via wiki-vars in addition to lpdb --- components/standings/commons/standings.lua | 53 ++++++--- .../standings/commons/standings_storage.lua | 103 ++++++++++++------ 2 files changed, 105 insertions(+), 51 deletions(-) diff --git a/components/standings/commons/standings.lua b/components/standings/commons/standings.lua index 0e0b7bbe1b0..dcfbc54aaa0 100644 --- a/components/standings/commons/standings.lua +++ b/components/standings/commons/standings.lua @@ -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') @@ -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 @@ -51,10 +54,17 @@ local Standings = {} ---@field positionChangeFromPreviousRound integer ---@field pointsChangeFromPreviousRound number +---Fetches a standng 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 varData = Variables.varDefault('standings2_' .. standingsIndex) + if varData then + local standings = Json.parseStringified(varData) + return Standings.standingsFromRecord(standings.standings, standings.entries) + end + local pageNameInCorrectFormat = string.gsub(pagename, ' ', '_') local record = mw.ext.LiquipediaDB.lpdb('standingstable', { conditions = '[[pagename::' .. pageNameInCorrectFormat .. ']] AND [[standingsindex::' .. standingsIndex .. ']]', @@ -70,20 +80,21 @@ 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, @@ -91,8 +102,8 @@ function Standings.standingsFromRecord(record) 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. @@ -122,7 +133,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)) @@ -134,15 +145,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', { @@ -153,6 +162,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) @@ -164,9 +183,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 true, + started = (record.extradata.rounds[roundIndex] or {}).started or true, + title = (record.extradata.rounds[roundIndex] or {}).title or ('Round ' .. roundIndex), } end) end diff --git a/components/standings/commons/standings_storage.lua b/components/standings/commons/standings_storage.lua index 65bfaec7aa0..494c75b1fd9 100644 --- a/components/standings/commons/standings_storage.lua +++ b/components/standings/commons/standings_storage.lua @@ -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('<.->.-', '') @@ -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) @@ -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), @@ -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 @@ -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 @@ -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 From e797e95768a669ab444ca910e7fd25b8091ef5f5 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Fri, 17 Jan 2025 16:17:11 +0200 Subject: [PATCH 2/4] add extra check for pagename correctness --- components/standings/commons/standings.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/components/standings/commons/standings.lua b/components/standings/commons/standings.lua index dcfbc54aaa0..c53a6cc082b 100644 --- a/components/standings/commons/standings.lua +++ b/components/standings/commons/standings.lua @@ -59,13 +59,17 @@ local Standings = {} ---@param standingsIndex integer #0-index'd on per page ---@return StandingsModel? function Standings.getStandingsTable(pagename, standingsIndex) - local varData = Variables.varDefault('standings2_' .. standingsIndex) - if varData then - local standings = Json.parseStringified(varData) - return Standings.standingsFromRecord(standings.standings, standings.entries) + 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 pageNameInCorrectFormat = string.gsub(pagename, ' ', '_') local record = mw.ext.LiquipediaDB.lpdb('standingstable', { conditions = '[[pagename::' .. pageNameInCorrectFormat .. ']] AND [[standingsindex::' .. standingsIndex .. ']]', limit = 1, From 31af63d935450e1413caac76d53536a63f9b4321 Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Fri, 17 Jan 2025 16:27:45 +0200 Subject: [PATCH 3/4] change default value back --- components/standings/commons/standings.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/standings/commons/standings.lua b/components/standings/commons/standings.lua index c53a6cc082b..e98e9900d67 100644 --- a/components/standings/commons/standings.lua +++ b/components/standings/commons/standings.lua @@ -187,8 +187,8 @@ function Standings.makeRounds(standings) return { round = roundIndex, opponents = opponents, - finished = (record.extradata.rounds[roundIndex] or {}).finished or true, - started = (record.extradata.rounds[roundIndex] or {}).started or true, + 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) From 19d0a0b806079e65f6afbad15df9c74e5139b5ab Mon Sep 17 00:00:00 2001 From: Rikard Blixt Date: Fri, 17 Jan 2025 15:34:29 +0100 Subject: [PATCH 4/4] Update components/standings/commons/standings.lua Co-authored-by: hjpalpha <75081997+hjpalpha@users.noreply.github.com> --- components/standings/commons/standings.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/standings/commons/standings.lua b/components/standings/commons/standings.lua index e98e9900d67..541e0db7351 100644 --- a/components/standings/commons/standings.lua +++ b/components/standings/commons/standings.lua @@ -54,7 +54,7 @@ local Standings = {} ---@field positionChangeFromPreviousRound integer ---@field pointsChangeFromPreviousRound number ----Fetches a standng table from a page. Tries to read from page variables before fetching from LPDB. +---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?