Path of Exile Wiki

Please consider helping keep the wiki up to date. Check the to-do list of updates needed for version 3.14.0.

Game data exports will becoming later as the technical changes in addition to regular changes take some more time.

READ MORE

Path of Exile Wiki
Advertisement
Module documentation[view] [edit] [history] [purge]

Templates

local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local f_item_link = require('Module:Item link').item_link
local cargo = mw.ext.cargo

local string_format = string.format
local table_concat = table.concat

local mw_html = mw.html

local mw_language = mw.getLanguage('en')

local p = {}

local i18n = {
    categories = {
        versions = 'Versions',
        timelines = 'Timelines',
    },
    
    show_date = {
        before = '← [[Version %s|%s]]<br>%s',
        after = '[[Version %s|%s]] →<br>%s',
    },
    version = {
        required_args = 'Arguments "patch" and "patchdate" are required',
        multiple_versions = 'There are multiple versions with the same name',
        header = '[[Version history|Version History]]',
    },
    timeline = {
        version = 'Version',
    },
}

-- ---------------------------------------------------------------------
-- Helper functions
-- ---------------------------------------------------------------------

h = {}

function h.cargo_query(tpl_args)
    --[[
    Returns a Cargo query of all the results.
    
    tpl_args should include these keys:
    tpl_args.tables
    tpl_args.fields
    tpl_args.q_*
    
    ]]
    
    local tables = m_util.string.split(tpl_args.tables, ', ')
    local fields = m_util.string.split(tpl_args.fields, ', ')
    
    -- Parse query arguments
    local query = {
    }
    for key, value in pairs(tpl_args) do 
        if string.sub(key, 0, 2) == 'q_' then
            query[string.sub(key, 3)] = value
        end
    end
    
    -- Query cargo rows:
    local results = m_cargo.query(tables, fields, query, args)
    
    return results
end

function h.date(value, args)
    --[[
    Format dates in correct and useable form.
    
    Parameters
    ----------
    value : String, required
        Date
    args : Table
        Table with extra formatting args.
    
    ]]
    
    local args = args or {}
    
    -- List of allowed extra arguments:
    local arg_list = {
        format = {
            default = 'F j, Y H:i:s',
            cargo   = 'Y-m-d H:i:s',
            no_time = 'F j, Y',
        },
    }
    
    local date_format = arg_list['format']['default']
    local timestamp = mw_language:formatDate(date_format, value)
    
    -- If the time is 00:00:00 then assume that the time isn't defined:
    if mw_language:formatDate('H:i:s', timestamp) == '00:00:00' then 
        date_format = arg_list['format']['no_time']
    end
    
    -- Add the extra arguments:
    for i,v in pairs(args) do
        if i == 'format' then
            date_format = arg_list[i][v]            
        end
    end
    
    -- Return the final timestamp format:
    local out
    if value ~= nil then
        out = mw_language:formatDate(date_format, timestamp)
    end
    
    return out
end


-- ---------------------------------------------------------------------
-- Template: Version
-- ---------------------------------------------------------------------


function validate_version(value)
    if value == nil then
        return value
    else
        return m_util.cast.version(value, {return_type='string'})
    end
end

function show_date(args)
    return function(tpl_args, frame)
        local version = tpl_args[args.key]
        local date = tpl_args[string.format('%s_date', args.key)]
        if version and date then
            date = h.date(date) or ''
            if args.key == 'before' then
                return string_format(i18n.show_date.before, version, version, date)
            elseif args.key == 'after' then
                return string_format(i18n.show_date.after, version, version, date)
            end
        else
            return ''
        end
    end
end


local version_map = {
    table = 'versions',
    fields = {
        patch = {
            field = 'version',
            type = 'String',
            validate = validate_version,
        },
        patchdate = {
            field = 'release_date',
            type = 'Datetime',
            validate = tostring,
        },
        major_part = {
            field = 'major_part',
            type = 'Integer',
        },
        minor_part = {
            field = 'minor_part',
            type = 'Integer',
        },
        patch_part = {
            field = 'patch_part',
            type = 'Integer',
        },
        revision_part = {
            field = 'revision_part',
            type = 'String',
        },
        before = {
            field = 'previous',
            type = 'String',
            validate = validate_version,
            show = show_date{key='before'},
        },
        after = {
            field = 'after',
            type = 'String',
            validate = validate_version,
            show = show_date{key='after'},
        },
    },
}

p.table_versions = m_cargo.declare_factory{data=version_map}

p.version = function(frame)
    --[[
    This function creates a infobox and stores the data in a cargo table.
    
    Examples:
    = p.version{
        before = '2.4.1',
        patch = '2.4.1b',
        patchdate = 'October 18, 2016',
        after = '2.4.2',
    }
    --]]

    local tpl_args = getArgs(frame, {parentFirst = true})
    local frame = m_util.misc.get_frame(frame)

    for k, data in pairs(version_map.fields) do
        if data.validate ~= nil then
            tpl_args[k] = data.validate(tpl_args[k])
        end
    end
    
    -- Workaround for patchdate returning the string 'nil' when it's nil, 
    -- not sure if that's intentional:
    if not tpl_args.patch or not tpl_args.patchdate or tpl_args.patchdate == 'nil' then
        error(i18n.version.required_args)
    end
    
    local version_parts = m_util.cast.version(tpl_args.patch, {return_type='table'})
    tpl_args.major_part = tonumber(version_parts[1])
    tpl_args.minor_part = tonumber(version_parts[2])
    tpl_args.patch_part = tonumber(version_parts[3])
    if version_parts[4] then
        tpl_args.revision_part = version_parts[4]
    end

    -- Check and set 'before' and 'after' tpl_args
    local edge_names = {'before', 'after'}
    for _, key in ipairs(edge_names) do
        local v = tpl_args[key]
        if v then
            local results = cargo.query(
                'versions', 
                'versions.release_date', 
                {
                    where=string.format('version="%s"', v),
                    -- Cargo bug work around
                    groupBy='versions._pageID',
                }
            )
            if #results == 1 then
                tpl_args[string.format('%s_date', key)] = results[1]['versions.release_date']
            elseif #results > 1 then
                error(i18n.version.multiple_versions)
            end
        end
    end

    
    -- Set Cargo data
    local _properties = {
        _table = version_map.table,
    }
    for key, data in pairs(version_map.fields) do
        if tpl_args[key] ~= nil then
            _properties[data.field] = tpl_args[key]
       end
    end
    
    m_cargo.store(frame, _properties)

    -- Generate output
    local release_date = h.date(tpl_args.patchdate)
    local tbl = mw_html.create('table')
    tbl
        :addClass('wikitable successionbox')
        :tag('tr')
            :tag('th')
                :attr('colspan', 3)
                :wikitext(i18n.version.header)
                :done()
            :done()
        :tag('tr')
            :tag('td')
                :cssText('width: 30%')
                :wikitext(version_map.fields.before.show(tpl_args, frame))
                :done()
            :tag('td')
                :cssText('width: 40%')
                :wikitext(string_format('<b>%s</b><br>%s', tpl_args.patch, release_date))
                :done()
            :tag('td')
                :cssText('width: 30%')
                :wikitext(version_map.fields.after.show(tpl_args, frame))

    local cats = {
        i18n.categories.versions,
    }

    return tostring(tbl) .. m_util.misc.add_category(cats)
end

-----

p.version_declare = function(frame)
    -- local args = getArgs(frame, {parentFirst = true})
    local frame = m_util.misc.get_frame(frame)

    local props = {
        _table = 'Versions',
    }

--    for i, _ in pairs(version_map) do
--        props[i] = _.datatype
--    end

    for i = 1, #temp_map_for_cargo do
        local v = temp_map_for_cargo[i]
        local _ = version_map[v]
        props[v] = _.datatype
    end

    --mw.logObject(props)

    return m_cargo.declare(frame, props)
end


-- ---------------------------------------------------------------------
-- Timeline 
-- ---------------------------------------------------------------------


function p.timeline(frame) 
    --[[ 
    Add a timeline when versions or items were added to the game.
    
    Examples:
    = p.timeline{
        tables = 'versions',
        fields = 'versions.version, versions.release_date',
        q_where = 'versions.version <> ""',
        q_orderBy = 'versions.version DESC, versions.release_date ASC'
    }
    
    = p.timeline{
        tables = 'versions, items',        
        fields = 'versions.version, versions.release_date, versions._pageName, items.class, items._pageName, items.name, items.release_version, items.inventory_icon, items.html',
        q_join = 'versions.version=items.release_version',
        q_where = 'versions.version IS NOT NULL AND items.release_version IS NOT NULL AND items.rarity = "Unique"',
        q_orderBy = 'versions.version DESC, versions.release_date ASC, items.name ASC',
        q_groupBy = 'versions._pageID, items.name',
        q_limit = 5000,
    }
    
    ]]
    
    
    -- Get args:
    local tpl_args = getArgs(frame, {parentFirst = true})
    local frame = m_util.misc.get_frame(frame)

    -- Query results:
    local results = h.cargo_query(tpl_args)
    
    -- Preallocate:
    local out = {}
    local last_main_version 
    local last_minor_version
    local current_version
    local result_list
    
    -- Loop through all the results from the query:
    for i, result in ipairs(results) do 
        release_version = result['versions.version']
        
        local v = m_util.cast.version(release_version)
        local version_h2 = table.concat({v[1], v[2]}, '.')
        
        if release_version ~= last_minor_version then
            
            if version_h2 ~= last_main_version then 
                if current_version ~= nil then
                    out[#out + 1] = tostring(current_version)
                end
                
                out[#out+1] = string.format(
                    '===%s %s===', 
                    i18n.timeline.version, 
                    table.concat({v[1], v[2], 0}, '.')
                ) 
                current_version = mw.html.create('ul')
            end
        
            current_version
                :tag('li')
                    :wikitext(string.format(
                        '%s - [[%s %s]]', 
                        h.date(result['versions.release_date']), 
                        i18n.timeline.version, 
                        release_version, 
                        result['versions.version'])
                    )
            result_list = current_version:tag('ol')
        end 
        
              
        -- If the result has an item class, then add another list with 
        -- the results.
        if result['items.class'] ~= nil then 
            -- result_list:tag('li'):wikitext(string.format('%s', 
                -- f_item_link{
                    -- page=result['items._pageName'], 
                    -- name=result['items.name'],
                    -- inventory_icon=result['items.inventory_icon'] or '', 
                    -- html=result['items.html'] or '', 
                    -- skip_query=true
                    -- }
                -- )
            -- )
            result_list:tag('li'):wikitext(string.format('[[%s]]', 
                result['items._pageName']
                )
            )
        end
        
        -- Save the last list:
        if (i == #results) and (current_version ~= nil) then 
            out[#out + 1] = tostring(current_version)
        end
        
        last_main_version = version_h2
        last_minor_version = release_version
    end
    
    -- Add categories:
    local cats = {
        i18n.categories.timelines,
    }
    
    return table.concat(out, '\n') .. m_util.misc.add_category(cats)
end

-----

return p