Module:Exchange

-- -- -- Implements --

local p = {} local yesno = require( 'Module:Yesno' ) local addcommas = require( 'Module:Addcommas' )._add

-- -- Simple mw.loadData wrapper used to access data located on module subpages -- local function load( item ) return mw.loadData( 'Module:Exchange/' .. item ) end

-- -- Returns the icon with a link to the item page -- If the icon does not exist, then it uses File:Coins 1000.png -- function p._icon( item ) local data = load( item ) local icon = data.icon or 'Coins 1000.png'

return '' end

-- -- Returns the difference between the current price and the last price -- If either are unavailable this returns 0 -- function p._diff( item, format ) local data = load( item ) local diff

if data.price and data.last then diff = data.price - data.last

if format then diff = addcommas( diff ) end

return diff end

return '0' end

-- -- For use in -- -- Essentially a replacement for -- @todo convert to html syntax when this goes live  --      136 uses as of 2014/06/22  -- 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 = '' elseif data.price < data.last then arrow = '' else arrow = '' 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 = '' else members = '' 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( 'view &bull; graph' ) :done :tag( 'td' ) :css( 'font-size', '85%' ) :wikitext( timeago( {data.date} ) ) :done

return tostring( tr )

end

-- -- For access price data for use in exchange graphs -- function p._data( item ) --[=[



]=]   return 'data' end

-- -- For use on exchange ns pages -- function p._page( item, uses )

local lang = mw.language.getContentLanguage local timeago = require( 'Module:TimeAgo' )._ago local round = require( 'Module:Number' )._round local data = load( item )

-- set variables here if possible to keep table building easier to follow local rowspan = 8 local volDate = data.volumeDate or lang:formatDate( 'c' ) local dateDiffZ = lang:formatDate( 'z' ) - lang:formatDate( 'z', volDate ) local dateDiffY = lang:formatDate( 'Y' ) - lang:formatDate( 'Y', volDate ) local price = addcommas( data.price ) or '\'\'N/A\'\'' local date = '\'\'N/A\'\'' local lowAlch = '\'\'Not alchable\'\'' local highAlch = '\'\'Not alchable\'\'' local memsIcon = ''

if data.volume and ( dateDiffZ + 365 * dateDiffY ) <= 7 then rowspan = 10 end

if data.date then date = lang:formatDate( 'j F Y, H:i "(UTC)"', data.date ) end

if not ( data.alchable and not yesno( data.alchable ) ) then lowAlch = addcommas( math.floor( data.value * 0.4 ) ) highAlch = addcommas( math.floor( data.value * 0.6 ) ) end

if data.members ~= nil then if data.members then memsIcon = '' else memsIcon = '' end end -- build table local tbl = mw.html.create( 'table' ) :addClass( 'wikitable' ) :css( {           ['border'] = '0',            ['border-collapse'] = 'separate',            ['margin-top'] = '-1em'        } ) :tag( 'tr' ) :tag( 'th' ) :attr( 'colspan', '2' ) :css( {                   border = '0',                    padding = '0'                } ) :tag( 'table' ) :css( {                       width = '100%',                        ['border-collapse'] = 'collapse'                    } ) :tag( 'tr' ) :tag( 'td' ) :css( {                               padding = '8px 16px',                                ['border-right'] = '0'                            } ) :wikitext( p._icon( item ) ) :done :tag( 'td' ) :css( {                               width = '100%',                                ['font-size'] = '135%',                                ['text-align'] = 'left',                                ['white-space'] = 'normal',                                padding = '8px 0',                                ['border-left'] = '0',                                ['border-right'] = '0'                            } ) -- this used to default to Grand Exchange Market Watch if item wasn't supplied -- but that only happened on 6 user pages, an orphanage and a preload :wikitext(  .. item ..  ) :tag( 'br' ) :done :tag( 'span' ) :css( {                                   ['font-weight'] = 'normal',                                    ['font-size'] = '75%'                                } ) :wikitext( data.examine or '' ) :done :done :tag( 'td' ) :css( {                               padding = '8px 16px',                                ['border-left'] = '0'                            } ) :wikitext( memsIcon ) :done :done :done :done :done :tag( 'tr' ) :tag( 'th' ) :css( {                   ['text-align'] = 'left',                    ['padding-left'] = '10px'                } ) :wikitext( 'Price data' ) :done :tag( 'td' ) :attr( 'rowspan', rowspan ) :css( 'vertical-align', 'top' ) :tag( 'div' ) :addClass( 'GEPage' ) :css( {                       padding = '10px 5px 0 5px',                        float = 'right'                    } ) :tag( 'div' ) :addClass( 'GEdatachart' ) :css( {                           margin = '5px 0 25px 0',                            ['min-width'] = '700px',                            ['height'] = '500px'                        } ) -- GE Chart goes here :done :done :done :done :tag( 'tr' ) :tag( 'td' ) :css( {                   ['vertical-align'] = 'top',                    ['padding-bottom'] = '5px'                } ) :tag( 'ul' ) :tag( 'li' ) :wikitext( '\'\'\'Price:\'\'\' ' ) :tag( 'span' ) :attr( 'id', 'GEPrice' ) :wikitext( price ) :done :done :tag( 'li' ) :wikitext( '\'\'\'Last updated:\'\'\' ' .. timeago( {[1]=data.date, purge='yes'} ) ) :tag( 'br' ) :done -- do I need this if its self closing? :tag( 'span' ) :attr( 'id', 'GEDate' ) :wikitext( date ) :done :done :done :done :done

if data.volume and ( dateDiffZ + 365 * dateDiffY ) <= 7 then tbl :tag( 'tr' ) :tag( 'th' ) :css( {                       ['text-align'] = 'left',                        ['padding-left'] = '10px'                    } ) :wikitext( 'Volume data' ) :done :done :tag( 'tr' ) :tag( 'td' ) :attr( 'id', 'volumeData' ) :css ( {                       ['vertical-align'] = 'top',                        ['padding-bottom'] = '5px'                    } ) :tag( 'ul' ) :tag( 'li' ) :wikitext( '\'\'\'7-day total:\'\'\' ' ) :tag( 'span' ) :attr( 'id', 'GEVolume' ) :wikitext( addcommas( 1000000 * data.volume ) ) :done :done :tag( 'li' ) :wikitext( '\'\'\'1-day average\'\'\' ' .. addcommas( round( 1000000 / 7 * data.volume, 3 ) ) ) :done :tag( 'li' ) :wikitext( '\'\'\'Last updated:\'\'\' ' .. timeago( {[1]=data.volumeDate, purge='yes'} ) ) :tag( 'br' ) :done :tag( 'span' ) :attr( 'id', 'GEVolumeDate' ) :wikitext( lang:formatDate( 'j F Y, H:i "(UTC)"', data.volumeDate ) ) :done :done :done :done end

tbl :tag( 'tr' ) :tag( 'th' ) :css( {                   ['text-align'] = 'left',                    ['padding-left'] = '10px'                } ) :wikitext( 'Other details' ) :done :done :tag( 'tr' ) :tag( 'td' ) :css( {                   ['vertical-align'] = 'top',                    ['padding-bottom'] = '5px'                } ) :tag( 'ul' ) :tag( 'li' ) :wikitext( '\'\'\'Exchange ID:\'\'\' ' ) :tag( 'span' ) :attr( 'id', 'GEDID' ) :wikitext( data.itemId or '\'\'Unknown\'\'' ) :done :done :tag( 'li' ) :wikitext( '\'\'\'Low Alchemy:\'\'\' ' .. lowAlch ) :done :tag( 'li' ) :wikitext( '\'\'\'High Alchemy:\'\'\' ' .. highAlch ) :done :tag( 'li' ) :wikitext( '\'\'\'Value:\'\'\' ' .. data.value and addcommas( data.value ) or '\'\'Unknown\'\'' ) :done :tag( 'li' ) :wikitext( '\'\'\'Exchange limit:\'\'\' ' .. data.limit and addcommas( data.limit ) or '\'\'Unknown\'\'' ) :done :tag( 'li' ) :wikitext( '\'\'\'GED Category:\'\'\' ' .. data.category or '\'\'Unknown\'\'' ) :done :done :done :done :tag( 'tr' ) :tag( 'th' ) :css( {                   ['text-align'] = 'left',                    ['padding-left'] = '10px'                } ) :wikitext( 'External links' ) :done :done :tag( 'tr' ) :tag( 'td' ) :css( {                   ['vertical-align'] = 'top',                    ['padding-bottom'] = '5px'                } ) :tag( 'ul' ) :tag( 'li' ) :wikitext( '.. data.itemId .. ' Lookup current price' ) :done :tag( 'li' ) :wikitext( '.. mw.uri.encode( data.item, 'QUERY' ) .. ' Search for relevant prices' ) :done :done :done :done :tag( 'tr' ) :tag( 'th' ) :css( {                   ['text-align'] = 'left',                    ['padding-left'] = '10px'                } ) :wikitext( 'Usage' ) :done :done :tag( 'tr' ) :tag( 'td' ) :css( {                   ['vertical-align'] = 'top',                    ['padding-left'] = '5px',                    ['padding-bottom'] = '5px'                } ) :wikitext( 'This item is used in:' ) :newline -- @todo move places used to data in module :wikitext( uses ) :done :done

--[=[

-- categories local cats = '' if ns == 'Exchange' then cat = cats ..                   ..                    .. ''        if data.item !=  then -- ' -> &#39;, & -> &#38; cats = cats .. ''       end if data.item then cats = cats .. '{{DEFAULTSORT:' .. data.item end if not data.itemId then cats = cats .. ''       end if not data.icon then cats = cats .. ''       end if data.value then if not ( data.alchable and not yesno( data.alchable ) ) then if ( ( data.value * 0.6 ) - price - natPrice ) > 0 then cats = cats .. ''               end if ( ( data.value * 0.4 ) - price - natPrice ) > 0 then cats = cats .. ''               end end else cats = cats .. ''       end local lastUpdate = round( lang:formatDate( 'z' ) - lang:formatDate( 'z', data.date ) + 365 * ( lang:formatDate( 'Y' ) - lang:formatDate( 'Y', data.date ) + 3 ) / 7, 0 ) if lastUpdate == 1 then cats = cats .. ''       elseif lastUpdate >= 2 and lastUpdate <= 4 then cats = cats .. ''       elseif lastUpdate > 4 then cats = cats .. ''       end if not data.limit then cats = cats .. ''       end if not data.category then cats = cats .. ''       end

]=]   local help = mw.html.create( 'div' ) :attr( 'id', 'gemw_guide' ) :css( {           padding = '5px 10px',            color = '#000',            border = '1px solid #6b5331',            background = '#fff3c3'        } ) :wikitext( 'If you need assistance on editing this page, or trying to understand how these Exchange pages work, please add a comment to Talk:Grand Exchange Market Watch.' )

return tostring( help ) .. tostring( tbl ) end

-- -- For accessing data through #invoke -- function p.view( frame )

local fargs = frame.args local pargs = frame:getParent.args local item = mw.ustring.gsub( pargs[1], '^%s*(%S%s+)%s*$', '%1' ) -- view and format can be set along with #invoke or through template arguments -- item (above) can only be set through template arguments local view = fargs.View or fargs.view or pargs.View or pargs.view or 'price' local format = yesno( fargs.format or pargs.format )

if not item then return ' Error: Item not specified ' end

view = mw.ustring.lower( view )

local ret_views = { price = true, limit = true, value = true }

if ret_views[view] then local ret = load( item )[view]

if format then ret = addcommas( ret ) end

return tostring( ret ) end

if view == 'icon' then return p._icon( item ) end if view == 'diff' then return p._diff( item, format ) end if view == 'table' then return p._table( item ) end if view == 'data' then return p._data( item ) end if view == 'page' then return p._page( item, pargs.uses ) end

end

return p