Module:MusicTable
Module documentation
This documentation is transcluded from Template:No documentation/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:MusicTable/doc. [edit]
Module:MusicTable's function main is invoked by Template:MusicTable.
Module:MusicTable requires Module:Array.
Module:MusicTable requires Module:PageListTools.
Module:MusicTable requires Module:Paramtest.
Module:MusicTable requires Module:Yesno.
local p = {}
local contains = require('Module:Array').contains
local pagesWithCats = require('Module:PageListTools').pageswithcats
local paramTest = require('Module:Paramtest')
local yesNo = require('Module:Yesno')
local html = mw.html
local ask = mw.smw.ask
local log = mw.log
function buildRow(trackData, hints, members)
local exclusivity = trackData.exclusive and '\'\'\'' or ''
local event = trackData.event and '\'\''or ''
local trackLink, _ = string.gsub(trackData.file, '%|[^%]]+%]', '|Play track]') -- Replace visual override on link
local row = html.create('tr'):attr({ ['id'] = removeStringArticles(trackData.name), ['data-music-track-name'] = trackData.name })
row:tag('td'):wikitext(event .. exclusivity .. '[[' .. trackData.name .. ']]' .. exclusivity .. event):done()
if(hints) then
row:tag('td'):wikitext(trackData.hint):done()
end
if(members == nil)then
row:tag('td'):wikitext(yesNo(trackData.members) and '[[File:Member icon.png|link=|Members]]' or '[[File:Free-to-play icon.png|link=|Free-to-play]]'):done()
end
row:tag('td'):wikitext(trackData.duration):done()
:tag('td'):wikitext(trackLink):done()
return row
end
function createHeader(hints, members)
local tabl = html.create('table'):addClass('wikitable sortable lighttable embed-audio-links qc-active music-tracks sticky-header')
local row = tabl:tag('tr')
row:tag('th'):wikitext('Name'):done()
if(hints) then
row:tag('th'):wikitext('Unlock hint'):done()
end
if(members == nil) then
if(hints) then
tabl:addClass(' align-center-3')
else
tabl:addClass(' align-center-2')
end
row:tag('th'):wikitext('Members'):done()
end
row:tag('th'):wikitext('Duration'):done()
:tag('th'):addClass('unsortable'):wikitext('Music track'):done()
return tabl
end
function addCategoryToData(data, cat, key)
local pagesWithCat = pagesWithCats({ cat })
for _, page in ipairs(data) do
if(contains(pagesWithCat, page[1])) then
page[key] = true
else
page[key] = false
end
end
return data
end
-- Removes leading articles for sort function
-- Sorts alphabetically after stripping any `A `, `An `, or `The ` and appending it to the end
-- Also removies "illegal" characters
function removeStringArticles(str)
if(string.find(str, '^A ')) then
str = string.sub(str, 3)
str = str .. ', A'
elseif(string.find(str, '^The ')) then
str = string.sub(str, 5)
str = str .. ', The'
elseif(string.find(str, '^An ')) then
str = string.sub(str, 4)
str = str .. ', An'
end
string.gsub(str, '!', '')
string.gsub(str, '\'', '')
return str
end
function tableConcat(mainTable, newTable)
for i = 1, #newTable, 1 do
mainTable[#mainTable+1] = newTable[i]
end
return mainTable
end
function filterData(data)
local pagesToExclude = pagesWithCats({ '[[Category:Unlisted music tracks]]' })
local retData = {}
for _, page in ipairs(data) do
if(not contains(pagesToExclude, page[1])) then
table.insert(retData, page)
end
end
return retData
end
function loadData(limit, batchSize, hints, members)
local allData = {}
local query = {
'[[Category:Music tracks]]' .. (members ~= nil and '[[Is members only::' .. members .. ']]' or ''),
'?=#-',
'?Music track title=name',
(hints and '?Unlock hint=hint' or ''),
(members == nil and '?Is members only=members' or ''),
'?Music duration=duration',
'?Music track=file',
}
query.limit = batchSize
query.offset = 0
for i = 0, limit, batchSize do
query.limit = batchSize
query.offset = i
local t1 = os.clock()
local smwData = ask(query)
local t2 = os.clock()
if(smwData == nil) then break end
log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smwData, (t2 - t1) * 1000))
smwData = filterData(smwData)
tableConcat(allData, smwData)
end
assert(allData ~= nil and #allData > 0, 'SMW query failed')
table.sort(allData, function(a, b) return removeStringArticles(a[1]) < removeStringArticles(b[1]) end)
return allData
end
function p._main(args)
local limit = paramTest.default_to(tonumber(args.limit), 5000) -- Acting as a real limiter
local batchSize = paramTest.default_to(tonumber(args.batchsize), 250) -- 250 is slightly faster than 100 here
local hints = yesNo(args.hints) or false
local members = paramTest.default_to(args.members, nil)
local data = loadData(limit, batchSize, hints, members)
data = addCategoryToData(data, '[[Category:Old School-exclusive music]]', 'exclusive')
data = addCategoryToData(data, '[[Category:Event music]]', 'event')
local ret = createHeader(hints, members)
for _, trackPage in ipairs(data) do
ret:node(buildRow(trackPage, hints, members))
end
return ret
end
--[[DEBUG
p._main({})
p._main({['hints'] = 'Yes', ['members'] = 'No'})
]]
function p.main(frame)
local args = frame:getParent().args
return p._main(args)
end
return p