Module:Sandbox/User:Jakesterwars/Uses material list

From RuneRealm Wiki

This is an old revision of this page, as edited by Alex (talk | contribs) at 00:13, 17 October 2024 (Created page with "local p = {} local geprice = require('Module:Exchange')._price local commas = require('Module:Addcommas') local skillpic = require('Module:SCP')._main local yesno = require('Module:Yesno') local lang = mw.getContentLanguage() local trim = mw.text.trim -- Sorting function for two item objects, first by name, then by sub-text function sortItemsByNameSubtext(item1, item2) if (item1.output.name < item2.output.name) then return true elseif (item1.output.name > item2.out..."). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Template:Module sandbox/doc. [edit] [history] [purge]
Module:Sandbox/User:Jakesterwars/Uses material list requires Module:Addcommas.
Module:Sandbox/User:Jakesterwars/Uses material list requires Module:Exchange.
Module:Sandbox/User:Jakesterwars/Uses material list requires Module:SCP.
Module:Sandbox/User:Jakesterwars/Uses material list requires Module:Yesno.

This module is a sandbox for Jakesterwars. It can be used to test changes to existing modules, prototype new modules, or just experimenting with lua features.

Invocations of this sandbox should be kept in userspace; if the module is intended for use in other namespaces, it should be moved out of the sandbox into a normal module and template.

This default documentation can be overridden by creating the /doc subpage of this module, as normal.

local p = {}

local geprice = require('Module:Exchange')._price
local commas = require('Module:Addcommas')
local skillpic = require('Module:SCP')._main
local yesno = require('Module:Yesno')
local lang = mw.getContentLanguage()
local trim = mw.text.trim

-- Sorting function for two item objects, first by name, then by sub-text
function sortItemsByNameSubtext(item1, item2)
	if (item1.output.name < item2.output.name) then
		return true
	elseif (item1.output.name > item2.output.name) then
		return false
	else
		return (item1.output.subtxt or '') < (item2.output.subtxt or '')
	end
end

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

function p._main(args)
	local materials = {}
	local materials_lowered = {}
	
	if (args == nil) then
		table.insert(materials, mw.title.getCurrentTitle().text)
	else
		local i = 1
		
		while args[i] do
			local arg = trim(args[i])
			
			table.insert(materials, arg)
	    	materials_lowered[arg:lower()] = true
	    	
			i = i + 1
		end
	end

    -- Fetch data
    local query = {
        '[[Uses material::'..table.concat(materials, '||')..']]',
        '[[Production JSON::+]]',
        '?=#-',
        '?Production JSON = json',
        limit = args.limit or 500,
    }
    
    local t1 = os.clock()
    local smw_data = mw.smw.ask(query)
    local t2 = os.clock()

    if not smw_data then
        return 'Failed to find products with those materials - ensure they are spelled correctly. (ERR: no results from SMW)[[Category:Empty drop lists]]'
    end
    
    mw.log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smw_data, (t2 - t1) * 1000))

    -- Post-process
    data = {}

    for _, e in ipairs(smw_data) do
    	if type(e.json) == 'string' then
            local json = mw.text.jsonDecode(e.json)
            table.insert(data, json)
        elseif type(e.json) == 'table' then
        	for _, f in ipairs(e.json) do
        		local json = mw.text.jsonDecode(f)
                table.insert(data, json)
        	end
    	end
    end
    
    smw_data = nil
    
    -- Items with different variants (e.g. Divine battlemage potion has (1), (2), (3), (4) variants)
    -- or methods (e.g. "4-dose oil" vs "3-dose oil" for pyre logs) may not come in sorted, so now do a final alphabetical sort on name, sub-text
    table.sort(data, sortItemsByNameSubtext)

    -- Render page
    local t = mw.html.create('table')
    t:addClass('wikitable sortable products-list align-center-1 align-right-3 align-right-4')

    local ttlrow = t:tag('tr')
        :tag('th')
            :attr('colspan', '2')
            :wikitext('Item')
        :done()
        :tag('th')
            :wikitext('Members')
            :done()
        :tag('th')
            :attr('data-sort-type', 'number')
            :wikitext('Skills')
        :done()
        :tag('th')
            :attr('data-sort-type', 'number')
            :wikitext('XP')
        :done()
        :tag('th')
            :wikitext('Materials')
        :done()

    local rows = 0

    -- Render rows
    for _, item in ipairs(data) do
        local _found = false

        for _, mat_info in ipairs(item.materials) do
            if materials_lowered[mat_info.name:lower()] then
                _found = true
                break
            end
        end

        if _found then
            local name_str

            if (tonumber(item.output.quantity) or 0) > 1 then
                name_str = string.format('[[%s]] × %s', item.output.name, item.output.quantity)
            else
                name_str = string.format('[[%s]]', item.output.name)
            end
            
            if item.output.subtxt then
            	name_str = string.format('%s <br /><small>(%s)</small>', name_str, item.output.subtxt)	
            end
            
            local member_str

            if item.members == 'Yes' then
				member_str = "[[File:Member icon.png|center|link=Members|alt=Members]]"	
			elseif item.members == 'No' then
				member_str = "[[File:Free-to-play icon.png|center|link=Free-to-play|alt=Free-to-play]]"	
			end
		
            local experience_cell = mw.html.create('td')
            experience_cell:addClass('plainlist')

            local experience_ul = experience_cell:tag('ul')
            experience_ul:addClass('skills-list')

            local skills_cell = mw.html.create('td')
            skills_cell:addClass('plainlist')

            local skills_ul = skills_cell:tag('ul')
            skills_ul:addClass('skills-list')

            if #item.skills == 0 then
        		local skill_li = skills_ul:tag('li')
        		local experience_li = experience_ul:tag('li')

        		experience_cell:addClass('table-na'):css('text-align', 'center')
        		experience_li:wikitext(string.format('None'))
        		skills_cell:addClass('table-na'):css('text-align', 'center')
        		skill_li:wikitext(string.format('None'))
        	else
        		for index, v in ipairs(item.skills) do
            		local skill_li = skills_ul:tag('li')
            		local experience_li = experience_ul:tag('li')
            		local stripped_experience = v.experience:gsub(',', '')

            		skill_li
                        :attr('data-sort-value', index == 1 and v.level or '')
                        :wikitext(skillpic(lang:ucfirst(v.name), v.level))
            		experience_li
                        :attr('data-sort-value', index == 1 and v.experience or '')
                        :wikitext(tonumber(stripped_experience) ~= nil and skillpic(lang:ucfirst(v.name), v.experience) or v.experience)
        		end
        	end

            local mats_ul = mw.html.create('ul')
            mats_ul:addClass('products-materials')

            local mat_sort_val = nil

            for _, mat_info in ipairs(item.materials) do
                local mat_li = mats_ul:tag('li')
                local qty = mat_info.quantity:gsub('%-', '–')
                local mat_name = mat_info.name

            	for _, mat in ipairs(materials_lowered) do
            		if mat_name:lower() == mat then
            			mat_li:addClass('production-selected')
            		end
            	end

                if materials_lowered[mat_name:lower()] then
                    mat_li:addClass('production-selected')
                end
                
                if mat_sort_val == nil then
                	mat_sort_val = qty
                end
                
                mat_li:wikitext(string.format('%s × [[%s]]', commas._add(qty), mat_name))
            end

            local prow = t:tag('tr')
            	:tag('td')
            		:wikitext(item.output.image)
                :tag('td')
                	:attr('data-sort-value', item.product)
                    :wikitext(name_str)
                :done()
                :tag('td')
                	:wikitext(member_str)
                :node(skills_cell)
                :node(experience_cell)
                :tag('td')
                	:attr('data-sort-value', mat_sort_val)
                	:addClass('plainlist')
                    :node(mats_ul)
                :done()
            rows = rows + 1
        end
    end

    if rows == 0 then
        return 'Failed to find products with those materials - ensure they are spelled correctly. (ERR: no mats found in results)[[Category:Empty drop lists]]'
    end

    return t
end

--[[ DEBUG COPYPASTA
= p._main({'Mithril bar'})
--]]

return p