Module:Store locations list

From RuneScape Classic Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Store locations list/doc

-- <pre>
local p = {}

local commas = require("Module:Addcommas")._add
local params = require('Module:Paramtest')
local yesno = require("Module:Yesno")

local p2pIcon = '[[File:Member icon.png|frameless|link=Pay-to-play]]'
local f2pIcon = '[[File:Free-to-play icon.png|frameless|link=Free-to-play]]'

function p.main(frame)
	local args = frame:getParent().args
	
	local item,limit = params.defaults{
					{args[1],mw.title.getCurrentTitle().text},
					{args.Limit,100}
				}
	mw.log(string.format('Searching for shops that sell: %s', item))

	-- Get parsed smw data
	local data = getData(item,limit)

	-- Create the header of the output
	local headerText = ""
	local restbl = mw.html.create('table')
	restbl:addClass('wikitable sortable align-center-3 align-center-4 align-center-5  align-center-6')
		:tag('tr')
			:tag('th'):wikitext('Seller'):done()
			:tag('th'):wikitext('Location'):done()
			:tag('th'):wikitext('Number<br>in stock'):attr('data-sort-type', 'number'):done()
			:tag('th'):wikitext('Price<br>sold at'):attr('data-sort-type', 'number'):done()
			:tag('th'):wikitext('Price<br>bought at'):attr('data-sort-type', 'number'):done()
			:tag('th'):wikitext('Members'):done()
		:done()

	-- Create the rows for the output table
	for _, shop in ipairs(data) do
		restbl:tag('tr')
			:tag('td'):wikitext(shop.seller):done()
			:tag('td'):wikitext(shop.location):done()
			:tag('td')
				:attr({['data-sort-value']=shop.stockSortValue})
				:wikitext(shop.stock)
			:done()
			:tag('td')
				:attr({['data-sort-value']=shop.sellSortValue})
				:wikitext(shop.sellvalue)
			:done()
			:tag('td')
				:attr({['data-sort-value']=shop.buySortValue})
				:wikitext(shop.buyvalue)
			:done()
			:tag('td'):wikitext(shop.members):done()
		:done()
	end

	return headerText .. tostring(restbl)
end

function getData(itemName,args,limit)
	-- Query smw
	local q = {
		'[[Sold item::'..itemName..']]',
		'?Sold by',
		'?Sold item image',
		'?Sold item',
		'?Sold item text',
		'?Store stock',
		'?Store sell price',
		'?Store buy price',
		'?Store notes',
		limit = limit,
		sort = 'Store sell price',
		order = descending
	}
	local smwdata = mw.smw.ask(q)
	local data = {}

	if smwdata == nil then
		error('The item "' .. itemName .. '" is not 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
		-- Retrieve shop info
		local qs = {item['Sold by'],'?Store Is members only','?Store location'}
		local smwdataStore = mw.smw.ask(qs)
		
		if smwdataStore then
			local members, location = {}, {}
			for _, store in ipairs(smwdataStore) do
				if type(store['Store Is members only']) == 'string' or type(store['Store Is members only']) == 'boolean' then
					table.insert(members,store['Store Is members only'])
				elseif type(store['Store Is members only']) == 'table' then
					for _, v in ipairs(store['Store Is members only']) do
						table.insert(members,v)
					end
				end
				if type(store['Store location']) == 'string' then
					table.insert(location,store['Store location'])
				elseif type(store['Store location']) == 'table' then
					for _, v in ipairs(store['Store location']) do
						table.insert(location,v)
					end
				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
		end
		
		-- Loop over smw return items
		-- item['Store location'] = 'x'
		-- item['Store Is members only'] = 'Yes'
		-- Process the item and add it to the final data table
		local dataline = processData(item, editbtn)
		table.insert(data, dataline)
	end

	return data
end

function processData(item, editbtn)
	local seller = item['Sold by'] or ""
	local namenotes = item['Store notes']
	if namenotes then
		seller = seller .. ' ' .. namenotes
	end
	
	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
	
	local stock = item['Store stock'] or ''
	local stockSortValue = 0
	if stock == '∞' then
		stock = '<span style="font-size:120%;">∞</span>'
		stockSortValue = '10e50'
	elseif stock == 'N/A' then
		stockSortValue = '10e99'
	else
		stock = tonumber(stock)
		if stock then
			stockSortValue = stock
			stock = commas(stock)
		else
			stock = editbtn		-- If stock can't be converted to a number it will default to the edit button
		end
	end

	local sellvalue = item['Store sell price'] or ''
	local sellSortValue = 0
	if not(sellvalue == 1e10) then
		sellvalue = tonumber(sellvalue)
		if sellvalue then
			sellSortValue = sellvalue
			sellvalue = '[[File:Coins.png|link=Coins]] ' .. commas(sellvalue)
		else
			sellvalue = editbtn		-- If sellvalue can't be converted to a number it will default to the edit button
		end
	else
		sellSortValue = sellvalue
		sellvalue = 'N/A'
	end
	
	local buyvalue = item['Store buy price'] or ''
	local buySortValue = 0
	if not(buyvalue == 'N/A') then
		buyvalue = tonumber(buyvalue)
		if buyvalue then
			buySortValue = buyvalue
			buyvalue = '[[File:Coins.png|link=Coins]] ' .. commas(buyvalue)
		else
			buyvalue = editbtn		-- If sellvalue can't be converted to a number it will default to the edit button
		end
	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

	return {
		seller = seller,
		location = location,
		stock = stock,
		stockSortValue = stockSortValue,
		sellvalue = sellvalue,
		sellSortValue = sellSortValue,
		buyvalue = buyvalue,
		buySortValue = buySortValue,
		members = members
	}
end

function editbutton(title)
	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