Module:Sandbox/User:Alsang: Difference between revisions

no edit summary
(copy of module:Products)
No edit summary
(14 intermediate revisions by the same user not shown)
Line 1:
require('strict')
require('Module:Mw.html extension')
local Arrayparam = require( 'Module:ArrayParamtest' )
local currency = require('Module:Currency').parse
local yesnolang = requiremw.getContentLanguage('Module:Yesno')
local purgexpdata = requiremw.loadData('Module:PurgeExperience/data')._purge
 
local p = {}
 
-- non dynamic module, no inputs
function p.main(frame)
function p.main()
return p._main(frame:getParent().args)
end
-- returns only directly needed parameter needed for the row,
-- other parameters are determined by subqueries of chained pages
local query = {
'[[Activity JSON::~*]]',
'? = name',
'?Activity JSON = activityJSON',
'limit = 1500'
}
local results = mw.smw.ask(query)
results = p.screenResults(results)
 
return p.displayTable(results)
local function recipe_sort(recipe_a, recipe_b)
-- Sort unknown levels to the end
--for debugging
if (recipe_a.level == nil) ~= (recipe_b.level == nil) then
--return '<pre>'..mw.text.jsonEncode(results, mw.text.JSON_PRETTY)..'</pre>'
return recipe_b.level == nil
end
 
if recipe_a.level ~= nil then
return recipe_a.level < recipe_b.level
end
 
-- Sort by name if same level
return recipe_a.output[1].name < recipe_b.output[1].name
end
 
-- goes through a list of results and culls the ones which are not needed for this table
function p._main(args)
function p.screenResults(results)
args = args or {}
local resultsScreened = {}
local item = args[1] or mw.title.getCurrentTitle().text
local showPrices = yesno(args.showPrices)
-- iterate through products
local showValues = yesno(args.showValues)
for _, item in ipairs(results) do
local limit = tonumber(args.limit or 0) or 0
if limit <= 0 then
-- if theres only one activity, wrap in table
limit = 500
if type(item.activityJSON)=='string' then
end
item.activityJSON = { item.activityJSON }
 
-- Query for data
local smw_data = mw.smw.ask{
'[[Uses item::' .. item .. ']]',
'?Uses item',
'?Recipe JSON',
showValues and '?Value',
limit = limit
}
if not smw_data then
return ":''No products found. To force an update, click "
..purge('dml-'..mw.uri.anchorEncode(item), 'here', 'span')
..".''[[Category:Empty products lists]]"
end
 
-- Create a list of all recipes, grouped by output item (to keep them together in the sort)
local produced_items = {}
for _, product in ipairs(smw_data) do
local jsons = product['Recipe JSON']
if type(jsons) == 'string' then
jsons = { jsons }
end
local parsed = {}
for _j, json in ipairs(jsonsitem.activityJSON) do
local json = mw.text.jsonDecode(json)
local activityJSON = mw.text.jsonDecode(json)
json.Value = product.Value
-- Filter out when this item isn't actually used (Will happen on pages with multiple recipes)
if activityJSON.duration and tonumber(activityJSON.duration)==20 then
if Array.any(json.materials, function(mat)
returnlocal mat.nameitemNew == item{}
itemNew.name = item.name
end) then
itemNew.XP = activityJSON.xp
table.insert(parsed, json)
itemNew.lvl = activityJSON.level
itemNew.profession = activityJSON.profession
itemNew.duration = activityJSON.duration
itemNew.product = activityJSON.output[1].name
itemNew.XPperHour = itemNew.XP and tonumber(itemNew.XP) and itemNew.duration and tonumber(itemNew.duration) and tonumber(itemNew.XP) * 3600 / tonumber(itemNew.duration)
itemNew.fitXP = xpdata.knowledge[itemNew.lvl]*4*0.0005
if itemNew.lvl>=200 then
itemNew.fitXP = itemNew.fitXP * 4
end
itemNew.fitXP = math.floor(itemNew.fitXP * 100 ) / 100
local query = mw.smw.ask('[[Sold item::' .. itemNew.product .. ']][[Shop sell price::!~N/A]]|?Shop sell price=data|mainlabel=-')
if type(query)=='table' then
-- price is returned as a number
itemNew.productSellPrice = tonumber(query[1].data)*0.005
else
-- will return nil if the item is not in a shop, or if it is in a shop but can only be sold to the shop
itemNew.productSellPrice = nil
end
table.insert(resultsScreened,itemNew)
end
end
table.sort(parsed, recipe_sort)
table.insert(produced_items, parsed)
end
 
-- Sort bysort the smallestresults by recipe in the grouplevel
table.sort(produced_itemsresultsScreened, function(item1, item2)
local first1lvl1 = item1[1].lvl
local first2lvl2 = item2[1].lvl
if (first1lvl1 == nil) ~= (first2lvl2 == nil) then --one of two are empty
return lvl2 == nil -- true if lvl2 is nil but not lvl1, false if lvl1 is nil but not lvl2
return first2 == nil
end
if first1lvl1 == nil then
return false -- Both empty, equivalent
end
return lvl1 < lvl2 -- normal comparison
 
return recipe_sort(first1, first2)
end)
 
return resultsScreened
-- Flatten into a single list
local recipes = {}
for _, product in ipairs(produced_items) do
for _, json in ipairs(product) do
table.insert(recipes, json)
end
end
 
end
-- Calculate shop prices
if showPrices then
local price_cache = {}
for _, recipe in ipairs(recipes) do
for _, item in ipairs(recipe.materials) do
-- Extract item name and quantity from the "item,#" format
 
-- Query for the shop buy price of the item
local shopPriceResult = price_cache[item.name] or mw.smw.ask{
'[[Sold item::' .. item.name .. ']]',
'?Shop buy price'
} or {}
price_cache[item.name] = shopPriceResult
local shopPrice
 
if shopPriceResult[1] then
shopPrice = tonumber(shopPriceResult[1]['Shop buy price'] or 0) or 0
end
 
-- Update the product with the total price
if shopPrice ~= nil then
item.price = shopPrice * item.quantity
end
end
end
end
 
-- Createmake the table
function p.displayTable(results)
local out = mw.html.create('table')
:addClass('wikitable align-right-1 sortable')
:tag('tr')
:tag('th')
:attr{ colspan = wikitext('3Page' })
:wikitext('Recipe')
:done()
:tag('th'):wikitext('Level'):done()
:IFwikitext(showValues'Product')
:tag('th'):wikitext('Value'):done()
:ENDtag('th')
:tag('th') :wikitext('IngredientsProfession'):done()
:IFdone(showPrices)
:tag('th'):wikitext('Price'):done()
:ENDwikitext('Level')
:done()
:tag('th')
:wikitext('XP')
:done()
:tag('th')
:wikitext('0.0005 of levelup XP')
:done()
:tag('th')
:wikitext('sell price<br>per action')
:done()
-- :tag('th')
-- :wikitext('Duration')
-- :done()
-- :tag('th')
-- :wikitext('XP/hr')
-- :done()
:done()
 
for _i, recipeitem in ipairs(recipesresults) do
local row = out:tag('tr')
--level
:tag('td')
:wikitext(item.name)
:css{ ['border-right'] = '0', ['padding-right'] = '0' }
:attr{ ['data-sort-value'] = recipe.output[1].name }
:wikitext(recipe.output[1].quantity .. ' &times;')
:done()
:tag('td')
:wikitext('[[' .. item.product .. ']]')
:addClass('plinkt-image no-border')
:css{ ['border-left'] = '0', ['padding-left'] = '0' }
:wikitext('[[File:' .. recipe.output[1].name .. '.png|link=' .. recipe.output[1].name .. '|30px]]')
:done()
:tag('td')
:wikitext('[[' .. item.profession .. ']]')
:addClass('plinkt-link no-border')
:wikitext('[[' .. recipe.output[1].name .. ']]')
:done()
:tag('td')
:IFwikitext(recipeitem.professionlvl)
:wikitext(('[[File:%s small icon.png|15px|link=%s]] %s'):format(recipe.profession, recipe.profession, recipe.level or 'Unknown'))
:ELSE()
:wikitext(('[[FileUnknown profession small icon.png|15px|link=Professions]] %s'):format(recipe.level or 'Unknown'))
:END()
:done()
:tag('td')
 
:wikitext(item.XP)
if showValues then
if recipe.Value then
row:tag('td')
:wikitext(currency(recipe.Value))
:done()
else
row:tag('td')
:attr{ ['data-sort-value'] = '' }
:wikitext('Unknown')
:done()
end
end
 
local ingredients = row:tag('td')
:attr{ ['data-sort-value'] = table.concat(Array.map(recipe.materials, function(item) return item.name end), '\0') }
:tag('ul')
:css{ ['list-style'] = 'none', ['margin'] = '0', ['padding-left'] = '0' }
 
for _, item in ipairs(recipe.materials) do
ingredients:tag('li')
:wikitext(('%s &times; [[File:%s.png|link=%s|18px]] [[%s]]'):format(item.quantity, item.name, item.name, item.name))
:done()
:tag('td')
end
:wikitext(item.fitXP)
 
:done()
if showPrices then
local prices = row:tag('td')
:wikitext(item.productSellPrice)
:tag('ul')
:done()
:css{ ['list-style'] = 'none', ['margin'] = '0', ['padding-left'] = '0' }
-- :tag('td')
 
-- :wikitext(item.duration)
for _, item in ipairs(recipe.materials) do
-- :done()
if item.price then
-- :tag('td')
prices:tag('li'):wikitext(currency(item.price)):done()
-- :wikitext(item.XPperHour)
else
-- :done()
prices:tag('li'):wikitext('Unknown'):done()
end
end
end
 
:done()
end
 
19,555

edits