Modul:CommodityTable

Aus Steel Beasts Wiki

Die Dokumentation für dieses Modul kann unter Modul:CommodityTable/Doku erstellt werden

require( 'strict' )

local CommodityTable = {}

local metatable = {}
local methodtable = {}
local common = require('Module:Common')
local commodity = require('Module:Commodity')
local TNT = require( 'Module:Translate' ):new()

metatable.__index = methodtable

local CURRENT_VERSION = '3.17.4'

--- Creates a table with booleans indicating if the column shall be visible
--- @param args table
--- @return table
local function makeVisibleColumnsFlags( args )
    local possibleColumns = {
        'Händler',
        'Ort',
        'Name',
        'Preis',
        'Kaufbar',
        'Verkaufbar',
        'Mietbar',
        'Maximalbestand',
        'Aufschlag / Rabatt',
        'Kategorie',
        'Spielversion',
    }

    local toCheck = args

    if args[ 'Spalten' ] ~= nil then
        local split = mw.text.split( args[ 'Spalten' ], ',', true )

        if #split > 0 then
            toCheck = {}
            for _, column in pairs( possibleColumns ) do
                toCheck[ 'Zeige ' .. column ] = 'Nein'
            end

            for _, column in pairs( split ) do
                toCheck[ 'Zeige ' .. mw.text.trim( column ) ] = 'Ja'
            end
        end
    end

    local flags = {}

    for _, column in pairs( possibleColumns ) do
        local key = 'Zeige ' .. column

        if toCheck[ key ] ~= nil and string.lower( tostring( toCheck[ key ] ) ) == 'nein' then
            flags[ column ] = false
        else
            flags[ column ] = true
        end
    end

    return flags
end

--- Creates the smw query restrictions form args
--- @param arg table
--- @return table
local function makeQueryRestrictions( arg )
    local restrictions = {
    	'[[Ort::!Levski]]'
    }
    local possibleRestrictions = {
        'Händler',
        'Ort',
        'Name',
        'Typ',
        'Preis',
        'Kaufbar',
        'Verkaufbar',
        'Mietbar',
        'Maximalbestand',
        'Preisoffset',
        'Kategorie',
        'Spielversion',
    }

    if arg == nil then
        return nil
    end

	if arg[ 'Query' ] ~= nil then
		table.insert( restrictions, arg[ 'Query' ] )
	else
	    for _, restriction in pairs( possibleRestrictions ) do
	        if arg[ restriction ] ~= nil then
	            table.insert( restrictions, string.format( '[[%s::%s]]', restriction, arg[ restriction ] ) )
	        end
	    end
    end

    if #restrictions == 0 then
        error( 'Für die Abfrage wird mindestens eine Bedingung benötigt.' )
    end

    return table.concat( restrictions )
end

local function typeToText( itemType )
	local function is(substr)
		return itemType == substr or mw.ustring.find( itemType, substr, 0, true ) ~= nil
	end

	if is('Char_Armor') then
		return 'Rüstung'
	elseif is('Char_Clothing') then
		return 'Kleidung'
	elseif is('Cooler') then
		return 'Kühler'
	elseif is('FPS_Consumable') then
		return 'Verbrauchsmaterial' --TODO
	elseif is('MiningModifier') then
		return 'Bergbau-Modifikator'
	elseif is('Missile') then
		return 'Rakete'
	elseif is('MissileLauncher') then
		return 'Raketenwerfer'
	elseif is('Paints') then
		return 'Farbe'
	elseif is('PowerPlant') then
		return 'Kraftwerk'
	elseif is('QuantumDrive') then
		return 'Quantenantrieb'
	elseif is('Shield') then
		return 'Schildgenerator'
	elseif is('Turret') then
		return 'Turm'
	elseif is('Unknown Type') then
		return 'Erz' --TODO!!!
	elseif is('WeaponAttachment') then
		return 'Waffenaufsatz'
	elseif is('WeaponGun') then
		return 'Schiffswaffe'
	elseif is('WeaponPersonal') then
		return 'Waffe'
	elseif is('WeaponMining') then
		return 'Bergbaulaser'
	end

    return itemType
end

--- Query the smw store for data
--- @return table
function methodtable.getSmwData( self )
    local queryParts = {
        makeQueryRestrictions( self.args ),
        --'[[Spielversion::' .. CURRENT_VERSION .. ']]',
        '?Inventar#-=inventory',
        '?Maximalbestand#-=max_inventory',
        '?Name=name',
        '?Händler=merchant',
        '?Ort=position',
        '?Preis#-p2=price',
        '?Preis#-n=price_raw',
        '?Preisoffset#-=offset',
        '?Typ=type',
        '+lang=de',
        '?Kaufbar#-=buyable',
        '?Verkaufbar#-=sellable',
        '?Mietbar#-=rentable',
        '?Spielversion#-=version',
        'mainlabel=-'
    }

    if self.args[ 'Limit' ] ~= nil then
        table.insert( queryParts, string.format( 'limit=%s', self.args[ 'Limit' ] ) )
    end
    
    if self.args[ 'Sortierung' ] ~= nil then
    	table.insert( queryParts, string.format( 'sort=%s', self.args[ 'Sortierung' ] ) )
	end

    return mw.smw.ask( queryParts ) or {}
end

--- Add rows to the table
---
--- @param itemTable table
--- @return table
function methodtable.addRows( self, itemTable )
    local data = self:getSmwData()
    local currentRow = 1

    local tableWidth = 0
    for _, visible in pairs( self.flags ) do
        if visible == true then
            tableWidth = tableWidth + 1
        end
    end

    if #data == 0 then
        return itemTable
                :tag( 'tr')
                    :tag( 'td' )
                        :attr( 'colspan', tableWidth )
                        :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'msg_no_entries' ) )
                    :done()
                :done()
    end

    for _, item in ipairs( data ) do
        local trClass = 'row-odd'
        if currentRow % 2 == 0 then
            trClass = 'row-even'
        end

        currentRow = currentRow + 1

        itemTable = itemTable:tag( 'tr' )
            :addClass( trClass )

        if self.flags[ 'Händler' ] == true then
            itemTable = itemTable:tag( 'td' )
                 :wikitext( item.merchant )
                 :done()
        end

        if self.flags[ 'Ort' ] == true then
            itemTable = itemTable:tag( 'td' )
                 :wikitext( item.position )
                 :done()
        end

        if self.flags[ 'Name' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( item.name )
                     :done()
        end

        if self.flags[ 'Preis' ] == true then
        	if type( item.price ) == 'table' then
        		item.price = item.price[ 1 ]
        	end

        	if type( item.price_raw ) == 'table' then
        		item.price_raw = item.price_raw[ 1 ]
        	end

            itemTable = itemTable:tag( 'td' )
        			 :attr('data-sort-value', item.price_raw )
                     :wikitext( item.price )
                     :done()
        end

        if self.flags[ 'Kaufbar' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( common.booleanToText( item.buyable ) )
                     :done()
        end

        if self.flags[ 'Verkaufbar' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( common.booleanToText( item.sellable ) )
                     :done()
        end

        if self.flags[ 'Maximalbestand' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( item.max_inventory )
                     :done()
        end

        if self.flags[ 'Aufschlag / Rabatt' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( commodity.formatOffset( item.offset ) )
                     :done()
        end

        if self.flags[ 'Kategorie' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( typeToText( item.type or '' ) or item.type )
                     :done()
        end

        if self.flags[ 'Spielversion' ] == true then
            itemTable = itemTable:tag( 'td' )
                     :wikitext( item.version )
                     :done()
        end

        itemTable = itemTable:done()
    end

    return itemTable
end

--- Makes the html table
--- @return string
function methodtable.make( self )
    local table = mw.html.create( 'table' )
        :attr( 'class', 'wikitable broadtable sortable' )
        :attr( 'style', 'width: 100%')
            :tag( 'tr' )

    if self.flags[ 'Händler' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_merchant' ) )
             :done()
    end

    if self.flags[ 'Ort' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_location' ) )
             :done()
    end

    if self.flags[ 'Name' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_name' ) )
             :done()
    end

    if self.flags[ 'Preis' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_price' ) )
             :done()
    end

    if self.flags[ 'Kaufbar' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_buyable' ) )
             :done()
    end

    if self.flags[ 'Verkaufbar' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_sellable' ) )
             :done()
    end

    if self.flags[ 'Maximalbestand' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_maximum_stock' ) )
             :done()
    end

    if self.flags[ 'Aufschlag / Rabatt' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_premium_discount' ) )
             :done()
    end

    if self.flags[ 'Kategorie' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_category' ) )
             :done()
    end

    if self.flags[ 'Spielversion' ] == true then
        table = table:tag( 'th' )
             :wikitext( TNT.formatInLanguage( self.lang, 'Module:CommodityTable/i18n.json', 'lbl_game_version' ) )
             :done()
    end

    -- Ending </tr></thead>
    table = table:done():done()

    table = self:addRows( table ):done()

    return tostring( table:allDone() )
end

--- New Instance
--- @return table CommodityTable
function CommodityTable.new( self, frameArgs )
    local instance = {
        args = frameArgs,
        flags = makeVisibleColumnsFlags( frameArgs )
    }

    if instance.args[ 'Limit' ] == nil then
        instance.args[ 'Limit' ] = 50
    end

    setmetatable( instance, metatable )

    return instance
end

--- Entry for module calls
---
--- @return string
function CommodityTable.fromArgs( frame )
    local args = require( 'Module:Arguments' ).getArgs( frame )

    local instance = CommodityTable:new( args )
    instance.lang = require( 'Module:Template translation' )._getLanguageSubpage( mw.title.getCurrentTitle() )

    return instance:make()
end

return CommodityTable