Modul:Wikidata-WP
Dokumentaci tohoto modulu lze vytvořit na stránce Nápověda:Modul:Wikidata-WP
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, wiki)
if wiki then
return mw.wikibase.getEntityIdForTitle(titleString, wiki)
end
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, options.wiki)
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, options.wiki)
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 formatStatementAndData(statement, options)
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 Filterers = require 'Modul:Wikidata/Filterers'
local Formatters = require 'Modul:Wikidata/Formatters'
local result = { Formatters.getFormattedValue(statement.mainsnak, options) }
local qualifiers
if statement.qualifiers and options.showqualifier then
local PropList = lib.textToTable(options.showqualifier)
for _, property in ipairs(PropList) do
local property = mw.ustring.upper(property)
local Values = {}
-- todo: remove this b/c
local default_options = {
autoformat = true,
isQualifier = true,
label = 'short',
nolink = lib.IsOptionTrue(options, 'nolink'),
precision = 9,
property = property
}
for arg, value in pairs(options) do
local match = mw.ustring.match(arg, 'qualifiers (.+)')
if match then
default_options[arg] = value
default_options[match] = value
end
end
if statement.qualifiers[property] then
local Qualifiers = mw.clone(statement.qualifiers[property])
local format_options = mw.clone(default_options)
format_options.nolink = format_options.nolink or (Qualifiers[1].datatype == 'time')
Filterers.filterQualifiers(Qualifiers, options)
for _, snak in ipairs(Qualifiers) do
if lib.IsSnakValue(snak) then
table.insert(Values, Formatters.getFormattedValue(snak, format_options))
end
end
elseif property == 'TIME' then
local Data = {}
local format_options = mw.clone(default_options)
format_options.nolink = true
-- todo: factor out
for key, array in pairs(lib.props) do
for _, prop in ipairs(array) do
for _, snak in ipairs(statement.qualifiers[prop] or {}) do
Data[key] = snak
break
end
end
end
if Data.begin or Data.ending then
table.insert(Values, lib.formatDateRange(Data, format_options))
end
end
if #Values > 0 then
result[property] = mw.text.listToText(Values)
end
end
end
if statement.references and lib.IsOptionTrue(options, 'showsource') then
local Module = require 'Modul:Wikidata/cite'
result.ref = Module.formatReferences(statement.references, options) -- or table of references?
end
return result
end
local function formatStatement(statement, options)
local data = formatStatementAndData(statement, options)
local result = data[1]
if options.isQualifier == true then
return result
end
local qualifiers
if statement.qualifiers and options.showqualifier then
local PropList = lib.textToTable(options.showqualifier)
local tmp = {}
for _, prop in ipairs(PropList) do
local prop = mw.ustring.upper(prop)
if data[prop] then
table.insert(tmp, data[prop])
end
end
if #tmp > 0 then
qualifiers = table.concat(tmp, options['qualifiers separator'] or i18n['qualifiers separator'])
end
end
if not qualifiers and options.showtargetdata then
local entity
local Filterers = require 'Modul:Wikidata/Filterers'
local Formatters = require 'Modul:Wikidata/Formatters'
if lib.IsSnakValue(statement.mainsnak) then
if statement.mainsnak.datavalue.type == 'wikibase-entityid' then
entity = mw.wikibase.getEntity(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 date
local rank = 'best'
if options.targetdate then
if lib.isPropertyId(options.targetdate) then
date = p.getRawValueFromLua{ entity = options.entity, property = options.targetdate }
else
date = options.targetdate
end
if date then
rank = 'valid'
end
end
local options = {
addclass = false,
autoformat = true,
date = date,
entity = entity,
isQualifier = true,
label = 'short',
nolink = true,
precision = 9,
rank = rank,
sort = {'date'},
}
local Snaks = {}
for _, property in ipairs(PropList) do
local result
if mw.ustring.lower(property) == 'time' then
local Data = {}
for key, array in pairs(lib.props) do
for _, prop in ipairs(array) do
options.property = prop
local Statements = Filterers.filterStatementsFromEntity(entity, options)
for _, statement in ipairs(Statements) do
Data[key] = statement.mainsnak
break
end
end
end
if Data.begin or Data.ending then
result = lib.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
qualifiers = table.concat(Snaks, options['qualifiers separator'] or i18n['qualifiers separator'])
end
end
end
if qualifiers then
if options.delimiter then
result = result .. options.delimiter .. qualifiers
else
result = result .. ' (' .. qualifiers .. ')'
end
end
if data.ref and data.ref ~= '' then
return result .. data.ref .. lib.category('references')
end
return result
end
local function formatStatements(statements, options)
local formattedStatements = {}
for _, statement in ipairs(statements) do
local formatted = 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:upper())
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.property)
end
if tostring(options.addclass) ~= 'false' then
return lib.addWdClass(value)
end
return value
end
local function getRawValue(options)
if options.rank ~= 'best' and options.rank ~= 'preferred' then
if type(options.sort) ~= 'table' then
options.sort = lib.textToTable(options.sort or '')
end
local byRank = false
for _, val in ipairs(options.sort) do
if val == 'rank' then
byRank = true
end
end
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
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
----- API pro šablony -----
function p.dumpWikidataEntity(frame)
local args = getArgs(frame, { removeBlanks = true })
return mw.dumpObject( mw.wikibase.getEntity( args.id ) )
end
function p.getCurrentId()
return mw.wikibase.getEntityIdForCurrentPage()
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, label = args.lang
if lang then
label = mw.wikibase.getLabelByLang(id, lang)
else
label, lang = mw.wikibase.getLabelWithLang(id)
end
if label and lib.IsOptionTrue(args, 'addclass') then
if lang ~= i18n.lang then
return lib.addWdClass(lib.formatTextInLanguage(label, lang))
else
return lib.addWdClass(label)
end
end
return label
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
if lang ~= i18n.lang then
description = lib.addWdClass(lib.formatTextInLanguage(description, lang))
else
description = lib.addWdClass(description)
end
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
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, args.wiki)
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.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.formatStatementsFromTemplate(frame)
local args = getArgs(frame, {
frameOnly = false,
parentOnly = false,
parentFirst = false,
})
return getFormattedStatements(args)
end
function p.getCount(frame)
local args = getArgs(frame, {
removeBlanks = true,
frameOnly = true,
})
args.limit = nil
return #p.getStatements(args)
end
function p.getRawValue(frame)
return getRawValue(getArgs(frame, {
removeBlanks = true,
frameOnly = true,
}))
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)
--obraceno, aby zustalo defaultni s addclass
if args['addclass'] == false then
return value
else
return lib.addWdClass(value)
end
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, args)
end
return nil
end
function p.formatEntity(frame)
local args = getArgs(frame, {
removeBlanks = true,
frameOnly = true,
})
args.id = args.id or p.getCurrentId()
if args.id then
local Formatters = require 'Modul:Wikidata/Formatters'
return Formatters.formatRawValue(args.id, 'wikibase-entityid', args)
end
return nil
end
function p.compareStatements(frame)
local args = getArgs(frame, {
removeBlanks = true,
frameOnly = true,
})
return p._compareStatements(args)
end
----- API pro moduly -----
function p.formatStatementsFromLua(options)
return getFormattedStatements(options)
end
function p.getSitelinkFromLua(options)
return getSitelink(options or {})
end
function p.getStatements(args)
local id = findEntityId(args)
return getStatements(id, args)
end
function p.getStatementsWithData(args)
local statements = p.getStatements(args)
local result = {}
for _, statement in ipairs(statements) do
table.insert(result, formatStatementAndData(statement, args))
end
return result
end
function p.getRawValueFromLua(options)
return getRawValue(options)
end
p.formatStatementsTable = formatStatements
function p._compareStatements(args)
if not args.value then
return error(lib.formatError('param-not-provided', 'value'))
end
local statements = p.getStatements(args)
local compare = require 'Modul:Wikidata/compare'
return compare.compareValues(args.value, statements, args)
end
-- zastaralé
function p.filterStatementsFromLua(entity, options)
local statements = mw.clone(entity.claims[(options.property or ''):upper()] or {})
local Filterers = require 'Modul:Wikidata/Filterers'
Filterers.filterStatements(statements, options)
return statements
end
return p