Modul:Wikidata

Z Enviwiki
Skočit na navigaci Skočit na vyhledávání

Věci přenesené přes šablony z cs:wiki


require "Modul:No globals"

local p = {}

local lib = require "Modul:Wikidata/lib"
local i18n = mw.loadData("Modul:Wikidata/i18n")

local function getEntityFromId(id)
	return mw.wikibase.getEntityObject(id)
end

local function findEntity(options)
	local entity
	if options.entity and type(options.entity) == "table" then
		entity = options.entity
	end
	if not entity then
		if options.id then
			local id = options.id:upper()
			entity = getEntityFromId(id)
			if entity and entity.id ~= id then
				mw.log(id .. ' je přesměrování na ' .. entity.id)
			end
		else
			entity = getEntityFromId()
		end
	end
	if options.of then
		if entity then
			local prop = mw.ustring.upper(options.of)
			local Statements = entity:getBestStatements(prop)
			local Formatters = require 'Modul:Wikidata/Formatters'
			for _, statement in pairs(Statements) do
				if lib.IsSnakValue(statement.mainsnak) then
					if statement.mainsnak.datavalue.type ~= 'wikibase-entityid' then
						return error(lib.formatError('invalid-datatype', prop, statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
					end
					local id = Formatters.getRawValue(statement.mainsnak)
					entity = getEntityFromId(id)
					if entity and entity.id ~= id then
						mw.log(id .. ' je přesměrování na ' .. entity.id)
					end
					return entity
				end
			end
		end
		return nil
	end
	return entity
end

local function getSitelink(options)
	local options = lib.common.cleanArgs(options)

	local entity = findEntity(options)
	if not entity or not entity.sitelinks then
		return nil
	end

	local site = options.site or options[1]

	local sitelink = entity:getSitelink(site)
	if not sitelink then
		return nil
	end

	if options.pattern then
		sitelink = lib.formatFromPattern(sitelink, options.pattern)
	end
	if lib.IsOptionTrue(options, 'addclass') then
		sitelink = lib.addClass(sitelink)
	end
	return sitelink
end

local function formatStatement(statement, options)
	if not statement.type or statement.type ~= 'statement' then
		return error(lib.formatError('unknown-claim-type', statement.type))
	end
	local Filterers = require 'Modul:Wikidata/Filterers'
	local Formatters = require 'Modul:Wikidata/Formatters'

	local mainsnak, qualifiers, targetdata, references
	if not lib.IsOptionTrue(options, 'qualifiersOnly') then
		mainsnak = Formatters.getFormattedValue(statement.mainsnak, options)
	end
	if statement.qualifiers and options.showqualifier then
		local PropList = lib.textToTable(options.showqualifier)
		local Snaks = {}
		for _, property in pairs(PropList) do
			local Values = {}
			local property = mw.ustring.upper(property)
			local format_options = {
				autoformat = true,
				precision = 9,
				property = property,
			}
			if statement.qualifiers[property] then
				local Qualifiers = Filterers.filterQualifiers(statement.qualifiers[property], options)
				for _, snak in pairs(Qualifiers) do
					if lib.IsSnakValue(snak) then
						table.insert(Values, Formatters.getFormattedValue(snak, format_options))
					end
				end
			elseif property == "TIME" then
				local Data = {}
				for key, array in pairs(lib.props) do
					for _, prop in pairs(array) do
						if statement.qualifiers[prop] then
							for _, snak in pairs(statement.qualifiers[prop]) do
								if lib.IsSnakValue(snak) then
									Data[key] = Formatters.getRawValue(snak)
									break
								end
							end
						end
					end
				end
				local Date = require 'Modul:Wikidata/datum'
				if Data.point then
					table.insert(Values, Date.formatDateFromTimevalue(Data.point, format_options))
				elseif Data.begin or Data.ending then
					table.insert(Values, Date.formatDateRange(Data, format_options))
				end
			end
			if #Values > 0 then
				table.insert(Snaks, mw.text.listToText(Values))
			end
		end
		if #Snaks > 0 then
			qualifiers = table.concat(Snaks, '; ')
		end
	end
	if not qualifiers and options.showtargetdata then
		local entity
		if lib.IsSnakValue(statement.mainsnak) then
			if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
				entity = getEntityFromId(Formatters.getRawValue(statement.mainsnak))
			else
				return error(lib.formatError('invalid-datatype', statement.mainsnak.property, statement.mainsnak.datatype, 'wikibase-item/wikibase-property'))
			end
		end
		if entity then
			local PropList = lib.textToTable(options.showtargetdata)
			local options = {
				autoformat = true,
				date = options.targetdate,
				entity = entity,
				precision = 9,
				rank = (options.targetdate and 'valid') or 'best',
				sort = 'date'
			}
			local Snaks = {}
			for _, property in pairs(PropList) do
				local result
				if mw.ustring.lower(property) == 'time' then
					local Data = {}
					for key, array in pairs(lib.props) do
						for _, prop in pairs(array) do
							options.property = prop
							local Statements = Filterers.filterStatementsFromEntity(entity, options)
							for _, statement in pairs(Statements) do
								Data[key] = Formatters.getRawValue(statement.mainsnak)
								break
							end
						end
					end
					local Date = require 'Modul:Wikidata/datum'
					if Data.point then
						result = Date.formatDateFromTimevalue(Data.point, options)
					elseif Data.begin or Data.ending then
						result = Date.formatDateRange(Data, options)
					end
				else
					options.property = property
					result = p.formatStatementsFromLua(options)
				end
				if result then
					table.insert(Snaks, result)
				end
			end
			if #Snaks > 0 then
				targetdata = table.concat(Snaks, '; ')
			end
		end
	end
	if statement.references and lib.IsOptionTrue(options, 'showsource') then
		local Module = require 'Module:Wikidata/cite'
		references = Module.formatSource(statement.references, options)
	end

	if qualifiers or targetdata then
		if lib.IsOptionTrue(options, 'qualifiersOnly') then
			mainsnak = qualifiers or targetdata
		else
			if options.delimiter then
				mainsnak = mainsnak .. options.delimiter .. (qualifiers or targetdata)
			else
				mainsnak = mainsnak .. ' (' .. (qualifiers or targetdata) .. ')'
			end
		end
	end
	if references then
		mainsnak = mainsnak .. references
	end
	return mainsnak
end

local function formatStatements(options)
	local value = options.value
	if value then
		if value == '' and lib.IsOptionTrue(options, 'over') then
			value = nil
		end
		if value and not lib.IsOptionTrue(options, 'compare') then
			return value
		end
	end

	--Get entity
	options = lib.common.cleanArgs(options)
	local entity = findEntity(options)

	options.limit = tonumber(options.limit) --TODO default
	local add_more = false
	if not lib.IsOptionTrue(options, 'compare') then
		if options.limit and lib.IsOptionTrue(options, 'showmore') then
			options.limit = options.limit + 1
			add_more = true
		end
	end

	local Filterers = require 'Modul:Wikidata/Filterers'
	local Statements = Filterers.filterStatementsFromEntity(entity, options)

	options.property = mw.ustring.upper(options.property)
	if value then
		local compare = require 'Modul:Wikidata/compare'
		local marked, category = compare.compareValues(value, Statements, {
			catbase = options.catbase,
			property = options.of or options.property
		})
		if lib.IsOptionTrue(options, 'addclass') and marked then
			value = marked
		end
		if lib.IsOptionTrue(options, 'addcat') and category then
			value = value .. category
		end
		return value
	end

	if #Statements == 0 then return nil end
	if add_more then
		if #Statements == options.limit then
			table.remove(Statements)
		else
			add_more = false
		end
	end
	-- Format statements and concat them cleanly
	local formattedStatements = {}
	options.entity = entity
	for _, statement in pairs(Statements) do
		table.insert(formattedStatements, formatStatement(statement, options))
	end
	if add_more then
		table.insert(formattedStatements, mw.ustring.format(i18n["more-on-Wikidata"], entity.id, options.property))
	end
	value = mw.text.listToText(formattedStatements, options.separator, options.conjunction)
	if lib.IsOptionTrue(options, 'addlink') then
		value = value .. ' <sup class="wd-link">([[d:' .. entity.id .. '#' .. options.property .. '|e]])</sup>'
	end
	if lib.IsOptionTrue(options, 'addcat') then
		value = value .. lib.category('used-property', options.catbase or 'Vlastnost ' .. options.property)
	end
	if lib.IsOptionTrue(options, 'addclass') then
		value = lib.addWdClass(value)
	end
	return value
end

function p.dumpWikidataEntity( frame )
	local args = frame and frame.args or {}

	return mw.dumpObject( getEntityFromId( args.id or nil ) )
end

function p.getBadges( frame )
	local args = lib.common.cleanArgs((frame and frame.args) or {})
	local site = args.site
	if not site then
		return error(lib.formatError('param-not-provided', 'site'))
	end
	local entity = findEntity( args )
	local Badges = {}
	if entity and entity.sitelinks and entity.sitelinks[site] then
		local ItemFormatter = require 'Modul:Wikidata/item'
		for _, badge in pairs(entity.sitelinks[site].badges) do
			table.insert(Badges, ItemFormatter.formatEntityId(badge))
		end
	end
	return table.concat( Badges, ', ' )
end

function p.getLabel( frame )
	local args = lib.common.cleanArgs((frame and frame.args) or {})
	local lang = args.lang
	if not lang or lang == mw.language.getContentLanguage():getCode() then
		local label = mw.wikibase.label(args.id or nil)
		if label and lib.IsOptionTrue(args, 'addclass') then
			label = lib.addClass(label)
		end
		return label
	end
	local entity = findEntity( args )
	if entity and entity.labels and entity.labels[lang] then
		local label = entity.labels[lang].value
		if label and lib.IsOptionTrue(args, 'addclass') then
			label = lib.addClass(label)
		end
		return label
	end
	return nil
end

function p.getDescription( frame )
	local args = lib.common.cleanArgs((frame and frame.args) or {})
	local lang = args.lang
	if not lang or lang == mw.language.getContentLanguage():getCode() then
		local description = mw.wikibase.description(args.id or nil)
		if description and lib.IsOptionTrue(args, 'addclass') then
			description = lib.addClass(description)
		end
		return description 
	end
	local entity = findEntity( args )
	if entity and entity.descriptions and entity.descriptions[lang] then
		local description = entity.descriptions[lang].value
		if description and lib.IsOptionTrue(args, 'addclass') then
			description = lib.addClass(description)
		end
		return description 
	end
	return nil
end

function p.getAliases( frame )
	local args = lib.common.cleanArgs((frame and frame.args) or {})
	local lang = args.lang
	local entity = findEntity( args )
	if not lang then
		lang = mw.language.getContentLanguage():getCode()
	end
	if not entity or not entity.aliases or not entity.aliases[lang] then
		return nil
	end

	local limit = tonumber(args.limit)

	local Aliases = {}
	for i, alias in pairs( entity.aliases[lang] ) do
		if not limit or (limit and i <= limit) then
			table.insert( Aliases, alias.value )
		else break end
	end
	local list = mw.text.listToText(Aliases, args.separator, args.conjunction)
	if lib.IsOptionTrue(args, 'addclass') then
		list = lib.addClass(list)
	end
	return list
end

function p.getCount( frame )
	local args = lib.common.cleanArgs((frame and frame.args) or {})
	if not args.property then
		return error(lib.formatError('param-not-provided', 'property'))
	end

	local entity = findEntity( args )

	args.limit = nil
	local Statements = filterStatements(entity, args)

	return #Statements or 0
end

function p.getCurrentId()
	local entity = getEntityFromId()
	return entity and entity.id
end

function p.getSitelink( frame )
	return getSitelink( frame.args or {} )
end

function p.getSitelinkFromLua( options )
	return getSitelink( options or {} )
end

-- @deprecated
function p.filterStatementsFromLua(...)
	local Filterers = require 'Modul:Wikidata/Filterers'
	return Filterers.filterStatementsFromEntity(...)
end

function p.formatStatements(frame)
	local args = frame and frame.args or {}
	return formatStatements(frame.args)
end

function p.formatStatementsFromLua(options)
	return formatStatements(options)
end

local function getRawValue(options)
	local entity = findEntity(options)
	if options.showspecial == nil then -- may be false
		options.showspecial = true
	end
	if options.rank ~= 'best' and options.rank ~= 'preferred' then
		if options.sort then
			if not mw.ustring.match(options.sort, 'rank') then
				options.sort = 'rank,' .. options.sort
			end
		else
			options.sort = 'rank'
		end
	end

	local Filterers = require 'Modul:Wikidata/Filterers'
	local Statements = Filterers.filterStatementsFromEntity(entity, options)
	for _, statement in pairs(Statements) do
		local Formatters = require 'Modul:Wikidata/Formatters'
		return Formatters.getRawValue(statement.mainsnak, options)
	end
	return nil
end

function p.getRawValue(frame)
	return getRawValue(lib.common.cleanArgs((frame and frame.args) or {}))
end

function p.getRawValueFromLua(options)
	return getRawValue(options)
end

return p