Skip to content
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
219 changes: 93 additions & 126 deletions lua/wikis/commons/ExternalMediaList.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@ local Lua = require('Module:Lua')
local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local Logic = Lua.import('Module:Logic')
local PlayerExt = Lua.import('Module:Player/Ext/Custom')
local String = Lua.import('Module:StringUtils')
local Table = Lua.import('Module:Table')
local Tabs = Lua.import('Module:Tabs')

local OpponentDisplay = Lua.import('Module:OpponentDisplay/Custom')
local ExternalMediaLinkDisplay = Lua.import('Module:Widget/ExternalMedia/Link')
local Condition = Lua.import('Module:Condition')
local ConditionTree = Condition.Tree
local ConditionNode = Condition.Node
local Comparator = Condition.Comparator
local BooleanOperator = Condition.BooleanOperator
local ColumnName = Condition.ColumnName
local ConditionUtil = Condition.Util

local MediaList = {}
local ExternalMediaListDisplay = Lua.import('Module:Widget/ExternalMedia/List')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Link = Lua.import('Module:Widget/Basic/Link')
local WidgetUtil = Lua.import('Module:Widget/Util')

local NON_BREAKING_SPACE = ' '
local MediaList = {}

---Main function for ExternalMediaList.
---Queries External Media Links for the given conditions (via arguments).
Expand All @@ -31,27 +37,28 @@ function MediaList.get(args)
args = MediaList._parseArgs(args)

local data = mw.ext.LiquipediaDB.lpdb('externalmedialink', {
conditions = MediaList._buildConditions(args),
conditions = tostring(MediaList._buildConditions(args)),
order = 'date desc',
limit = args.limit
})

--if we do not get any results from the query return empty string
--if we do not get any results from the query return empty
if type(data[1]) ~= 'table' then return end

if args.separateByYears and args.dynamic and not args.year then
return mw.html.create()
:node(MediaList._displayDynamic(data, args))
:node(MediaList._formLink(args.linkToForm))
elseif args.separateByYears and not args.year then
return mw.html.create()
:node(MediaList._displayByYear(data, args))
:node(MediaList._formLink(args.linkToForm))
---@return string|Widget|Widget[]|Html?
local function createDisplay()
if args.separateByYears and args.dynamic and not args.year then
return MediaList._displayDynamic(data, args)
elseif args.separateByYears and not args.year then
return MediaList._displayByYear(data, args)
end
return MediaList._displayYear(data, args)
end

return mw.html.create()
:node(MediaList._displayYear(data, args))
:node(MediaList._formLink(args.linkToForm))
return HtmlWidgets.Fragment{children = WidgetUtil.collect(
createDisplay(),
MediaList._formLink(args.linkToForm)
)}
end

---Parses the arguments for further usage in this module.
Expand All @@ -69,7 +76,7 @@ function MediaList._parseArgs(args)
end)

return {
types = args.type and Array.map(Array.map(mw.text.split(args.type, ','), String.trim), string.lower) or nil,
types = args.type and Array.map(Array.parseCommaSeparatedString(args.type), string.lower) or nil,
author = args.author and mw.ext.TeamLiquidIntegration.resolve_redirect(args.author) or nil,
subjects = subjects,
org = args.organization and mw.ext.TeamLiquidIntegration.resolve_redirect(args.organization) or nil,
Expand All @@ -79,7 +86,7 @@ function MediaList._parseArgs(args)
separateByYears = Logic.readBool(args.seperate_years or args.separate_years),
dynamic = Logic.emptyOr(Logic.readBoolOrNil(args.dynamic), true),
linkToForm = Logic.readBool(args.linkToForm),
booleanOperator = Logic.readBool(args['and']) and ' AND ' or ' OR ',
booleanOperator = Logic.readBool(args['and']) and BooleanOperator.all or BooleanOperator.any,
isEventPage = Logic.readBool(args.event),
event = Logic.readBool(args.event)
and mw.title.getCurrentTitle().prefixedText
Expand All @@ -91,75 +98,64 @@ end

---Builds the query conditions for the given arguments
---@param args table
---@return string
---@return ConditionTree
function MediaList._buildConditions(args)
local conditions = {
'[[namespace::136]]'
}
local conditions = ConditionTree(BooleanOperator.all):add(
ConditionNode(ColumnName('namespace'), Comparator.eq, 136)
)

if Table.isNotEmpty(args.types) then
table.insert(conditions, '(' .. table.concat(Array.map(args.types, function(typeValue)
return '[[type::' .. typeValue .. ']]'
end), ' OR ' ) .. ')')
conditions:add(ConditionUtil.anyOf(ColumnName('type'), args.types))
end

if args.year then
table.insert(conditions, '[[date_year::' .. args.year.. ']]')
conditions:add(ConditionNode(ColumnName('year', 'date'), Comparator.eq, args.year))
end

local additionalConditions = {}
for _, subject in pairs(args.subjects) do
table.insert(additionalConditions, MediaList._buildMultiKeyCondition(subject, 'extradata_subject', 20))
end
local additionalConditions = ConditionTree(args.booleanOperator)

additionalConditions:add(Array.map(args.subjects, function (subject)
return MediaList._buildMultiKeyCondition(subject, 'extradata_subject', 20)
end))

if args.org then
table.insert(
additionalConditions,
'([[extradata_subject_organization::'
.. args.org
.. ']] OR [[extradata_subject_organization::'
.. args.org:gsub(' ', '_')
.. ']])'
)
table.insert(additionalConditions, MediaList._buildMultiKeyCondition(args.org, 'extradata_subject_organization', 5))
additionalConditions:add{
ConditionUtil.anyOf(ColumnName('extradata_subject_organization'), {args.org, args.org:gsub(' ', '_')}),
MediaList._buildMultiKeyCondition(args.org, 'extradata_subject_organization', 5)
}
end

if args.author then
table.insert(additionalConditions, MediaList._buildMultiKeyCondition(args.author, 'authors_author', 5))
end
additionalConditions:add(MediaList._buildMultiKeyCondition(args.author, 'authors_author', 5))

if args.event then
table.insert(
additionalConditions,
'([[extradata_event_link::'
.. args.event
.. ']] OR [[extradata_event_link::'
.. args.event:gsub(' ', '_')
.. ']])'
additionalConditions:add(
ConditionUtil.anyOf(ColumnName('extradata_event_link'), {args.event, args.event:gsub(' ', '_')})
)
end

if Logic.isNotEmpty(additionalConditions) then
table.insert(conditions, '(' .. table.concat(additionalConditions, args.booleanOperator) .. ')')
end
conditions:add(additionalConditions)

return table.concat(conditions, ' AND ')
return conditions
end

---Builds a multi key condition for a given prefix and value
---@param value string|number
---@param prefix string
---@param limit integer
---@return string
---@return ConditionTree?
function MediaList._buildMultiKeyCondition(value, prefix, limit)
return table.concat(Array.map(Array.range(1, limit), function(index)
return '([[' .. prefix .. index .. '::' .. value .. ']]'
.. ' OR [['.. prefix .. index .. '::' .. value:gsub(' ', '_') .. ']])'
end), ' OR ')
if Logic.isEmpty(value) then
return
end
return ConditionTree(BooleanOperator.any):add(
Array.map(Array.range(1, limit), function (index)
return ConditionUtil.anyOf(ColumnName(prefix .. index), {value, value:gsub(' ', '_')})
end)
)
end

---Builds the display for the dynamic tabs per year option
---@param data table[]
---@param data externalmedialink[]
---@param args table
---@return Html|string?
function MediaList._displayDynamic(data, args)
Expand All @@ -168,7 +164,7 @@ function MediaList._displayDynamic(data, args)
local tabIndex = 1
for year, yearItems in Table.iter.spairs(MediaList._groupByYear(data), MediaList._sortInYear) do
tabsData['name' .. tabIndex] = year
tabsData['content' .. tabIndex] = tostring(MediaList._displayYear(yearItems, args))
tabsData['content' .. tabIndex] = MediaList._displayYear(yearItems, args)

tabIndex = tabIndex + 1
end
Expand All @@ -177,24 +173,22 @@ function MediaList._displayDynamic(data, args)
end

---Builds the display for the per year option (without tabs)
---@param data table[]
---@param data externalmedialink[]
---@param args table
---@return Html
---@return Widget[]
function MediaList._displayByYear(data, args)
local display = mw.html.create()
local display = {}

for year, yearItems in Table.iter.spairs(MediaList._groupByYear(data), MediaList._sortInYear) do
display
:wikitext('\n====' .. year .. '====\n')
:node(MediaList._displayYear(yearItems, args))
Array.appendWith(display, HtmlWidgets.H4{children = year}, MediaList._displayYear(yearItems, args))
end

return display
end

---Groups provided data by year
---@param data table[]
---@return table[][]
---@param data externalmedialink[]
---@return table<string, externalmedialink[]>
function MediaList._groupByYear(data)
local _, groupedData = Array.groupBy(data, function(item)
return item.date:sub(1, 4)
Expand All @@ -204,7 +198,7 @@ function MediaList._groupByYear(data)
end

---Sort function to sort External Media Links within a year
---@param _ table?
---@param _ string[]?
---@param key1 string
---@param key2 string
---@return boolean
Expand All @@ -213,69 +207,42 @@ function MediaList._sortInYear(_, key1, key2)
end

---Displays the External Media Links for a given data set (usually of a year)
---@param data table[]
---@param data externalmedialink[]
---@param args table
---@return Html
---@return Widget
function MediaList._displayYear(data, args)
local yearDisplay = mw.html.create('ul')

for _, item in ipairs(data) do
yearDisplay:node(MediaList._row(item, args))
end

return yearDisplay
end

---Displays a single External Media Link
---@param item externalmedialink
---@param args table
---@return Html
function MediaList._row(item, args)
local row = mw.html.create('li')
:node(MediaList._editButton(item.pagename))
:node(args.showSubjectTeam and MediaList._displayTeam(args.subjects[1], item.date) or '')
:node(ExternalMediaLinkDisplay{data = item, showUsUk = args.showUsUk})

return row
end

---Display for the edit button in front of External Medial Link rows
---@param page string
---@return string
function MediaList._editButton(page)
return mw.text.nowiki('[') .. '[[Data:' .. page .. '|e]]' .. mw.text.nowiki(']') .. NON_BREAKING_SPACE
end

---Displays the subject's team for a given External Media Link
---@param subject string
---@param date string
---@return Widget?
function MediaList._displayTeam(subject, date)
local _, team = PlayerExt.syncTeam(subject, nil, {date = date})
if not team then
return
end
return OpponentDisplay.InlineTeamContainer{template = team, date = date, style = 'icon'}
return ExternalMediaListDisplay{
data = data,
subject = args.subjects[1],
showSubjectTeam = args.showSubjectTeam,
showUsUk = args.showUsUk,
}
end

---Displays the link to the Form with which External Media Links are to be created.
---@param show boolean defines if the link is to be displayed or not
---@return Html?
---@return Widget?
function MediaList._formLink(show)
if not show then return end

return mw.html.create('div')
:css('display', 'block')
:css('text-align', 'center')
:css('padding', '0.5em')
:node(mw.html.create('div')
:css('display', 'inline')
:css('white-space', 'nowrap')
:wikitext(mw.text.nowiki('[')
.. '[[Special:FormEdit/ExternalMediaLinks|Add an external media link]]'
.. mw.text.nowiki(']')
)
)
return HtmlWidgets.Div{
css = {
display = 'block',
['text-align'] = 'center',
padding = '0.5em',
},
children = HtmlWidgets.Div{
css = {
display = 'inline',
['white-space'] = 'nowrap',
},
children = {
mw.text.nowiki('['),
Link{link = 'Special:FormEdit/ExternalMediaLinks', children = 'Add an external media link'},
mw.text.nowiki(']'),
}
}
}
end

return Class.export(MediaList, {exports = {'get'}})
Loading
Loading