Module:Store locations list
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Store locations list/doc
-- <nowiki>
local p = {}
local commas = require("Module:Addcommas")._add
local yesno = require("Module:Yesno")
local is_empty = require("Module:Paramtest").is_empty
local has_content = require("Module:Paramtest").has_content
local currency_image = require("Module:Currency Image")
local purge = require("Module:Purge")._purge
local p2pIcon = '[[File:P2P icon.png|25px|frameless|link=Pay-to-play]]'
local f2pIcon = '[[File:F2P icon.png|25px|frameless|link=Free-to-play]]'
local packIcon = ' [[File:Empty sack pack.png|25px|frameless|link=Item pack|alt=Item pack]]'
function p.main(frame)
local args = frame:getParent().args
local item = args[1] and mw.text.trim(args[1]) or mw.title.getCurrentTitle().text
mw.log(string.format('Searching for shops that sell: %s', item))
local historical = yesno(args['Historical'],false)
-- Get parsed smw data
local data = getData(item,args)
-- Create the header of the output
local headerText = "<div class=\"seealso\">This is an auto-generated list (" .. purge('res', 'update now', 'span') .. "). For help, see [[Template:Store locations list/FAQ|the FAQ]].</div>\n"
if historical then
headerText = "<div class=\"seealso\">Note: As this item is no longer sold, this is a list of stores that previously sold it.</div>\n"..headerText
end
local restbl = mw.html.create('table')
if historical then
restbl:addClass('wikitable sortable storeloc-hist align-right-3 align-right-4 align-right-5 align-center-6 sticky-header')
else
restbl:addClass('wikitable sortable align-right-3 align-right-4 align-right-5 align-center-6 sticky-header')
end
restbl:tag('tr')
:tag('th'):wikitext('Seller'):done()
:tag('th'):wikitext('Location'):done()
:tag('th'):wikitext('Cost'):attr('data-sort-type', 'number'):done()
:tag('th'):wikitext('Currency'):done()
:tag('th'):wikitext('Base stock'):attr('data-sort-type', 'number'):done()
:tag('th'):wikitext('Members?'):done()
:done()
-- Create the rows for the output table
local hasHistoric = false
for _, shop in ipairs(data) do
local row = restbl:tag('tr')
if shop.historic then
hasHistoric = true
local seller = shop.seller .. '<span title="Was previously sold by" style="cursor:help;"><i><b> †</b></i></span>'
row :addClass('store-hist')
:tag('td'):wikitext(seller):done()
else
row:tag('td'):wikitext(shop.seller):done()
end
row :tag('td'):wikitext(shop.location):done()
:tag('td')
:attr({
['data-sort-value']=shop.costSortValue,
['title']=shop.costTitle
})
:css('cursor','help')
:wikitext(shop.cost)
:done()
:tag('td')
:attr({
['data-sort-value']=shop.currSortValue,
['title']=shop.currTitle
})
:wikitext(shop.currency)
:done()
:tag('td')
:attr({
['data-sort-value']=shop.stockSortValue,
['title']=shop.stockTitle
})
:css('cursor','help')
:wikitext(shop.stock)
:done()
:tag('td'):wikitext(shop.members):done()
:done()
end
if hasHistoric then
local caption = '<i>† Denotes discontinued stores that stocked [[' .. item .. ']]. For help, see [[Template:Store locations list/FAQ|the FAQ]].</i>'
restbl:tag('caption')
:css('caption-side', 'bottom')
:wikitext(caption)
:done()
end
return headerText .. tostring(restbl)
end
function getData(itemName,args)
local historical = yesno(args['Historical'] or args[2],false)
local itemIsMembers = false
mw.log('Querying for item info for '..itemName)
local itemData = mw.smw.ask({
'[['..itemName..']]',
'?Is members only'
})
if itemData then
itemIsMembers = itemData[1]['Is members only'] == true
-- == true to exclude Is members only being a table
end
mw.log('Found that item membership is: '..tostring(itemIsMembers))
-- Query smw historical
local qh = {
'[[Sold item hist::'..itemName..']]',
'?Sold by hist#-=Sold by',
'?Store stock',
'?Store stock infinite',
'?Store sell price',
'?Store currency',
'?Sold by hist.Is members only=Store members',
'?Sold by hist.Store location=Store location',
limit = args.limit or 100,
sort = args.sort,
order = args.order
}
-- Query for packs historical
local qph = {
'[[Pack of hist::'..itemName..']]',
'?Pack amount',
'?Sold by hist#-=Sold by',
'?Store stock',
'?Store stock infinite',
'?Store sell price',
'?Store currency',
'?Sold by hist.Is members only=Store members',
'?Sold by hist.Store location=Store location',
'?Sold item.Is members only=Item members',
limit = args.limit or 100,
sort = args.sort,
order = args.order
}
-- Query smw
local q = {
'[[Sold item::'..itemName..']]',
'?Sold by#-',
'?Store stock',
'?Store stock infinite',
'?Store sell price',
'?Store currency',
'?Sold by.Is members only=Store members',
'?Sold by.Store location=Store location',
limit = args.limit or 100,
sort = args.sort,
order = args.order
}
-- Query for packs
local qp = {
'[[Pack of::'..itemName..']]',
'?Pack amount',
'?Sold by#-',
'?Store stock',
'?Store stock infinite',
'?Store sell price',
'?Store currency',
'?Sold by.Is members only=Store members',
'?Sold by.Store location=Store location',
'?Sold item.Is members only=Item members',
limit = args.limit or 100,
sort = args.sort,
order = args.order
}
local smwdata = {}
local smwdataP = {}
-- Historical pages
if historical then
smwdata = mw.smw.ask(qh)
smwdataP = mw.smw.ask(qph)
else -- Regular pages (show both)
smwdata = mw.smw.ask(q)
smwdataP = mw.smw.ask(qp)
-- Historic shops
local smwdataH = mw.smw.ask(qh)
if smwdataH then
for _,item in ipairs(smwdataH) do
item.Historic = true
table.insert(smwdata,item)
end
end
local smwdataPH = mw.smw.ask(qph)
if smwdataPH then
for _,item in ipairs(smwdataPH) do
item.Historic = true
table.insert(smwdataP,item)
end
end
end
-- Query packs
if smwdataP then
for _,item in ipairs(smwdataP) do
item['Is pack'] = true
table.insert(smwdata,item)
end
end
local data = {}
if smwdata == nil and historical then
error('The item "' .. itemName .. '" was never sold in any shop, please check for typos[[Category:Empty store lists]]', 0)
elseif smwdata == nil then
error('The item "' .. itemName .. '" is not, and was never, sold in any shop, please check for typos[[Category:Empty store lists]]', 0)
end
-- Loop over array of subobjects (items sold by shops)
for _, item in ipairs(smwdata) do
local soldby = item['Sold by'] or item['Sold by hist'] or ""
local seller = '[['..soldby..']]'
if item['Is pack'] then
seller = seller..packIcon
end
local editbtn = editbutton(item['Sold by'] or item['Sold by hist'] or "")
-- Retrieve shop info
local smwdataStore = {
['Is members only'] = itemIsMembers or item['Item members'] or item['Store members'],
['Store location'] = item['Store location']
}
-- Loop over smw return items
local members, location = {}, {}
if type(smwdataStore['Is members only']) == 'string' or type(smwdataStore['Is members only']) == 'boolean' then
table.insert(members,smwdataStore['Is members only'])
elseif type(smwdataStore['Is members only']) == 'table' then
for _, v in ipairs(smwdataStore['Is members only']) do
table.insert(members,v)
end
end
if type(smwdataStore['Store location']) == 'string' then
table.insert(location,smwdataStore['Store location'])
elseif type(smwdataStore['Store location']) == 'table' then
for _, v in ipairs(smwdataStore['Store location']) do
table.insert(location,v)
end
end
if #members == 1 then
item['Store Is members only'] = members[1]
else
item['Store Is members only'] = members
end
if #location == 1 then
item['Store location'] = location[1]
else
item['Store location'] = location
end
-- Process the item and add it to the final data table
local dataline = processData(item, seller, editbtn)
table.insert(data, dataline)
end
return data
end
function processData(item, seller, editbtn)
-- location
local location = item['Store location'] or editbtn
if type(location) == 'table' and #location > 0 then
location = table.concat(location, ', ')
elseif type(location) == 'table' then
location = editbtn
end
-- Historic?
local historic = false
if item.Historic then
historic = true
end
-- members only?
local members = item['Store Is members only']
if type(members) == 'table' then
-- contains yes and no
local hasYes, hasNo = false, false
for _, value in ipairs(members) do
value = yesno(value)
if value == true then
hasYes = true
elseif value == false then
hasNo = true
end
end
if hasYes and hasNo then
members = f2pIcon.."/"..p2pIcon
elseif hasYes then
members = p2pIcon
elseif hasNo then
members = f2pIcon
else
members = editbtn
end
elseif yesno(members) == true then
members = p2pIcon
elseif yesno(members) == false then
members = f2pIcon
-- Unsupported type for yesno, default to editbtn
else
members = editbtn
end
-- base amount in stock
local stock = item['Store stock'] or ''
local stockSortValue = 0
local stockTtl = ''
stock = string.lower(string.gsub(stock, ',', ''))
if item['Store stock infinite'] then
if item['Is pack'] then
stockTtl = '<span style="font-size:120%;">∞</span>'
else
stockTtl = 'Infinite available'
end
stock = '<span style="font-size:120%;">∞</span>'
if historic then
stockSortValue = '-10e99'
else
stockSortValue = '10e99'
end
else
stock = tonumber(stock)
if stock then
if item['Is pack'] then
local packNum = tonumber(item['Pack amount'])
local total = stock * packNum
stockSortValue = total
stockTtl = commas(stock)..' packs of '..commas(packNum)
stock = commas(total)
else
stockSortValue = stock
stockTtl = commas(stock)
stock = commas(stock)
end
if historic then
stockSortValue = stockSortValue * -1
end
else
stock = editbtn -- If stock can't be converted to a number it will default to the edit button
end
end
-- item cost
local cost = item['Store sell price'] or ''
local costSortValue = 0
local rawCost = 0
local costTtl
cost = string.lower(string.gsub(cost, ',', ''))
if cost == 'free' or cost == '0' or cost == 'sample' then
cost = 'Free sample'
costTtl = 'Free sample'
else
cost = tonumber(cost)
if cost then
if item['Is pack'] then
local packNum = tonumber(item['Pack amount'])
local each = cost / packNum
costSortValue = each
costTtl = 'Pack of '..commas(packNum)..' costs '..commas(cost)
cost = commas(each)
else
costSortValue = cost
costTtl = commas(cost)
cost = commas(cost)
end
rawCost = costSortValue
if historic then
costSortValue = costSortValue * 1000
end
else
cost = editbtn
end
end
-- currency
local currency = item['Store currency']
local currSortValue = currency
local currTitle = currency
if is_empty(currency) then
currency = editbtn
elseif cost == 'Free sample' then
currency = "-"
else
local displayVal = currency:gsub("^%l", string.upper) -- first letter uppercase
currTitle = displayVal
local imageName = currency_image(currency, rawCost) or ''
if(has_content(imageName)) then
currency = string.format('<span class="inventory-image">[[File:%s|x22px|link=]]</span> %s', imageName, displayVal)
else
currency = displayVal
end
end
if historic then
currSortValue = 'zz ' .. currSortValue
end
return {
seller = seller,
location = location,
members = members,
stock = stock,
stockTitle = stockTtl,
stockSortValue = stockSortValue,
cost = cost,
costTitle = costTtl,
costSortValue = costSortValue,
currency = currency,
currTitle = currTitle,
currSortValue = currSortValue,
historic = historic
}
end
function editbutton(title)
if (title=="") then
return ""
end
local link = string.gsub(mw.title.getCurrentTitle():fullUrl("action=edit"), mw.title.getCurrentTitle().fullText, title)
link = string.gsub(link, ' ', '_')
link = string.format("<span class='plainlinks'>[%s '''?''' (edit)]</span>", link)
return link
end
return p
-- </nowiki>