Module:Toolinfo

From Wikimedia Commons, the free media repository
Jump to navigation Jump to search
Lua

CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules


Usage

[edit]

{{#invoke:Toolinfo|function_name}}


Code

-----
-- Generate and process toolinfo.json data.
--
-- Toolhub and Hay's Directory use the toolinfo.json standard to document tools
-- used within the Wikimedia movement. This module is intended to support
-- creating templates which render nicely formatted information about a tool for
-- reading on-wiki while retaining well structured source values which can be
-- converted into the toolinfo.json format.
-----
local checkType = require( "libraryUtil" ).checkType
local find = mw.ustring.find
local ipairs = ipairs
local jsonDecode = mw.text.jsonDecode
local jsonEncode = mw.text.jsonEncode
local utils = require( "Module:Toolinfo/utils" )

local p = {}

--- Toolinfo keys that we reasonably expect to find.
local EXPECTED_KEYS = {
	"name",
	"title",
	"description",
	"url",
	"author",
	"repository",
	"subtitle",
	"openhub_id",
	"url_alternates",
	"bot_username",
	"deprecated",
	"replaced_by",
	"experimental",
	"for_wikis",
	"icon",
	"license",
	"sponsor",
	"available_ui_languages",
	"technology_used",
	"tool_type",
	"api_url",
	"developer_docs_url",
	"user_docs_url",
	"feedback_url",
	"privacy_policy_url",
	"translate_url",
	"bugtracker_url",
	"_language",
}

--- Array type toolinfo.json keys (as a set)
local IS_ARRAY = {
	[ "author" ] = true,
	[ "url_alternates" ] = true,
	[ "for_wikis" ] = true,
	[ "sponsor" ] = true,
	[ "available_ui_languages" ] = true,
	[ "technology_used" ] = true,
	[ "developer_docs_url" ] = true,
	[ "user_docs_url" ] = true,
	[ "feedback_url" ] = true,
	[ "privacy_policy_url" ] = true,
}

--- Non-string valued toolinfo.json keys (as a set)
local IS_TYPED = {
	[ "author" ] = true,
	[ "deprecated" ] = true,
	[ "experimental" ] = true,
	[ "url_alternates" ] = true,
	[ "developer_docs_url" ] = true,
	[ "user_docs_url" ] = true,
	[ "feedback_url" ] = true,
	[ "privacy_policy_url" ] = true,
	[ "deprecated" ] = true,
	[ "experimental" ] = true,
}

--- Coerce value to typed data.
-- @string name - Toolinfo field name
-- @param value - Toolinfo field value
-- @return mixed String, table, boolean, or nil
local function castValueToType( name, value )
	if IS_TYPED[ name ] and type( value ) == "string" and value ~= "" then
		-- Cast to proper type by decoding as JSON.
		value = jsonDecode( value )
	end
	if type( value ) == "string" and not not find( value, "^%s*$" ) then
		-- Whitespace only and empty strings become nil
		value = nil
	end
	return value
end

--- Build a table from consecutive `name_N` values found in an input table.
--
-- Looks for keys name_1, name_2, ..., name_1000 in input table and returns the
-- values found in a table with integer indexes (an array).
-- @table input - table to collect values from
-- @string name - base name of keys to collect
-- @return table of found values
local function buildTableFromConsecutiveValues( input, name )
	checkType( "buildTableFromConsecutiveValues", 1, input, "table", false )
	checkType( "buildTableFromConsecutiveValues", 2, name, "string", false )
	local tbl = {}
	for i = 1, 1000 do
		local key = name .. "_" .. i
		local val = castValueToType( name, input[ key ] )
		if val ~= nil then
			tbl[ i ] = val
		else
			break
		end
	end
	return tbl
end

--- Build a toolinfo.json record from a table of arguments.
-- @table args
-- @return table
local function buildToolinfoTable( args )
	checkType( "buildToolinfoTable", 1, args, "table", false )
	local info = {}
	for _, key in ipairs( EXPECTED_KEYS ) do
		if IS_ARRAY[ key ] then
			-- Make table from key_N values
			local data = buildTableFromConsecutiveValues( args, key )
			if not utils.tbl_empty( data ) then
				info[ key ] = data
			end
		elseif args[ key ] then
			info[ key ] = castValueToType( key, args[ key ] )
		end
	end
	return info
end

--- Convert frame.args to toolinfo.json.
-- Used by [[Template:Toolinfo]]
-- @param frame - Frame object
-- @return string
function p.argsToToolinfoJSON( frame )
	checkType( "argsToToolinfoJSON", 1, frame, "table", false )
	local args = utils.getFrameOrParentArgs( frame )
	local info = buildToolinfoTable( args )
	return jsonEncode( info, mw.text.JSON_PRETTY )
end

--- Convert frame.args to JSON.
-- Used by [[Template:Toolinfo/Person]] and [[Template:Toolinfo/Url]].
-- @param frame - Frame object
-- @return string
function p.argsToJSON( frame )
	checkType( "argsToJSON", 1, frame, "table", false )
	local args = utils.getFrameOrParentArgs( frame )
	return jsonEncode( args )
end

return p