diff --git a/lua/wikis/commons/Lpdb.lua b/lua/wikis/commons/Lpdb.lua index 24b1ad8d7fd..aa4ca1e309a 100644 --- a/lua/wikis/commons/Lpdb.lua +++ b/lua/wikis/commons/Lpdb.lua @@ -31,6 +31,14 @@ function Lpdb.isStorageDisabled() return Logic.readBool(Variables.varDefault('disable_LPDB_storage')) end +---@class LpdbQueryParameters +---@field conditions string? +---@field offset integer? +---@field limit integer? +---@field query string? +---@field groupby string? +---@field order string? + -- Executes a mass query. --[==[ Loops LPDB queries to e.g. @@ -67,7 +75,7 @@ example: ]==] ---@generic T ---@param tableName `T` ----@param queryParameters table +---@param queryParameters LpdbQueryParameters ---@param itemChecker fun(item: T): boolean? ---@param limit number? function Lpdb.executeMassQuery(tableName, queryParameters, itemChecker, limit) diff --git a/lua/wikis/commons/Mock/Lpdb.lua b/lua/wikis/commons/Mock/Lpdb.lua index 92f3bf8b953..3f0550cbc08 100644 --- a/lua/wikis/commons/Mock/Lpdb.lua +++ b/lua/wikis/commons/Mock/Lpdb.lua @@ -131,7 +131,7 @@ dbStructure.squadplayer = { ---- groupby ---@generic T:LpdbBaseData ---@param dbTable `T` ----@param parameters table +---@param parameters LpdbQueryParameters ---@return T[] function mockLpdb.lpdb(dbTable, parameters) local lpdbData = mockLpdb._getMockData(dbTable) diff --git a/lua/wikis/commons/Tournament.lua b/lua/wikis/commons/Tournament.lua index 6b0a382d344..c3a9e531823 100644 --- a/lua/wikis/commons/Tournament.lua +++ b/lua/wikis/commons/Tournament.lua @@ -41,32 +41,40 @@ local TOURNAMENT_PHASE = { ---@class StandardTournament: StandardTournamentPartial ---@field startDate {year: integer, month: integer?, day: integer?, timestamp: integer?}? ---@field endDate {year: integer, month: integer?, day: integer?, timestamp: integer?}? +---@field locations table ---@field region string? +---@field type string ---@field featured boolean ---@field status string? ---@field phase TournamentPhase ---@field tierOptions table +---@field prizepool number +---@field participantsNumber number ---@field extradata table +---@field organizers table ---@field isHighlighted fun(self: StandardTournament, options?: table): boolean ---@param conditions string|AbstractConditionNode? ---@param filterTournament? fun(tournament: StandardTournament): boolean +---@param queryProps LpdbQueryParameters? ---@return StandardTournament[] -function Tournament.getAllTournaments(conditions, filterTournament) +function Tournament.getAllTournaments(conditions, filterTournament, queryProps) local tournaments = {} + local limit = queryProps and Table.extract(queryProps, 'limit') or nil Lpdb.executeMassQuery( 'tournament', - { + Table.merge({ conditions = conditions and tostring(conditions), order = 'sortdate desc', limit = 1000, - }, + }, queryProps), function(record) local tournament = Tournament.tournamentFromRecord(record) if not filterTournament or filterTournament(tournament) then table.insert(tournaments, tournament) end - end + end, + limit ) return tournaments end @@ -134,13 +142,18 @@ function Tournament.tournamentFromRecord(record) liquipediaTier = Tier.toIdentifier(tier), liquipediaTierType = Tier.toIdentifier(tierType) --[[ @as string? ]], publisherTier = record.publishertier, + locations = record.locations, region = (record.locations or {}).region1, + type = record.type, status = record.status, icon = record.icon, iconDark = record.icondark, series = record.series, game = record.game, tierOptions = tierOptions, + prizepool = record.prizepool, + participantsNumber = record.participantsnumber, + organizers = record.organizers, extradata = extradata, } @@ -171,9 +184,15 @@ function Tournament.calculatePhase(tournament) return TOURNAMENT_PHASE.FINISHED end +---@class DateRecord +---@field year integer +---@field month integer? +---@field day integer? +---@field timestamp integer? + --- This function parses fuzzy dates into a structured format. ---@param dateRecord string? # date in the format of `YYYY-MM-DD`, with `-MM-DD` optional. ----@return {year: integer, month: integer?, day: integer?, timestamp: integer?}? +---@return DateRecord? function Tournament.parseDateRecord(dateRecord) if not dateRecord then return nil diff --git a/lua/wikis/commons/TournamentsListing/CardList.lua b/lua/wikis/commons/TournamentsListing/CardList.lua index 926951eb0f4..a87c10c98d6 100644 --- a/lua/wikis/commons/TournamentsListing/CardList.lua +++ b/lua/wikis/commons/TournamentsListing/CardList.lua @@ -21,6 +21,7 @@ local LeagueIcon = Lua.import('Module:LeagueIcon') local Region = Lua.import('Module:Region') local String = Lua.import('Module:StringUtils') local Table = Lua.import('Module:Table') +local Tournament = Lua.import('Module:Tournament') local Opponent = Lua.import('Module:Opponent/Custom') local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom') @@ -56,6 +57,7 @@ local DEFAULT_LIMIT = 5000 ---@field showRank boolean ---@field noLis boolean ---@field offset number +---@field limit number ---@field allowedPlacements string[] ---@field dynamicPlacements boolean ---@field onlyHighlightOnValue string? @@ -123,6 +125,7 @@ function BaseTournamentsListing:readConfig() showRank = Logic.readBool(Logic.nilOr(args.showRank)), noLis = Logic.readBool(args.noLis), offset = tonumber(args.offset) or 0, + limit = tonumber(args.limit) or DEFAULT_LIMIT, allowedPlacements = self:_allowedPlacements(), dynamicPlacements = Logic.readBool(args.dynamicPlacements), onlyHighlightOnValue = args.onlyHighlightOnValue, @@ -138,7 +141,7 @@ end ---@return self function BaseTournamentsListing:create() - local data = self.args.data or self:_query() + local data = self.args.data and Array.map(self.args.data, Tournament.tournamentFromRecord) or self:_query() if Table.isNotEmpty(data) then self.data = data end @@ -146,14 +149,11 @@ function BaseTournamentsListing:create() return self end ----@return table +---@return StandardTournament[] function BaseTournamentsListing:_query() - return mw.ext.LiquipediaDB.lpdb('tournament', { - conditions = self:buildConditions(), - query = 'pagename, name, icon, icondark, organizers, startdate, enddate, status, locations, series, ' - .. 'prizepool, participantsnumber, game, liquipediatier, liquipediatiertype, extradata, publishertier, type', + return Tournament.getAllTournaments(self:buildConditions(), nil, { order = self.args.order, - limit = self.args.limit or DEFAULT_LIMIT, + limit = self.config.limit, offset = self.config.offset, }) end @@ -248,12 +248,12 @@ function BaseTournamentsListing:_header() end ---@private ----@param tournamentData table +---@param tournamentData StandardTournament ---@return Widget function BaseTournamentsListing:_row(tournamentData) local config = self.config - local highlight = config.showHighlight and self:getHighlightClass(tournamentData) or nil + local highlight = config.showHighlight and tournamentData:isHighlighted(self.config) or nil local status = tournamentData.status and tournamentData.status:lower() if config.showRank then @@ -261,7 +261,7 @@ function BaseTournamentsListing:_row(tournamentData) end local prizeValue = tonumber(tournamentData.prizepool) or 0 - local participantNumber = tonumber(tournamentData.participantsnumber) or -1 + local participantNumber = tonumber(tournamentData.participantsNumber) or -1 local placements = self:_fetchPlacementData(tournamentData) @@ -277,13 +277,13 @@ function BaseTournamentsListing:_row(tournamentData) } or nil, TableWidgets.Cell{ attributes = { - ['data-sort-value'] = tournamentData.name + ['data-sort-value'] = tournamentData.fullName }, children = LeagueIcon.display{ icon = tournamentData.icon, - iconDark = tournamentData.icondark, - link = tournamentData.parent, - name = tournamentData.name, + iconDark = tournamentData.iconDark, + link = tournamentData.pageName, + name = tournamentData.fullName, options = {noTemplate = true}, } }, @@ -292,11 +292,11 @@ function BaseTournamentsListing:_row(tournamentData) ['text-decoration'] = status == CANCELLED and 'line-through' or nil, }, attributes = { - ['data-sort-value'] = tournamentData.name, + ['data-sort-value'] = tournamentData.fullName, }, children = LinkWidget{ - children = tournamentData.name, - link = tournamentData.pagename, + children = tournamentData.fullName, + link = tournamentData.pageName, } }, config.showOrganizer @@ -309,7 +309,7 @@ function BaseTournamentsListing:_row(tournamentData) css = { ['font-style'] = (status == POSTPONED or status == DELAYED) and 'italic' or nil, }, - children = BaseTournamentsListing._dateDisplay(tournamentData.startdate, tournamentData.enddate, status) + children = BaseTournamentsListing._dateDisplay(tournamentData.startDate, tournamentData.endDate, status) }, TableWidgets.Cell{ children = prizeValue > 0 @@ -378,7 +378,7 @@ function BaseTournamentsListing:_calculateRank(prize) end ---@private ----@param tournamentData table +---@param tournamentData StandardTournament ---@return string[] function BaseTournamentsListing._organizerDisplay(tournamentData) local organizers = Logic.emptyOr(tournamentData.organizers) or {} @@ -446,8 +446,8 @@ function BaseTournamentsListing._displayLocation(locationData, locationIndex) end ---@private ----@param startDate string ----@param endDate string +---@param startDate DateRecord +---@param endDate DateRecord ---@param status string? ---@return Widget|string function BaseTournamentsListing._dateDisplay(startDate, endDate, status) @@ -459,7 +459,7 @@ function BaseTournamentsListing._dateDisplay(startDate, endDate, status) end ---@private ----@param tournamentData table +---@param tournamentData StandardTournament ---@return {qualified: table[]?, [1]: table[]?, [2]: table[]?} function BaseTournamentsListing:_fetchPlacementData(tournamentData) local placements = {} @@ -501,7 +501,7 @@ function BaseTournamentsListing:_fetchPlacementData(tournamentData) local opponent = Opponent.fromLpdbStruct(item) if not opponent then - mw.logObject({pageName = tournamentData.pagename, place = item.placement}, 'Invalid Prize Pool Data returned from') + mw.logObject({pageName = tournamentData.pageName, place = item.placement}, 'Invalid Prize Pool Data returned from') elseif Opponent.isTbd(opponent) then opponent = Opponent.tbd(Opponent.team) end @@ -531,18 +531,10 @@ function BaseTournamentsListing.participantsNumber(number) return LANG:formatNum(number) end --- overwritable in case wikis want several highlight options ----@protected ----@param tournamentData table ----@return boolean -function BaseTournamentsListing:getHighlightClass(tournamentData) - return HighlightConditions.tournament(tournamentData, self.config) -end - ----@param tournamentData table +---@param tournamentData StandardTournament ---@return string? function BaseTournamentsListing:displayTier(tournamentData) - local tier, tierType, options = Tier.parseFromQueryData(tournamentData) + local options = tournamentData.tierOptions options.link = true if self.config.onlyTierTypeIfBoth then options.onlyTierTypeIfBoth = true @@ -550,7 +542,7 @@ function BaseTournamentsListing:displayTier(tournamentData) options.tierTypeShort = true end - return Tier.display(tier, tierType, options) + return Tier.display(tournamentData.liquipediaTier, tournamentData.liquipediaTierType, options) end return BaseTournamentsListing diff --git a/lua/wikis/commons/TournamentsListing/Conditions.lua b/lua/wikis/commons/TournamentsListing/Conditions.lua index 6c2b057f246..2490f0357e2 100644 --- a/lua/wikis/commons/TournamentsListing/Conditions.lua +++ b/lua/wikis/commons/TournamentsListing/Conditions.lua @@ -147,15 +147,15 @@ function TournamentsListingConditions.base(args) return conditions end ----@param tournamentData table +---@param tournamentData StandardTournament ---@param config table ---@return string function TournamentsListingConditions.placeConditions(tournamentData, config) local conditions = ConditionTree(BooleanOperator.all) :add{ - ConditionNode(ColumnName('liquipediatier'), Comparator.eq, tournamentData.liquipediatier), - ConditionNode(ColumnName('liquipediatiertype'), Comparator.eq, tournamentData.liquipediatiertype), - ConditionNode(ColumnName(config.useParent and 'parent' or 'pagename'), Comparator.eq, tournamentData.pagename), + ConditionNode(ColumnName('liquipediatier'), Comparator.eq, tournamentData.liquipediaTier), + ConditionNode(ColumnName('liquipediatiertype'), Comparator.eq, tournamentData.liquipediaTierType or ''), + ConditionNode(ColumnName(config.useParent and 'parent' or 'pagename'), Comparator.eq, tournamentData.pageName), ConditionNode(ColumnName('placement'), Comparator.neq, '') }