Module:Store locations list

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:Store locations list/doc. [edit]
Module:Store locations list's function main is invoked by Template:Store locations list.
Module:Store locations list requires Module:Addcommas.
Module:Store locations list requires Module:Currency Image.
Module:Store locations list requires Module:Paramtest.
Module:Store locations list requires Module:Purge.
Module:Store locations list requires Module:Yesno.

-- <pre>
local p = {}

local commas = require("Module:Addcommas")._add
local params = require('Module:Paramtest')
local yesNo = require("Module:Yesno")
local currencyImage = require("Module:Currency Image")
local purge = require("Module:Purge")._purge

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

function p.main(frame)
    return p._main(frame:getParent().args)
end

function p._main(args)
    local item, limit = params.defaults{
                            {args[1], mw.title.getCurrentTitle().text},
                            {args.Limit, 500}
                        }

    -- Create the header of the output
    local restbl = mw.html.create('table')
    restbl:addClass('wikitable sortable autosort=1,a align-center-3 align-center-4 align-center-5 align-center-6 align-center-7 align-center-8 store-locations-list')
        :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('Restock<br/>time'):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('Change<br/>Per'):attr('data-sort-type', 'number'):done()
            :tag('th'):wikitext('Members'):done()
        :done()

    -- Get parsed smw data
    mw.log(string.format('Searching for shops that sell: %s', item))
    local data = p.getData(item, limit)
    -- Create the rows for the output table
    for _, shop in ipairs(data) do

        local shopVersionValues = shop.shopVersion or { '' }
        if type(shopVersionValues) == 'string' then
            shopVersionValues = { shopVersionValues }
        end
        for i, shopVersion in ipairs(shopVersionValues) do
            local curVersionSeller = shop.seller

            local notetext = shopVersion
            if shop.namenotes ~= '' then
                notetext = shop.namenotes
            end
            if notetext ~= '' then
                curVersionSeller = curVersionSeller..' <span class="shop-version">'..notetext..'</span>'
            end

            local membersValues = shop.members or {}
            local curMembers = membersValues
            if type(membersValues) == 'table' then
                curMembers = membersValues[i] or membersValues[1] or ''
            end
            if curMembers == '' then
            	curMembers = '[[Category:Store locations list with empty members]]'
            end
            local locationValues = shop.location or {}
            local curLocation = locationValues
            if type(locationValues) == 'table' then
                curLocation = locationValues[i] or locationValues[1] or ''
            end
            if curLocation == '' then
            	curLocation = '[[Category:Store locations list with empty location]]'
            end

            restbl:tag('tr')
                :tag('td'):wikitext(curVersionSeller):done()
                :tag('td'):wikitext(curLocation):done()
                :tag('td')
                    :attr({['data-sort-value']=shop.stockSortValue})
                    :wikitext(shop.stock)
                :done()
                :tag('td')
                    :attr({['data-sort-value']=shop.restockSortValue})
                    :wikitext(shop.restock)
                :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.delta):done()
                :tag('td'):wikitext(membersTextToIcon(curMembers)):done()
            :done()
        end
    end

    return tostring(restbl)
end

function p.getData(itemName, limit)
    -- Query smw
    local q = {
        '[[Sold item text::'..itemName..']]',
        '?Sold item JSON',
        limit = limit,
    }

    local t1 = os.clock()
    local smwdata = mw.smw.ask(q)
    local t2 = os.clock()

    if smwdata == nil then
        error('The item "' .. itemName .. '" is not sold in any shop, please check for typos[[Category:Empty store lists]]', 0)
    end
    mw.log(string.format('SMW (store locations list): entries: %d, time elapsed: %.3f ms.', #smwdata, (t2 - t1) * 1000))

    -- Iterate through each shop instance of item
    local data = {}
    for _, item in ipairs(smwdata) do
        local soldItemJSON = mw.text.jsonDecode(item['Sold item JSON'] or '{}')
        local dataline = p.processData(soldItemJSON)
        table.insert(data, dataline)
    end
    return data
end

function p.processData(item)
    local seller = item['Sold by'] or ''
    if not seller:match('^%[%[') then
        seller = '[['..seller..']]'
    end

    local delta = string.format('[[Store price delta::%.1f]]%%',(item['Store delta'] or 10)/10)

    local region = item['Region'] or ''

    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 = ''
        end
    end

    local restock = item['Restock time'] or ''
    local restockSortValue = 0
    if restock == 'N/A' then
        restockSortValue = '10e99'
    else
        restock = tonumber(restock)
        if restock then
            restockSortValue = restock
            restock = ticktime(restock)
        else
            restock = ''
        end
    end

    local currency = item['Store currency']

    local sellvalue = item['Store sell price'] or ''
    local sellSortValue = 0
    if not (sellvalue == 1e10) then
        sellvalue = tonumber(sellvalue)
        if sellvalue then
            sellSortValue = sellvalue
            sellvalue = commas(sellvalue)
            local currencyImg = currencyImage(currency, sellSortValue) or ''
            if params.has_content(currencyImg) then
                currencyImg = string.format('[[File:%s|link=%s]] ', currencyImg, currency)
                sellvalue = currencyImg .. sellvalue
            end
        else
            sellvalue = ''
        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 = commas(buyvalue)
            local currencyImg = currencyImage(currency, buySortValue) or ''
            if params.has_content(currencyImg) then
                currencyImg = string.format('[[File:%s|link=%s]] ', currencyImg, currency)
                buyvalue = currencyImg .. buyvalue
            end
        else
            buyvalue = ''
        end
    end

    return {
        seller = seller,
        region = region,
        stock = stock,
        stockSortValue = stockSortValue,
        restock = restock,
        restockSortValue = restockSortValue,
        sellvalue = sellvalue,
        sellSortValue = sellSortValue,
        buyvalue = buyvalue,
        buySortValue = buySortValue,
        delta = delta,
        namenotes = item['Store notes'] or '',
        location = item['Location'],
        members = item['Members'],
        shopVersion = item['Shop version'],
    }
end

function ticktime(ticks)
    if ticks==-1 then
        return 'unknown'
    end
    local ret = ''
    local days = math.floor(ticks/144000)
    local hours = math.floor(ticks%144000/6000)
    local minutes = math.floor(ticks%6000/100)
    local seconds = ticks%100*0.6
    if days > 0 then
        ret = ret .. days .. 'd '
    end
    if hours > 0 then
        ret = ret .. hours .. 'h '
    end
    if minutes > 0 then
        ret = ret .. minutes .. 'm '
    end
    if seconds > 0 then
        ret = ret .. seconds .. 's'
    end
    return ret
end

function membersTextToIcon(text)
    local lower = string.lower(text or '')
    local hasYes = string.match(lower, 'yes')
    local hasNo = string.match(lower, 'no')
    if hasYes and hasNo then
        return f2pIcon..'/'..p2pIcon
    elseif hasYes then
        return p2pIcon
    elseif hasNo then
        return f2pIcon
    end
    return ''
end

return p