Přeskočit na obsah

Modul:Wikidata/sandbox

Z Wikipedie, otevřené encyklopedie

Dokumentaci tohoto modulu lze vytvořit na stránce Modul:Wikidata/sandbox/Dokumentace

require 'Modul:No globals'

local p = {}

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

local getArgs = (require 'Modul:Arguments').getArgs

local function getEntityIdFromStatements(statements)
	for _, statement in ipairs(statements) do
		if lib.IsSnakValue(statement.mainsnak) then
			if statement.mainsnak.datavalue.type ~= 'wikibase-entityid' then
				return error(lib.raiseInvalidDatatype('getEntityIdFromStatements',
					statement.mainsnak.datatype, {'wikibase-item', 'wikibase-property'}))
			end
			local Formatters = require 'Modul:Wikidata/Formatters'
			return Formatters.getRawValue(statement.mainsnak)
		end
	end
	return nil
end

local function getEntityIdFromEntity(entity, prop)
	local prop = mw.ustring.upper(prop)
	local statements = entity:getBestStatements(prop)
	return getEntityIdFromStatements(statements)
end

local function getEntityIdFromId(id, prop)
	local prop = mw.ustring.upper(prop)
	local statements = mw.wikibase.getBestStatements(id, prop)
	return getEntityIdFromStatements(statements)
end

local function getIdFromTitle(titleString)
	local title = mw.title.new(titleString)
	while title do
		local id = mw.wikibase.getEntityIdForTitle(title.prefixedText)
		if id then
			return id
		end
		title = title.redirectTarget
	end
	return nil
end

local function findEntityId(options)
	local id
	if options.entity and type(options.entity) == "table" then
		id = options.entity.id
	end
	if not id and options.page then
		id = getIdFromTitle(options.page)
		if not id then
			return nil
		end
	end
	if not id then
		id = options.id or p.getCurrentId()
	end
	if id and options.of then
		id = getEntityIdFromId(id, options.of)
	end
	return 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 = mw.wikibase.getEntity(id)
			if entity and entity.id ~= id then
				mw.log(id .. ' je přesměrování na ' .. entity.id)
			end
		else
			if options.page then
				local id = getIdFromTitle(options.page)
				if id then
					entity = mw.wikibase.getEntity(id)
				end
			else
				entity = mw.wikibase.getEntity()
			end
		end
	end
	if options.of then
		if entity then
			local id = getEntityIdFromEntity(entity, options.of)
			if id then
				return mw.wikibase.getEntity(id)
			end
		end
		return nil
	end
	return entity
end

local function getSitelink(options)
	local id = findEntityId(options)
	if not id then
		return nil
	end

	local site = options.site or options[1]
	local sitelink = mw.wikibase.sitelink(id, 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.addWdClass(sitelink)
	end
	return sitelink
end

local function formatStatements(statements, options)
	local StatementFormatter
	if options.formatter then
		StatementFormatter = require('Modul:Wikidata/Statement/' .. options.formatter)
	else
		StatementFormatter = require 'Modul:Wikidata/Statement'
	end

	local formattedStatements = {}
	for _, statement in ipairs(statements) do
		if not statement.type or statement.type ~= 'statement' then
			return error(lib.formatError('unknown-claim-type', statement.type or '[neznámý]')) -- fixme: i18n
		end
		local formatted = StatementFormatter.formatStatement(statement, options)
		local add = true
		for _, fmt in ipairs(formattedStatements) do
			if formatted == fmt then
				add = false
				break
			end
		end
		if add then -- not in_array
			table.insert(formattedStatements, formatted)
		end
	end
	return formattedStatements
end

local function getStatements(id, options)
	if not id then
		return {}
	end
	local statements = mw.wikibase.getAllStatements(id, options.property)
	local Filterers = require 'Modul:Wikidata/Filterers'
	Filterers.filterStatements(statements, options)
	return statements
end

local function prepareShowMore(options)
	if options.limit and lib.IsOptionTrue(options, 'showmore') then
		options.limit = options.limit + 1
		return true
	end
	return false
end

local function handleShowMore(values, limit, add_more)
	if add_more then
		if #values == limit then
			table.remove(values)
		else
			add_more = false
		end
	end
	return add_more
end

local function makeList(values, options, add_more)
	if add_more then
		table.insert(values, mw.ustring.format(i18n['more-on-Wikidata'], options.id, options.property))
	end
	return mw.text.listToText(values, options.separator, options.conjunction)
end

local function getFormattedStatements(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
	local options = lib.common.cleanArgs(options)

	options.limit = tonumber(options.limit) --TODO default?
	local add_more = false
	if not lib.IsOptionTrue(options, 'compare') then
		add_more = prepareShowMore(options)
	end

	local id = findEntityId(options)
	local statements = getStatements(id, 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 tostring(options.addclass) ~= 'false' and marked then
			value = marked
		end
		if lib.IsOptionTrue(options, 'addcat') and category then
			return value .. category
		end
		return value
	end

	if #statements == 0 then return nil end
	add_more = handleShowMore(statements, options.limit, add_more)

	options.id = id
	-- Format statements and concat them cleanly
	local formattedStatements = formatStatements(statements, options)
	value = makeList(formattedStatements, options, add_more)

	if lib.IsOptionTrue(options, 'addlink') then
		value = mw.ustring.format('%s <sup class="wd-link">([[d:%s#%s|e]])</sup>', value, id, options.property)
	end
	if lib.IsOptionTrue(options, 'addcat') then
		value = value .. lib.category('used-property', options.catbase or 'Vlastnost ' .. options.property)
	end
	if tostring(options.addclass) ~= 'false' then
		return lib.addWdClass(value)
	end
	return value
end

function p.dumpWikidataEntity(frame)
	local args = getArgs(frame, { removeBlanks = true })

	return mw.dumpObject( mw.wikibase.getEntity( args.id ) )
end

function p.getBadges(frame)
	local args = getArgs(frame, { removeBlanks = true })
	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 Formatters = require 'Modul:Wikidata/Formatters'
		for _, badge in ipairs(entity.sitelinks[site].badges) do
			table.insert(Badges, Formatters.formatRawValue(badge, 'wikibase-entityid'))
		end
	end
	return table.concat( Badges, ', ' )
end

function p.getLabel(frame)
	local args = getArgs(frame, { removeBlanks = true })
	local id = findEntityId(args)
	if not id then
		return nil
	end
	local lang = args.lang
	local code = mw.language.getContentLanguage():getCode()
	if not lang or lang == code then
		local label, _ = lib.getLabelInLanguage(id, { code })
		if label and lib.IsOptionTrue(args, 'addclass') then
			label = lib.addWdClass(label)
		end
		return label
	end
	local entity = mw.wikibase.getEntity(id)
	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.addWdClass(label)
		end
		return label
	end
	return nil
end

function p.getDescription(frame)
	local args = getArgs(frame, { removeBlanks = true })
	local id = findEntityId(args)
	if not id then
		return nil
	end
	local lang = args.lang
	if not lang or lang == mw.language.getContentLanguage():getCode() then
		local description = mw.wikibase.description(id)
		if description and lib.IsOptionTrue(args, 'addclass') then
			description = lib.addWdClass(description)
		end
		return description 
	end
	local entity = mw.wikibase.getEntity(id)
	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.addWdClass(description)
		end
		return description 
	end
	return nil
end

function p.getAliases(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	})
	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

	args.limit = tonumber(args.limit)
	local add_more = prepareShowMore(args)

	local Aliases = {}
	for i, alias in ipairs(entity.aliases[lang]) do
		if not args.limit or i <= args.limit then
			table.insert(Aliases, alias.value)
		else break end
	end
	add_more = handleShowMore(Aliases, args.limit, add_more)
	local list = makeList(Aliases, args, add_more)
	return lib.addWdClass(list)
end

p.getCurrentId = mw.wikibase.getEntityIdForCurrentPage

function p.getId(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = false,
		parentFirst = false
	})

	if not args[1] then
		return mw.wikibase.getEntityIdForCurrentPage()
	end

	for _, titleString in ipairs(args) do
		local id = getIdFromTitle(titleString)
		if id then
			return id
		end
	end
	return nil
end

function p.getSitelink(frame)
	return getSitelink(getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	}))
end

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

function p.formatStatements(frame)
	local args = getArgs(frame, {
		removeBlanks = false, -- todo
		frameOnly = true,
	})
	local parent_args = getArgs(frame:getParent(), { removeBlanks = true })
	local add
	if parent_args.item and not args.id then
		args.id = parent_args.item
		add = lib.category('arbitrary-data')
	end
	local value = getFormattedStatements(args)
	if add and value then
		return value .. add
	end
	return value
end

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

function p.getStatements(args)
	local id = findEntityId(args)
	return getStatements(id, args)
end

function p.getCount(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	})
	args.limit = nil
	return #p.getStatements(args)
end

p.formatStatementsTable = formatStatements

local function getRawValue(options)
	if options.rank ~= 'best' and options.rank ~= 'preferred' then
		local byRank = mw.ustring.match(options.sort or '', 'rank') and true
		options.sort = lib.textToTable(options.sort or '')
		if not byRank then
			table.insert(options.sort, 1, 'rank')
		end
	end

	for _, statement in ipairs(p.getStatements(options)) do
		local Formatters = require 'Modul:Wikidata/Formatters'
		return Formatters.getRawValue(statement.mainsnak, options)
	end
	return nil
end

function p.getRawValue(frame)
	return getRawValue(getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	}))
end

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

local function getQualifiers(args)
	if not args.qualifier then
		return error(lib.formatError('param-not-provided', 'qualifier'))
	end
	for _, statement in ipairs(p.getStatements(args)) do
		if statement.qualifiers then
			local qualifiers = mw.clone(statement.qualifiers[mw.ustring.upper(args.qualifier)] or {})
			local Filterers = require 'Modul:Wikidata/Filterers'
			Filterers.filterQualifiers(qualifiers, args)
			return qualifiers
		end
		return {}
	end
	return {}
end

function p.getQualifier(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	})
	args.limit = tonumber(args.limit)
	local add_more = prepareShowMore(args)
	local limit = args.limit
	args.limit = 1
	args.isQualifier = true
	if not args['qualifiers limit'] then
		args['qualifiers limit'] = limit
	end
	local qualifiers = getQualifiers(args)
	if #qualifiers == 0 then
		return nil
	end

	add_more = handleShowMore(qualifiers, limit, add_more)
	local Formatters = require 'Modul:Wikidata/Formatters'
	local formattedQualifiers = {}
	for _, qualifier in ipairs(qualifiers) do
		table.insert(formattedQualifiers, Formatters.getFormattedValue(qualifier, args))
	end

	local value = makeList(formattedQualifiers, args, add_more)
	return lib.addWdClass(value)
end

function p.getRawQualifier(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	})
	local limit = args.limit and tonumber(args.limit)
	args.limit = 1
	for _, qualifier in ipairs(getQualifiers(args)) do
		local Formatters = require 'Modul:Wikidata/Formatters'
		return Formatters.getRawValue(qualifier)
	end
	return nil
end

function p.formatEntity(frame)
	local args = getArgs(frame, {
		removeBlanks = true,
		frameOnly = true,
	})
	local id = args.id or p.getCurrentId()
	args.id = nil
	if id then
		local Formatters = require 'Modul:Wikidata/Formatters'
		return Formatters.formatRawValue(id, 'wikibase-entityid', args)
	end
	return nil
end

return p