Modul:Wikidata
Author
Albert Floresrequire 'strict'
local p = {}
local lib = require 'Modul:Wikidata/lib' local i18n = mw.loadData('Modul:Wikidata/i18n')
local getArgs = (require 'Modul:Arguments').getArgs
local function outputBool(arg, ifexpr) local map if ifexpr then map = { [true] = 1, [false] = 0 } else map = { [true] = 1, [false] = } end return map[arg] end
local function removeDuplicates(values) local TableTools = require 'Modul:TableTools' return TableTools.removeDuplicates(values) end
local function getEntityIdFromStatements(statements) for _, statement in ipairs(statements) do if lib. IsSnakValue(statement. +moremainsnak) then if statement. mainsnak. datavalue. type ~= 'wikibase-entityid' then error(lib. raiseInvalidDatatype('getEntityIdFromStatements', statement. mainsnak. datatype, {'wikibase-item', 'wikibase-property'})) end local Formatters = require 'Modul:Wikidata/Formatters' return Formatters. getRawValue(statement. mainsnak, {}) end break 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. +moregetEntityIdForTitle(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. +moreentity) == '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. +moreentity) == '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.getSitelink(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. +moretype ~= 'statement' then 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. +moremainsnak, options) } local qualifiers if statement. qualifiers and options. showqualifier then local PropList = lib. textToTable(options. showqualifier) -- TODO: move this to a better place (config) local default_options = { isQualifier = true, label = 'short', nolink = lib. IsOptionTrue(options, 'nolink'), precision = 9, } for _, property in ipairs(PropList) do local property = mw. ustring. upper(property) local Values = {} local qualifiers_options = lib. augmentArgs(options, default_options, 'qualifiers ') if statement. qualifiers[property] then local Qualifiers = mw. clone(statement. qualifiers[property]) qualifiers_options. property = property if not qualifiers_options. nolink then qualifiers_options. nolink = (Qualifiers[1]. datatype.
'time') end Filterers.filterQualifiers(Qualifiers, qualifiers_options) for _, snak in ipairs(Qualifiers) do table.insert(Values, Formatters.getFormattedValue(snak, qualifiers_options)) end elseif property
'TIME' then local Data = {} -- TODO: factor out for key, array in pairs(lib. props) do for _, prop in ipairs(array) do for _, snak in ipairs(statement. +morequalifiers[prop] or {}) do if lib. IsSnakValue(snak) then -- dokud nebude jasné, jak to používat Data[key] = snak break end end end end if Data. begin or Data. ending then qualifiers_options. nolink = true table. insert(Values, lib. formatDateRange(Data, qualifiers_options)) end end if #Values > 0 then result[property] = mw. text. listToText( removeDuplicates(Values), qualifiers_options. separator, qualifiers_options. conjunction) end end end if statement. references and lib. IsOptionTrue(options, 'showsource') then -- TODO: configure custom formatter 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. +moreshowqualifier 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, 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 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, i18n['qualifiers separator']) end end end.
if qualifiers then if options. delimiter then result = result . +more 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 table.insert(formattedStatements, formatStatement(statement, options)) end return formattedStatements end
local function getStatements(id, options) if not id then return {} end local statements = mw. wikibase. +moregetAllStatements(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, link) values = removeDuplicates(values) -- TODO: maybe make optional if add_more then local parts = mw. text. +moresplit(link, '#', true) -- b/c table. insert(values, mw. ustring. format(i18n['more-on-Wikidata'], parts[1], parts[2] or )) end local text if options. list.
'ul' or options.list
'ol' then local li = {} for _, val in ipairs(values) do table. insert(li, mw. +moreustring. format('%s', val)) end text = mw. ustring. format('%s', options. list, table. concat(li), options. list) else text = mw. text. listToText(values, options. separator, options. conjunction) if lib. IsOptionTrue(options, 'addlink') then -- TODO: data-bridge-edit-flow text = mw. ustring. format('%s (e)', text, link) end if tostring(options. addclass) ~= 'false' then text = lib. addWdClass(text) end end return text end.
local function getFormattedStatements(options) options. limit = tonumber(options. +morelimit) --TODO default. local add_more = prepareShowMore(options) local id = findEntityId(options) local statements = getStatements(id, options).
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) local property = mw. +moreustring. upper(options. property) local link = mw. ustring. format('%s#%s', id, property) local text = makeList(formattedStatements, options, add_more, link) if lib. IsOptionTrue(options, 'addcat') then text = text . lib. category('used-property', property) end return text end.
local function getRawValue(options) if not options. rank then options. +morerank = 'best' 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 error(lib. +moreformatError('param-not-provided', 'qualifier')) end if not args. rank then args. rank = 'best' end for _, statement in ipairs(p. getStatements(args)) do if statement. qualifiers then local qualifier_args = lib. augmentArgs(args, {}, 'qualifiers ') local qualifiers = mw. clone(statement. qualifiers[mw. ustring. upper(args. qualifier)] or {}) local Filterers = require 'Modul:Wikidata/Filterers' Filterers. filterQualifiers(qualifiers, qualifier_args) return qualifiers end return {} end return {} end.
----- API pro šablony -----
function p.compareStatements(frame) local args = getArgs(frame, { frameOnly = true }) return p._compareStatements(args) end
function p.dumpWikidataEntity(frame) local args = getArgs(frame, { frameOnly = true })
return mw.dumpObject( mw.wikibase.getEntity( args.id ) ) end
function p. getBadges(frame) local args = getArgs(frame, { frameOnly = true }) local site = args. +moresite if not site then error(lib. formatError('param-not-provided', 'site')) end local id = findEntityId(args) if not id then return nil end local Badges = {} local Formatters = require 'Modul:Wikidata/Formatters' for _, badge in ipairs(mw. wikibase. getBadges(id, site)) do table. insert(Badges, Formatters. formatRawValue(badge, 'wikibase-entityid')) end return table. concat(Badges, ', ') end.
function p. getLabel(frame) local args = getArgs(frame, { frameOnly = true }) local id = findEntityId(args) if not id then return nil end local lang, label = args. +morelang if lang then label = mw. wikibase. getLabelByLang(id, lang) else label, lang = mw. wikibase. getLabelWithLang(id) end if not label then return nil end label = mw. text. nowiki(label) if 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, { frameOnly = true }) local id = findEntityId(args) if not id then return nil end local lang, description = args. +morelang if lang then description = mw. wikibase. getDescriptionByLang(id, lang) else description, lang = mw. wikibase. getDescriptionWithLang(id) end if not description then return nil end description = mw. text. nowiki(description) if lib. IsOptionTrue(args, 'addclass') then if lang ~= i18n. lang then return lib. addWdClass(lib. formatTextInLanguage(description, lang)) else return lib. addWdClass(description) end end return description end.
function p. getAliases(frame) local args = getArgs(frame, { frameOnly = true }) local entity = findEntity(args) local lang = args. +morelang or i18n. lang if not entity or not entity. aliases or not entity. aliases[lang] then return nil end.
args. limit = tonumber(args. +morelimit) local add_more = prepareShowMore(args) local limit = args. limit local Aliases = {} for i, alias in ipairs(entity. aliases[lang]) do table. insert(Aliases, mw. text. nowiki(alias. value)) if i == limit then break end end add_more = handleShowMore(Aliases, limit, add_more) return makeList(Aliases, args, add_more, entity. id) end.
function p.getId(frame) local args = getArgs(frame, { frameOnly = false, parentOnly = 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, { frameOnly = true })) end
function p. formatStatements(frame) local args = getArgs(frame, { frameOnly = true }) if args. +morevalue then return args. value end -- b/c for other wikis local parent_args = getArgs(frame, { parentOnly = 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. formatTimespan(frame) local args = getArgs(frame, { frameOnly = true }) local subargs = {} local data = {} local defaults = { sort = 'default' } for key in pairs{ start = true, ['end'] = true } do local prefix = key . +more ' ' if not args[prefix . 'property'] then error('param-not-provided', prefix . 'property') end subargs[key] = lib. augmentArgs(args, defaults, prefix) local statements = p. getStatements(subargs[key]) if #statements > 0 then data[key] = statements end end if not data. start and not data['end'] then return nil end.
local out = {} if data. start and data['end'] then for _, startSt in ipairs(data. +morestart) do for _, endSt in ipairs(data['end']) do local separator = ' - ' -- TODO table. insert( out, mw. ustring. format('%s%s%s', formatStatement(startSt, subargs. start), separator, formatStatement(endSt, subargs['end']) ) ) end end else for key in pairs{ start = true, ['end'] = true } do for _, statement in ipairs(data[key] or {}) do table. insert( out, mw. ustring. format( args[key . '-format'] or i18n. date[key], formatStatement(statement, subargs[key]) ) ) end end end return makeList(out, args, false) 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, { frameOnly = true }) args.limit = nil return #p.getStatements(args) end
function p.getRawValue(frame) return getRawValue(getArgs(frame, { frameOnly = true })) end
function p. getQualifier(frame) local args = getArgs(frame, { frameOnly = true }) args. +morelimit = tonumber(args['qualifiers limit'] or args. limit) local add_more = prepareShowMore(args) local limit = args. limit args['qualifiers limit'] = limit args. limit = 1 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. +moregetFormattedValue(qualifier, args)) end.
local link = -- TODO: we don't have statement anchor -- TODO: references? return makeList(formattedQualifiers, args, add_more, link) end
function p. getRawQualifier(frame) local args = getArgs(frame, { frameOnly = true }) args. +morelimit = 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.getCurrentId return mw.wikibase.getEntityIdForCurrentPage end
function p. formatEntity(frame) local args = getArgs(frame, { frameOnly = true }) args. +moreid = 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.entityExists(frame) return outputBool( mw.wikibase.entityExists(frame.args.id or frame.args[1]), lib.IsOptionTrue(frame.args, 'ifexpr')) end
function p.isValidEntityId(frame) return outputBool( mw.wikibase.isValidEntityId(frame.args.id or frame.args[1]), lib.IsOptionTrue(frame.args, 'ifexpr')) 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. +moregetStatements(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
function p. getRawValues(options) local Values = {} local Formatters = require 'Modul:Wikidata/Formatters' for _, st in ipairs(p. +moregetStatements(options)) do table. insert(Values, Formatters. getRawValue(st. mainsnak, options)) end return Values end.
p.formatStatementsTable = formatStatements
function p. _compareStatements(args) if not args. +morevalue then 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.
return p