Module:Version: Difference between revisions

From Path of Exile Wiki
Jump to navigation Jump to search
>Illviljan
mNo edit summary
>Illviljan
(Adding support for items in timeline lists.)
Line 1: Line 1:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local util = require('Module:Util')
local m_util = require('Module:Util')
local f_item_link = require('Module:Item link').item_link
local cargo = mw.ext.cargo
local cargo = mw.ext.cargo


Line 28: Line 29:
function h.cargo_query(tpl_args)
function h.cargo_query(tpl_args)
     --[[
     --[[
     Returns a Cargo query of all the results, even if there are more
     Returns a Cargo query of all the results.
    results than the maximum query limit. It also adds popular fields.  
      
      
     tpl_args should include these keys:
     tpl_args should include these keys:
Line 38: Line 38:
     ]]
     ]]
      
      
     local tables = util.string.split(tpl_args.tables, ', ')
     local tables = m_util.string.split(tpl_args.tables, ', ')
     local fields = util.string.split(tpl_args.fields, ', ')
     local fields = m_util.string.split(tpl_args.fields, ', ')
      
      
     -- Parse query arguments
     -- Parse query arguments
    local query_limit = 5000
     local query = {
     local query = {
        -- Workaround: fix duplicates
        groupBy='versions._pageID',
        limit = query_limit,
        offset = 0,
     }
     }
     for key, value in pairs(tpl_args) do  
     for key, value in pairs(tpl_args) do  
Line 55: Line 50:
     end
     end
      
      
    -- Add commonly used fields:
     -- Query cargo rows:
    fields_base = {
     local results = m_util.cargo.query(tables, fields, query, args)
        '_pageID',
        '_pageName'
    }
    for _, tbl in ipairs(tables) do
        for _, fld in ipairs(fields_base) do
            fields[#fields+1] = string.format('%s.%s', tbl, fld)
        end
    end
   
     -- Query cargo table. If there are too many results then repeat,
    -- offset, query and add the remaining results:
     results = {}     
    repeat
local result = mw.ext.cargo.query(
            table.concat(tables, ', '),
            table.concat(fields, ', '),
            query
        )
query.offset = query.offset + #result
for _,v in ipairs(result) do
results[#results + 1] = v
end
until #result < query_limit
      
      
     return results
     return results
end
end




Line 96: Line 66:
         return value
         return value
     else
     else
         return util.cast.version(value, {return_type='string'})
         return m_util.cast.version(value, {return_type='string'})
     end
     end
end
end
Line 162: Line 132:
}
}


p.table_versions = util.cargo.declare_factory{data=version_map}
p.table_versions = m_util.cargo.declare_factory{data=version_map}


p.version = function(frame)
p.version = function(frame)
    local args = getArgs(frame, {parentFirst = true})
    local frame = util.misc.get_frame(frame)
     --[[
     --[[
    This function creates a infobox and stores the data in a cargo table.
   
    Examples:
     = p.version({
     = p.version({
         before = '2.4.1a',
         before = '2.4.1a',
Line 176: Line 146:
     })
     })
     --]]
     --]]
    local args = getArgs(frame, {parentFirst = true})
    local frame = m_util.misc.get_frame(frame)
     for k, data in pairs(version_map.fields) do
     for k, data in pairs(version_map.fields) do
         if data.validate ~= nil then
         if data.validate ~= nil then
Line 186: Line 160:
     end
     end
      
      
     local version_parts = util.cast.version(args.patch, {return_type='table'})
     local version_parts = m_util.cast.version(args.patch, {return_type='table'})
     args.major_part = tonumber(version_parts[1])
     args.major_part = tonumber(version_parts[1])
     args.minor_part = tonumber(version_parts[2])
     args.minor_part = tonumber(version_parts[2])
Line 227: Line 201:
     end
     end
      
      
     util.cargo.store(frame, _properties)
     m_util.cargo.store(frame, _properties)




Line 260: Line 234:
     }
     }


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


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


     local props = {
     local props = {
Line 285: Line 259:
     --mw.logObject(props)
     --mw.logObject(props)


     return util.cargo.declare(frame, props)
     return m_util.cargo.declare(frame, props)
end
end


Line 295: Line 269:
p.version_history_list = function(frame)
p.version_history_list = function(frame)
     local args = getArgs(frame, {parentFirst = true})
     local args = getArgs(frame, {parentFirst = true})
     local frame = util.misc.get_frame(frame)
     local frame = m_util.misc.get_frame(frame)


     -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
     -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
Line 319: Line 293:
     local results = {}
     local results = {}
     repeat
     repeat
         local result = util.smw.query(query, frame)
         local result = m_util.smw.query(query, frame)
         local length = #result
         local length = #result
         query.offset = query.offset + length
         query.offset = query.offset + length
Line 336: Line 310:
         local version = result['Is version']
         local version = result['Is version']


         local v = util.cast.version(result['Is version'])
         local v = m_util.cast.version(result['Is version'])
         local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it
         local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it


Line 365: Line 339:
p.version_history_list_2 = function(frame)
p.version_history_list_2 = function(frame)
     local args = getArgs(frame, {parentFirst = true})
     local args = getArgs(frame, {parentFirst = true})
     local frame = util.misc.get_frame(frame)
     local frame = m_util.misc.get_frame(frame)


     -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
     -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
Line 393: Line 367:
     local results = {}
     local results = {}
     repeat
     repeat
         local result = util.smw.query(query, frame)
         local result = m_util.smw.query(query, frame)
         local length = #result
         local length = #result
         query.offset = query.offset + length
         query.offset = query.offset + length
Line 439: Line 413:
function p.timeline(frame)  
function p.timeline(frame)  
     --[[  
     --[[  
     Adds a timeline when each result from the smw query was released in
     Add a timeline when versions or items were added to the game.
    the game.
TODO:
    * Support for different result formats ie table, plain text etc.
    * Make sure it works with items (and areas?) once item2 uses cargo.
      
      
     Examples:
     Examples:
Line 451: Line 421:
         q_where = 'versions.version <> ""',
         q_where = 'versions.version <> ""',
         q_orderBy = 'versions.version DESC, versions.release_date ASC'
         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,
     }
     }
      
      
     ]]
     ]]
      
      
     local tpl_args = getArgs(frame, {
    -- Get args:
        parentFirst = true
     local tpl_args = getArgs(frame, {parentFirst = true})
    })
     local frame = m_util.misc.get_frame(frame)
     local frame = util.misc.get_frame(frame)
   
     -- Query results:
     -- Query results
     local results = h.cargo_query(tpl_args)
     local results = h.cargo_query(tpl_args)
      
      
    -- Preallocate:
local out = {}
local out = {}
local last_main_version  
local last_main_version  
Line 468: Line 448:
     local current_version
     local current_version
     local result_list
     local result_list
 
   
    -- Loop through all the results from the query:
for i, result in ipairs(results) do  
for i, result in ipairs(results) do  
release_version = result[tpl_args.tables .. '.release_version']
release_version = result['versions.version']
if release_version == nil then
release_version = result[tpl_args.tables .. '.version']
end
local v = util.cast.version(release_version)
local v = m_util.cast.version(release_version)
local version_h2 = table.concat({v[1], v[2]}, '.')
local version_h2 = table.concat({v[1], v[2]}, '.')
       
if release_version ~= last_minor_version then
if release_version ~= last_minor_version then
           
if version_h2 ~= last_main_version then  
if version_h2 ~= last_main_version then  
if current_version ~= nil then
if current_version ~= nil then
Line 496: Line 475:
:wikitext(string.format(
:wikitext(string.format(
                         '%s - [[%s %s]]',  
                         '%s - [[%s %s]]',  
                         result[tpl_args.tables .. '.release_date'],  
                         result['versions.release_date'],  
                         i18n.timeline.version,  
                         i18n.timeline.version,  
                         release_version,  
                         release_version,  
                         result[tpl_args.tables .. '.release_version'])
                         result['versions.version'])
                     )
                     )
result_list = current_version:tag('ol')
result_list = current_version:tag('ol')
end  
end  
         -- If it's not a version page then add another list with the
             
         -- results.
         -- If the result has an item class, then add another list with  
if result[tpl_args.tables .. 'version'] == '' then
         -- the results.
            -- If the result has an item class then the il-format can
        if result['items.class'] ~= nil then  
            -- be used.
            result_list:tag('li'):wikitext(string.format('%s',  
if  result[tpl_args.tables .. 'item_class'] ~= '' then  
                f_item_link{
result_list:tag('li'):wikitext(string.format('%s',  
                    page=result['items._pageName'],
                    f_item_link{page=result[tpl_args.tables .. '._pageName']}
                    name=result['items.name'],
                     )
                    inventory_icon=result['items.inventory_icon'] or '',
                    html=result['items.html'] or '',
                    skip_query=true
                     }
                 )
                 )
else
            )
result_list:tag('li'):wikitext(string.format('[[%s]]',
        end
                    result[tpl_args.tables .. '._pageName']
                    )
                )
               
end
end
          
          
         -- Save the last list
         -- Save the last list:
if (i == #results) and (current_version ~= nil) then  
if (i == #results) and (current_version ~= nil) then  
out[#out + 1] = tostring(current_version)
out[#out + 1] = tostring(current_version)
Line 532: Line 508:
end
end
-- Categories
-- Add categories:
     local cats = {
     local cats = {
'Timelines',
'Timelines',
     }
     }
return table.concat(out, '\n') .. util.misc.add_category(cats)
return table.concat(out, '\n') .. m_util.misc.add_category(cats)
end
end



Revision as of 20:17, 16 January 2018

Module documentation[view] [edit] [history] [purge]


Templates

local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
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 date_format = 'd F Y H:i:s'

local i18n = {
    timeline = {
        version = 'Version',
    },
}

-- ---------------------------------------------------------------------
-- Helper
-- ---------------------------------------------------------------------

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_util.cargo.query(tables, fields, query, args)
    
    return results
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 = mw_language:formatDate(date_format, date)
            if args.key == 'before' then
                return string_format('← [[Version %s|%s]]<br>%s', version, version, date)
            elseif args.key == 'after' then
                return string_format('[[Version %s|%s]] →<br>%s', 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 = 'before',
            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_util.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.1a',
        patch = '2.4.1b',
        patchdate = 'October 18, 2016',
        after = '2.4.2',
    })
    --]]

    local 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
            args[k] = data.validate(args[k])
        end
    end

    if not args.patch or not args.patchdate then
        error('Arguments "patch" and "patchdate" are required')
    end
    
    local version_parts = m_util.cast.version(args.patch, {return_type='table'})
    args.major_part = tonumber(version_parts[1])
    args.minor_part = tonumber(version_parts[2])
    args.patch_part = tonumber(version_parts[3])
    if version_parts[4] then
        args.revision_part = version_parts[4]
    end

    -- Check and set 'before' and 'after' args
    local edge_names = {'before', 'after'}
    for _, key in ipairs(edge_names) do
        local v = 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
                args[string.format('%s_date', key)] = results[1]['versions.release_date']
            elseif #results > 1 then
                error('There are multiple versions with the same name')
            end
        end
    end


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


    -- Generate output
    -- todo: rework it somehow
    local release_date = mw_language:formatDate(date_format, args.patchdate)

    local tbl = mw_html.create('table')
    tbl
        :addClass('wikitable successionbox')
        :tag('tr')
            :tag('th')
                :attr('colspan', 3)
                :wikitext('[[Version history|Version History]]')
                :done()
            :done()
        :tag('tr')
            :tag('td')
                :cssText('width: 30%')
                :wikitext(version_map.fields.before.show(args, frame))
                :done()
            :tag('td')
                :cssText('width: 40%')
                :wikitext(string_format('<b>%s</b><br>%s', args.patch, release_date))
                :done()
            :tag('td')
                :cssText('width: 30%')
                :wikitext(version_map.fields.after.show(args, frame))

    local cats = {
        '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_util.cargo.declare(frame, props)
end

-----

------------------------------------------------------------------------------------------------------
-- Template: Version history list

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

    -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
    -- = p.version_history_list({conditions='[[Is version::~0.9*]]'})
    -- = p.version_history_list({conditions='[[Is version::~0.5*]]'})

    if args.conditions then
        args.conditions = args.conditions .. '[[Has release date::+]]'
    else
        args.conditions = '[[Is version::+]][[Has release date::+]]'
    end

    local query = {
        args.conditions,
        '?Is version',
        '?Has release date',
        sort = 'Has release date, Is version',
        order = 'desc, desc',
        link = 'none',
        offset = 0,
    }

    local results = {}
    repeat
        local result = m_util.smw.query(query, frame)
        local length = #result
        query.offset = query.offset + length

        for i = 1, length do
            results[#results + 1] = result[i]
        end
    until length < 1000

    local out = {}
    local last_minor_version, current_list

    for i = 1, #results do
        local result = results[i]
        local date = result['Has release date']
        local version = result['Is version']

        local v = m_util.cast.version(result['Is version'])
        local minor_version = table_concat({v[1], v[2], v[3]}, '.') -- todo: rework it

        if minor_version ~= last_minor_version then
            if current_list ~= nil then
                out[#out + 1] = tostring(current_list)
            end

            out[#out + 1] = string_format('===Version %s===', minor_version)
            current_list = mw_html.create('ul')
        end

        current_list:tag('li'):wikitext(string_format('%s &ndash; [[Version %s]]', date, version))

        -- save the last list
        if i == #results and current_list ~= nil then
            out[#out + 1] = tostring(current_list)
        end

        last_minor_version = minor_version
    end

    return table_concat(out, '\n')
end

-----

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

    -- = p.version_history_list({conditions='[[Is version::~1*||~2*]]'})
    -- = p.version_history_list({conditions='[[Is version::~0.9*]]'})
    -- = p.version_history_list({conditions='[[Is version::~0.5*]]'})

    if args.conditions then
        args.conditions = args.conditions .. '[[Has release date::+]]'
    else
        args.conditions = '[[Is version::+]] [[Has release date::+]]'
    end

    local query = {
        args.conditions,
        '?Is version',
        '?Has release date',
        '?Has major version part',
        '?Has minor version part',
        '?Has patch version part',
--        '?Has revision version part',
        sort = 'Has major version part, Has minor version part, Has patch version part, Is version',
        order = 'desc, desc, desc, desc',
        link = 'none',
        offset = 0,
    }

    local results = {}
    repeat
        local result = m_util.smw.query(query, frame)
        local length = #result
        query.offset = query.offset + length

        for i = 1, length do
            results[#results + 1] = result[i]
        end
    until length < 1000

--    mw.logObject(results)

    local out = {}
    local last_minor_version, current_list

    for i = 1, #results do
        local result = results[i]
        local date = result['Has release date']
        local version = result['Is version']

        local patch_version = string_format('%s.%s.%s',
            result['Has major version part'], result['Has minor version part'], result['Has patch version part'])

        if patch_version ~= last_minor_version then
            if current_list ~= nil then
                out[#out + 1] = tostring(current_list)
            end

            out[#out + 1] = string_format('===Version %s===', patch_version)
            current_list = mw_html.create('ul')
        end

        current_list:tag('li'):wikitext(string_format('%s &ndash; [[Version %s]]', date, version))

        -- save the last list
        if i == #results and current_list ~= nil then
            out[#out + 1] = tostring(current_list)
        end

        last_minor_version = patch_version
    end

    return table_concat(out, '\n')
end

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]]', 
                        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
                    }
                )
            )
        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 = {
		'Timelines',
    }
	
	return table.concat(out, '\n') .. m_util.misc.add_category(cats)
end

-----

return p