Cqm (Message Wall | contribs) mNo edit summary |
Cqm (Message Wall | contribs) mNo edit summary |
||
Line 285: | Line 285: | ||
local limit = data.limit and addcommas( data.limit ) or '<i>Unknown</i>' |
local limit = data.limit and addcommas( data.limit ) or '<i>Unknown</i>' |
||
local maxProfit = '<i>Unknown</i>' |
local maxProfit = '<i>Unknown</i>' |
||
+ | local members = '<i>Unknown</i>' |
||
local details = '[[Exchange:' .. item .. '|view]] • [[Exchange:' .. item .. '/Data|graph]]' |
local details = '[[Exchange:' .. item .. '|view]] • [[Exchange:' .. item .. '/Data|graph]]' |
||
local lastUpdated = timeago( {data.date} ) |
local lastUpdated = timeago( {data.date} ) |
||
Line 293: | Line 294: | ||
end |
end |
||
+ | local tr = '|-\n' .. |
||
+ | '|' .. image .. |
||
+ | '|style="width:15%;text-align:center;"|' .. itemStr .. |
||
+ | '|' .. priceStr .. |
||
+ | '|' .. alchStr .. |
||
+ | '|' .. profitStr .. |
||
+ | '|' .. roi .. |
||
+ | '|' .. limit .. |
||
+ | '|' .. maxProfit .. |
||
+ | '|' .. members .. |
||
+ | '|style="white-space:nowrap;"|' .. details .. |
||
+ | '|style="font-size:85%;"|' .. lastUpdated .. '\n' |
||
+ | |||
+ | --[=[ |
||
local tr = mw.html.create( 'tr' ) |
local tr = mw.html.create( 'tr' ) |
||
:tag( 'td' ) |
:tag( 'td' ) |
||
Line 333: | Line 348: | ||
:wikitext( lastUpdated ) |
:wikitext( lastUpdated ) |
||
:done() |
:done() |
||
+ | ]=] |
||
− | return |
+ | return tr |
end |
end |
||
Revision as of 23:16, 19 January 2015
Documentation for this module may be created at Module:Exchange/doc
--[[
{{Helper module|name=Exchange
|fname1=_price(arg)
|ftype1=String
|fuse1=Gets the current median price of item named arg
|fname2=_value(arg)
|ftype2=String
|fuse2=Gets the value of item named arg
}}
--]]
-- <pre>
--
-- Implements various exchange templates
-- See Individual method docs for more details
--
-- See also [[Module:ExchangeData]]
--
-- @todo document p._table and p.view better
--
local p = {}
-- only load commonly used modules here
local yesno = require( 'Module:Yesno' )
local addcommas = require( 'Module:Addcommas' )._add
-- map redirects to their correct pages
local geRedirects = {
['1/2 anchovy pizza'] = '½ anchovy pizza',
['1/2 meat pizza'] = '½ meat pizza',
["1/2 p'apple pizza"] = "½ p'apple pizza",
['1/2 plain pizza'] = '½ plain pizza',
['1/3 evil turnip'] = '⅓ evil turnip',
['2/3 cake'] = '⅔ cake',
['2/3 chocolate cake'] = '⅔ chocolate cake',
['2/3 evil turnip'] = '⅔ evil turnip',
['Dragon platelegs/skirt ornament kit (or)'] = 'Dragon platelegs & skirt ornament kit (or)',
['Dragon platelegs/skirt ornament kit (sp)'] = 'Dragon platelegs & skirt ornament kit (sp)'
}
--
-- Makes sure first letter of item is uppercase
-- Automatically handles any redirects
--
local function checkTitle( item )
-- upper case first letter to make sure we can find a valid item page
item = mw.text.split( item, '' )
item[1] = mw.ustring.upper( item[1] )
item = table.concat( item )
-- automatically handle redirects
if geRedirects[item] ~= nil then
item = geRedirects[item]
end
return item
end
--
-- Simple mw.loadData wrapper used to access data located on module subpages
--
-- @param item {string} Item to retrieve data for
-- @return {table} Table of item data
--
local function load( item )
item = checkTitle( item )
return mw.loadData( 'Module:Exchange/' .. item )
end
--
-- Returns the price of an item
--
-- @param item {string} Item to get current price of
-- @param multi {number} (optional) Multiplies the output price by the specified number
-- @param format {boolean} (optional) Format the result with commas (defaults to false)
-- @return {number|string} Price of item. Will return a string if formatted, else a number.
--
function p._price( item, multi, format )
local price = load( item ).price
local multi = type( multi ) == 'number' and multi or 1
local format = type( format ) == 'boolean' and format or false
local ret = price * multi
if format then
return addcommas( ret )
end
return ret
end
--
-- Returns the limit of an item
--
-- @param item {string} Item to get the limit of
-- @return {number} Limit of item
--
function p._limit( item )
return load( item ).limit
end
--
-- Returns the value of an item
--
-- @param item {string} Item to get the value or
-- @return {number} Value of item
--
function p._value( item )
return load( item ).value
end
--
-- Gets an items icon with a link to the item page
--
-- @deprecated
--
-- @param {string} Item to get icon for
-- @param {string} Icon file with a link to the item's page
-- If icon file is not found, defaults to [[File:Coins 1000.png]]
-- @return {string}
--
function p._icon( item )
local data = load( item )
local icon = data.icon or 'Coins 1000.png'
return '[[File:' .. icon .. '|link=' .. item .. ']]'
end
--
-- Calculates the difference between the current price and the last price of an item
--
-- @param item {string} Item to calculate price difference for
-- @param format {boolean} `true` if the output is to be formatted with commas
-- Defaults to `false`
-- @return {number|string} The price difference as a number
-- If `format` is set to `true` then this returns a string
-- If either of the prices to calculate the diff from are unavailable, this returns `0` (number)
--
function p._diff( item, format )
local data = load( item )
local diff = 0
if data.price and data.last then
diff = data.price - data.last
if format then
diff = addcommas( diff )
end
end
return diff
end
--
-- {{GEItem}} internal method
--
-- @todo check if this needs to be in a separate method
-- can it be merged into p.table instead?
--
-- @param item {string} Item to get data for
-- @return {string}
--
function p._table( item )
-- load data and any required modules
local data = load( item )
local timeago = require( 'Module:TimeAgo' )._ago
local changeperday = require( 'Module:ChangePerDay' )._change
-- set variables here to make the row building easier to follow
local div = '\'\'Unknown\'\''
local limit = data.limit and addcommas( data.limit ) or '\'\'Unknown\'\''
local members
if data.last then
local link = 'http://services.runescape.com/m=itemdb_rs/viewitem.ws?obj=' .. data.itemId
local change = math.abs( changeperday( {data.price, data.last, data.date, data.lastDate} ) )
if data.price > data.last then
arrow = '[[File:Up.png|20px|link=' .. link .. ']]'
elseif data.price < data.last then
arrow = '[[File:Down.png|20px|link=' .. link .. ']]'
else
arrow = '[[File:Unchg.png|40px|link=' .. link .. ']]'
end
if change >= 0.04 then
arrow = arrow .. arrow .. arrow
elseif change >= 0.02 then
arrow = arrow .. arrow
end
div = mw.html.create( 'div' )
:css( 'white-space', 'nowrap' )
:wikitext( arrow )
div = tostring( div )
end
if data.members == nil then
members = '\'\'Unknown\'\''
elseif yesno( data.members ) then
members = '[[File:P2P icon.png|30px|link=Pay-top-play]]'
else
members = '[[File:F2P icon.png|30px|link=Free-to-play]]'
end
-- build table row
local tr = mw.html.create( 'tr' )
:tag( 'td' )
:wikitext( p._icon( item ) )
:done()
:tag( 'td' )
:css( {
['width'] = '15%',
['text-align'] = 'left'
} )
:wikitext( '[[' .. item .. ']]' )
:done()
:tag( 'td' )
:wikitext( addcommas( data.price ) )
:done()
:tag( 'td' )
:wikitext( div )
:done()
if data.alchable == nil or yesno( data.alchable ) then
local low, high = '\'\'Unknown\'\'', '\'\'Unknown\'\''
if data.value then
low = addcommas( math.floor( data.value * 0.4 ) )
high = addcommas( math.floor( data.value * 0.6 ) )
end
tr
:tag( 'td' )
:wikitext( low )
:done()
:tag( 'td' )
:wikitext( high )
:done()
else
tr
:tag( 'td' )
:attr( 'colspan', '2' )
:wikitext( '\'\'Cannot be alchemised\'\'' )
:done()
end
tr
:tag( 'td' )
:wikitext( limit )
:done()
:tag( 'td' )
:wikitext( members )
:done()
:tag( 'td' )
:css( 'white-space', 'nowrap' )
-- todo remove graph link when data is moved to modules
:wikitext( '[[Exchange:' .. item .. '|view]] • [[Exchange:' .. item .. '/Data|graph]]' )
:done()
:tag( 'td' )
:css( 'font-size', '85%' )
:wikitext( timeago( {data.date} ) )
:done()
return tostring( tr )
end
--
-- Internal method for p.highAlchTable and p.lowAlchTable
--
function p._alchTable( item, data, alch )
local timeago = require( 'Module:TimeAgo' )._ago
local round = require( 'Module:Number' )._round
local natPrice = load( 'Nature rune' ).price
local profit = alch - data.price - natPrice
local image = '[[File:' .. item .. '.png|' .. item .. ']]'
local itemStr = '[[' .. item .. ']]'
local priceStr = addcommas( data.price )
local alchStr = addcommas( alch )
local profitStr = addcommas( profit )
local roi = tostring( round( ( profit / ( data.price + natPrice ) * 100 ), 1 ) ) .. '%'
local limit = data.limit and addcommas( data.limit ) or '<i>Unknown</i>'
local maxProfit = '<i>Unknown</i>'
local members = '<i>Unknown</i>'
local details = '[[Exchange:' .. item .. '|view]] • [[Exchange:' .. item .. '/Data|graph]]'
local lastUpdated = timeago( {data.date} )
if data.limit then
local min = ( data.limit > 4800 ) and 4800 or data.limit
local maxProfit = addcommas( min * profit )
end
local tr = '|-\n' ..
'|' .. image ..
'|style="width:15%;text-align:center;"|' .. itemStr ..
'|' .. priceStr ..
'|' .. alchStr ..
'|' .. profitStr ..
'|' .. roi ..
'|' .. limit ..
'|' .. maxProfit ..
'|' .. members ..
'|style="white-space:nowrap;"|' .. details ..
'|style="font-size:85%;"|' .. lastUpdated .. '\n'
--[=[
local tr = mw.html.create( 'tr' )
:tag( 'td' )
:wikitext( image )
:done()
:tag( 'td' )
:css( {
width = '15%',
['text-align'] = 'left'
} )
:wikitext( itemStr )
:done()
:tag( 'td' )
:wikitext( priceStr )
:done()
:tag( 'td' )
:wikitext( alchStr )
:done()
:tag( 'td' )
:wikitext( profitStr )
:done()
:tag( 'td' )
:wikitext( roi )
:done()
:tag( 'td' )
:wikitext( limit )
:done()
:tag( 'td' )
:wikitext( maxProfit )
:done()
:tag( 'td' )
:wikitext( members )
:done()
:tag( 'td' )
:css( 'white-space', 'nowrap' )
:wikitext( details )
:done()
:tag( 'td' )
:css( 'font-size', '85%' )
:wikitext( lastUpdated )
:done()
]=]
return tr
end
--
-- {{ExchangeItem/HighAlchTable}}
--
-- @example {{ExchangeItem/HighAlchTable|<item>}}
--
function p.highAlchTable( frame )
local args = frame:getParent().args
local item = checkTitle( args[1] )
local data = load( item )
local alch = math.floor( data.value * 0.6 )
return p._alchTable( item, data, alch )
end
--
-- {{ExchangeItem/LowAlchTable}}
--
-- @example {{ExchangeItem/LowAlchTable|<item>}}
--
function p.lowAlchTable( frame )
local args = frame:getParent().args
local item = checkTitle( args[1] )
local data = load( item )
local alch = math.floor( data.value * 0.4 )
return p._alchTable( item, data, alch )
end
--
-- {{GEP}}
-- {{GEPrice}}
--
-- @example {{GEPrice|<item>|<format>|<multi>}}
-- @example {{GEPrice|<item>|<multi>}}
-- @example {{GEP|<item>|<multi>}}
--
function p.price( frame )
-- usage: {{foo|item|format|multi}} or {{foo|item|multi}}
local args = frame.args
local pargs = frame:getParent().args
local item = pargs[1]
if item then
item = mw.text.trim( item )
else
error( '"item" argument not specified', 0 )
end
-- default to formatted for backwards compatibility with old GE templates
local format = true
local multi = 1
-- format is set with #invoke
-- so set it first to allow it to be overridden by template args
if args.format ~= nil then
format = yesno( args.format )
end
if tonumber( pargs[2] ) ~= nil then
multi = tonumber( pargs[2] )
-- indicated someone is trying to pass an equation as a mulitplier
-- known use cases are fractions, but pass it to #expr to make sure it's handled correctly
elseif pargs[2] ~= nil and mw.ustring.find( pargs[2], '[/*+-]' ) then
multi = tonumber( frame:preprocess( '{{#expr:' .. pargs[2] .. '}}' ) )
-- uses elseif to prevent something like {{GEP|Foo|1}}
-- causing a formatted output, as 1 casts to true when passed to yesno
elseif type( yesno( pargs[2] ) ) == 'boolean' then
format = yesno( pargs[2] )
if tonumber( pargs[3] ) ~= nil then
multi = tonumber( pargs[3] )
end
end
return p._price( item, multi, format )
end
--
-- {{GEItem}}
--
-- @example {{GEItem|<item>}}
--
function p.table( frame )
local args = frame:getParent().args
local item = args[1]
if item then
item = mw.text.trim( item )
else
error( '"item" argument not specified', 0 )
end
return p._table( item )
end
--
-- Implements {{GEIcon}}
--
-- @deprecated
--
-- @example {{GEItem|<item>}}
-- @example {{GEIcon|<item>|w}} (outputs <item> after the image)
--
function p.icon( frame )
local args = frame:getParent().args
local item = args[1]
local w = args[2]
if item then
item = mw.text.trim( item )
else
error( '"item" argument not specified', 0 )
end
local ret = p._icon( item )
if w == 'w' then
ret = ret .. ' ' .. item
end
return '<span class="GEIcon">' .. ret .. '</span>'
end
--
-- {{ExchangeItem}}
--
-- @example {{ExchangeItem|<item>}}
-- @example {{ExchangeItem|Item=<item>}} (deprecated)
--
function p.view( frame )
local args = frame:getParent().args
local item = args[1] or args['Item']
local view = args.view or args.View or ''
local loadView = {limit=true, value=true, itemId=true}
if item then
item = mw.text.trim( item )
else
error( '"item" argument not specified', 0 )
end
view = mw.ustring.lower( view )
if view == 'itemid' then
view = 'itemId'
end
if view == 'diff' then
return p._diff( item )
elseif loadView[view] then
return load( item )[view]
--
-- values of view beyond this point are deprecated and will eventually be removed
-- except the default output (for Exchange ns pages)
--
elseif view == 'price' then
-- p.price defaults to formatted
-- so pass to p._price instead
return p._price( item )
elseif view == 'icon' then
return p._icon( item )
elseif view == 'table' then
return p._table( item )
else
local default = require( 'Module:ExchangeDefault' )
-- handle redirects and casing of item before passing it on
item = checkTitle( item )
return default.main( frame, item )
end
end
return p