Modulis:Vikidati
Dokumentācija iekļauta no Modulis:Vikidati/doc (labot | hronoloģija) Vari eksperimentēt šī moduļa smilšu kastes (izveidot | spoguļversija) un testu (izveidot) lapā Moduļa apakšlapas. |
--script that retrieves basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
wd = wd or {}
reference = reference or require "Module:Wikidata/fr/Atsauces"
local linguistic = require "Module:Valodas rīki"
local formatDate = require "Module:Komplekss datums"
local formatNum = require 'Module:Conversion'
local langmodule = require'Module:Valodas'
local cite = require "Module:Biblio"
local langcodes = mw.loadData "Module:Wikidata/fr/Valodu kodi"
local getData = require 'Module:Wikidata/fr/Récup'
local entities = require 'Module:Wikidata/fr/Formatēšana'
local tools = require 'Module:Wikidata/fr/Rīki'
local defaultlang = mw.getContentLanguage():getCode()
local translate = tools.translate
function wd.addtrackingcat(prop, cat) -- doit parfois être appelé par d'autres modules
if not prop and not cat then
return error("no property provided")
end
if not cat then
cat = translate('trackingcat', prop or 'P??')
end
return tools.addcat(cat )
end
local function removeblanks(args)
for i, j in pairs(args) do
if j == '' then args[i] = nil end
end
return args
end
local function unknownvalue(displayformat) -- à améliorer
if not displayformat then
return translate('somevalue')
end
if type(displayformat) == 'string' then
return displayformat
end
return tools.formatError()
end
local function novalue(displayformat)
if not displayformat then
return translate('novalue')
end
if type(displayformat) == 'string' then
return displayformat
end
return tools.formatError()
end
local function getlangcode(entityid)
return langcodes[tonumber(entityid:sub(2))]
end
local function showlang(statement) -- retourne le code langue entre paranthèse avant la valeur (par exemple pour les biblios et liens externes)
local mainsnak = statement.mainsnak
if mainsnak.snaktype ~= 'value' then
return nil
end
local langlist = {}
if mainsnak.datavalue.type == 'monolingualtext' then
langlist = {mainsnak.datavalue.value.language}
elseif (not statement.qualifiers) or (not statement.qualifiers.P407) then
return
else
for i, j in pairs( statement.qualifiers.P407 ) do
if j.snaktype == 'value' then
local langentity = tools.getId(j)
local langcode = getlangcode(langentity)
table.insert(langlist, langcode)
end
end
end
if (#langlist > 1) or (#langlist == 1 and langlist[1] ~= defaultlang) then -- si c'est en français, pas besoin de le dire
return langmodule.indicationMultilingue(langlist)
end
end
local function formattable(statements, params) -- transform a table of claims into a table of formatted values
for i, j in pairs(statements) do
j = wd.formatStatement(j, params)
end
return statements
end
function wd.tableToText(values, params) -- takes a list of already formatted values and make them a text
if not values then
return nil
end
return linguistic.quickconj( values, params.conjtype)--linguistic.conj( values, params.lang, params.conjtype )
end
function wd.rangeobject(begin, ending, params)
--[[
objet comportant un timestamp pour le classement chronologique et deux dateobject (begin et ending)
]]--
local timestamp
if begin then
timestamp = begin.timestamp
else
timestamp = ending.timestamp
end
return {begin = begin, ending = ending, timestamp = timestamp, type = 'rangeobject'}
end
function wd.dateobject(orig, params)
--[[ transforme un snak en un nouvel objet utilisable par Module:Date complexe
{type = 'dateobject', timestamp = str, era = '+' ou '-', year = number, month = number, day = number, calendar = calendar}
]]--
if not params then
params = {}
end
local newobj = formatDate.splitDate(orig.time, orig.calendar)
newobj.precision = params.precision or orig.precision
newobj.type = 'dateobject'
return newobj
end
function wd.objecttotext(obj, params)
if obj.type == 'dateobject' then
return formatDate.simplestring(obj, params)
elseif obj.type == 'rangeobject' then
return formatDate.daterange(obj.begin, obj.ending, params)
end
end
function wd.getDate(statement)
--[[
returns an object containing a timestamp for easy sorting, and other data
2 types of object
dateobject
{timestamp = string, year = number, month = number, day = number, calendar = string}
rangeobject
{timestamp = string, begin = dateobject, ending = dateobject}
]]--
local q = statement.qualifiers
if not q or not (q.P585 or q.P580 or q.P582) then
return nil
end
local begin, ending
-- si p585 : dateobject
if q.P585 and q.P585[1].snaktype == 'value' then -- P585: punctual date
return wd.dateobject(q.P585[1].datavalue.value)
end
-- si p580 ou P582 : rangeobject avec une date de début et/ou une date de fin
if q.P582 and q.P582[1].snaktype == 'value' then
ending = wd.dateobject(q.P582[1].datavalue.value)
end
if (q.P580 and q.P580[1].snaktype == 'value') then
begin = wd.dateobject(q.P580[1].datavalue.value)
end
if begin or ending then -- sinon ce sont des 'specialvalues', il faudrait aussi les prendre en charge
return wd.rangeobject(begin, ending)
end
end
function wd.getFormattedDate(statement, params)
local datetable = wd.getDate(statement)
if not datetable then
return nil
end
return wd.objecttotext(datetable, params)
end
function wd.getDatavalue(snak, params)
if not params then
params = {}
end
local speciallabels = params.speciallabels -- parfois on a besoin de faire une liste d'éléments pour lequel le libellé doit être changé, pas très pratique d'utiliser une fonction pour ça
if snak.snaktype ~= 'value' then
return nil
end
local datatype = snak.datavalue.type
local value = snak.datavalue.value
local displayformat = params.displayformat
if type(displayformat) == 'function' then
return displayformat(snak, params)
end
if (datatype == 'wikibase-entityid') then
return entities.formatEntity(tools.getId(snak), params)
end
if datatype == ('string') then
if params.displayformat == 'weblink' then
return require('Module:Weblink').makelink(value, params.text)
end
if type(params.displayformat) == 'function' then
value = params.displayformat(value)
end
if params.urlpattern then
local urlpattern = params.urlpattern
if type(urlpattern) == 'function' then
urlpattern = urlpattern(value)
end
value = '[' .. mw.ustring.gsub(urlpattern, '$1', value) .. ' ' .. (params.text or value) .. ']'
end
return value
end
if datatype == 'time' then -- format example: +00000001809-02-12T00:00:00Z
local precision = params.precision -- degré de précision à afficher ('day', 'month', 'year'), inférieur ou égal à value.precision
if displayformat == 'raw' then
return value.time
else
return wd.objecttotext(wd.dateobject(value, {precision = precision}), {linktopic = params.linktopic})
end
end
if datatype == 'globecoordinate' then
-- retourne une table avec clés latitude, longitude, précision et globe à formater par un autre module (à changer ?)
value.globe = require('Module:Wikidata/Globes')[value.globe] -- transforme l'ID du globe en nom anglais utilisable par geohack
if formatting == 'latitude' then
return value.latitude
elseif formatting == 'longitude' then
return value.longitude
else
return value -- note : les coordonnées Wikidata peuvent être utilisée depuis Module:Coordinates. Faut-il aussi autoriser à appeler Module:Coordiantes ici ?
end
end
if datatype == 'quantity' then -- todo : gérer les paramètre précision
local amount, unit = value.amount, value.unit
if displayformat == 'raw' then
return amount
end
if unit then
unit = unit:match('Q%d+')
end
local showunit = params.showunit or true
if showunit == '-' then
showunit = false
end
local targetunit = params.targetunit
return formatNum.displayvalue(amount, unit,
{targetunit = params.targetunit, displayformat = params.displayformat, rounding = params.rounding, showunit = showunit}
)
end
if datatype == 'monolingualtext' then
return langmodule.langue({value.language, value.text})
end
return tools.formatError('unknown-datavalue-type' )
end
function wd.getClaims( args ) -- returns a table of the claims matching some conditions given in args
return getData.getClaims(args)
end
function wd.formatClaimList(claims, args)
if not claims then
return nil
end
for i, j in pairs(claims) do
claims[i] = wd.formatStatement(j, args)
end
if args.removedupes and (args.removedupes ~= '-') then
claims = tools.addnewvalues({}, claims)
end
return claims
end
function wd.stringTable(args) -- like getClaims, but get a list of string rather than a list of snaks, for easier manipulation
local claims = wd.getClaims(args)
return wd.formatClaimList(claims, args)
end
local function getQualifiers(statement, qualifs, params)
if not statement.qualifiers then
return nil
end
local vals = {}
for i, j in pairs(qualifs) do
if statement.qualifiers[j] then
for k, l in pairs(statement.qualifiers[j]) do
table.insert(vals, l)
end
end
end
if #vals == 0 then
return nil
end
return vals
end
function wd.getFormattedQualifiers(statement, qualifs, params)
if not params then params = {} end
local qualiftable = getQualifiers(statement, qualifs)
if not qualiftable then
return nil
end
for i, j in pairs(qualiftable) do
qualiftable[i] = wd.formatSnak(j, params)
end
return linguistic.conj(qualiftable)
end
function wd.formatStatement( statement, args )
if not args then
args = {}
end
if not statement.type or statement.type ~= 'statement' then
return tools.formatError( 'unknown-claim-type' )
end
local str = wd.formatSnak( statement.mainsnak, args )
if args.showlang == true then
str = (showlang(statement) or '') .. ' ' .. str
end
if args.showqualifiers then
local qualifs = args.showqualifiers
if type(qualifs) == 'string' then
qualifs = mw.text.split(qualifs, ',')
end
local qualifargs = {}
-- formatage des qualificateur = args commençant par "qualif", ou à défaut, les mêmes que pour la valeur principale
qualifargs.displayformat = args.qualifdisplayformat or args.displayformat
qualifargs.labelformat = args.qualiflabelformat or args.labelformat
qualifargs.link = args.qualiflink or args.link
local formattedqualifs = wd.getFormattedQualifiers(statement, qualifs, qualifargs)
if formattedqualifs then
str = str .. linguistic.inparentheses(formattedqualifs, lang)
end
end
if args.showdate then -- when "showdate and chronosort are both set, date retrieval is performed twice
local timedata = wd.getDate(statement)
if timedata then
local formatteddate = wd.objecttotext(timedata, args)
formatteddate = linguistic.inparentheses(formatteddate, lang)
str = str .. '<small>' .. formatteddate ..'</small>'
end
end
if args.showsource and statement.references then
local sourcestring = ''
for i, ref in pairs(statement.references) do
local s = ''
local function hasValue(prop) -- checks that the prop is here with valid value
if ref.snaks[prop] and ref.snaks[prop][1].snaktype == 'value' then
return true
end
return false
end
local function firstsnak(prop)
return wd.formatSnak(prop[1])
end
if ref.snaks.P248 then
for j, source in pairs(ref.snaks.P248) do
if source.snaktype == 'value' then
local page, accessdate
if hasValue('P304') then
page = wd.formatSnak(ref.snaks.P304[1])
end
if hasValue('P813') then
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
s = reference.citeitem(tools.getId(source), {['page'] = page, ['accessdate'] = accessdate})
s = mw.getCurrentFrame():extensionTag( 'ref', s )
sourcestring = sourcestring .. s
end
end
elseif hasValue('P854') and hasValue('P1476') then
local url, title, accessdate, publishdate, publishlang
url, title = wd.formatSnak(ref.snaks.P854[1]), wd.formatSnak(ref.snaks.P1476[1])
if hasValue('P813') then
accessdate = wd.formatSnak(ref.snaks.P813[1])
end
-- publishdate avec P577 ? (ne semble pas vraiment correspondre)
if hasValue('P407') then
local id = tools.getId(ref.snaks.P407[1])
publishlang = getlangcode(id)
end
s = cite.lienWeb{titre = title, url = url, langue = publishlang, ['en ligne le'] = publishdate, ['consulté le'] = accessdate}
s = mw.getCurrentFrame():extensionTag( 'ref', s)
sourcestring = sourcestring .. s
elseif ref.snaks.P854 and ref.snaks.P854[1].snaktype == 'value' then
s = mw.getCurrentFrame():extensionTag( 'ref', wd.formatSnak(ref.snaks.P854[1]))
sourcestring = sourcestring .. s
end
end
str = str .. sourcestring
end
return str
end
function wd.formatSnak( snak, params )
if not params then params = {} end -- pour faciliter l'appel depuis d'autres modules
if snak.snaktype == 'somevalue' then
return unknownvalue(params.unknownlabel)
elseif snak.snaktype == 'novalue' then
return novalue(params.novaluelabel)
elseif snak.snaktype == 'value' then
return wd.getDatavalue( snak, params)
else
return tools.formatError( 'unknown-snak-type' )
end
end
function wd.getDescription(entity, lang)
lang = lang or defaultlang
local description
if lang == defaultlang then
return mw.wikibase.descriptionl(qid)
end
if not entity.descriptions then
return translate('no description')
end
local descriptions = entity.descriptions
if not descriptions then
return nil
end
if descriptions[lang] then
return descriptions[delang].value
end
return entity.id
end
function wd.addLinkback(str, id, property)
if not id then
id = tools.getEntity()
end
if not id then
return str
end
if type(id) == 'table' then
id = id.id
end
local class = ''
if property then
class = 'wd_' .. string.lower(property)
end
local title = translate('see-wikidata-value')
local icon = '[%s [[File:Blue pencil.svg|%s|10px|baseline|link=]] ]'
local url = mw.uri.fullUrl('d:' .. id, 'uselang=fr')
url.fragment = property
url = tostring(url)
local v = mw.html.create('span')
:addClass(class)
:wikitext(str)
:tag('span')
:addClass('noprint plainlinks wikidata-linkback')
:css('padding-left', '.5em')
:wikitext(icon:format(url, title))
:allDone()
return tostring(v)
end
function wd.addRefAnchor(str, id)
--[[
Insère une ancre pour une référence générée à partir d'un élément Wikidata.
L'id Wikidata sert d'identifiant à l'ancre, à utiliser dans les modèles type "harvsp"
--]]
return tostring(mw.html.create('span'):attr('id', id)
:attr('class', "ouvrage")
:wikitext(str)
)
end
function wd.formatStatements( args )--Format statement and concat them cleanly
if args.value == '-' then
return nil
end
--If a value is already set, use it
if args.value and args.value ~= '' then
return args.value
end
args.entity = tools.getEntity(args.entity)
local valuetable = wd.stringTable(args)
local str = wd.tableToText(valuetable, args)
if not str then
return nil
end
if args.addcat and (args.addcat ~= '-') then
str = str .. wd.addtrackingcat(args.property)
end
if args.linkback and (args.linkback ~= '-') then
str = wd.addLinkback(str, args.entity, args.property)
end
return str
end
function wd.showQualifier( args )
local qualifs = args.qualifiers or args.qualifier
if type(qualifs) == 'string' then
qualifs = mw.text.split(qualifs, ',')
end
if not qualifs then
return tools.formatError( 'property-param-not-provided' )
end
local claims = wd.getClaims(args)
if not claims then
return nil
end
local str = ''
for i, j in pairs(claims) do
local new = wd.getFormattedQualifiers(j, qualifs, args) or ''
str = str .. new
end
return str
end
function wd.formatAndCat(args)
if not args then
return nil
end
args.linkback = true
args.addcat = true
if args.value then -- do not ignore linkback and addcat, as formatStatements do
local val = args.value .. wd.addtrackingcat(args.property)
val = wd.addLinkback(val, args.entity, args.property)
return val
end
return wd.formatStatements( args )
end
function wd.getTheDate(args)
local claims = wd.getClaims(args)
if not claims then
return nil
end
local formattedvalues = {}
for i, j in pairs(claims) do
table.insert(formattedvalues, wd.getFormattedDate(j))
end
local val = linguistic.conj(formattedvalues)
if not val then
return nil
end
if args.addcat == true then
val = val .. wd.addtrackingcat(args.property)
end
val = wd.addLinkback(val, args.entity, args.property)
return val
end
-- Complex functions using several items
local function getids(query)
query.excludespecial = true
query.displayformat = 'raw'
return wd.stringTable(query)
end
function wd.Dump(entity)
entity = tools.getEntity(entity)
if not entity then
return tools.formatError("entity-param-not-provided")
end
return "<pre>"..mw.dumpObject(entity).."</pre>"
end
wd.getid = tools.getId
wd.getmainid = tools.getMainId
-- fonctions obsolètes
function wd.getLabel(entity, args)
entities.getLabel(entity)
end
function wd.formatEntity(entity, args)
return entities.formatEntity(entity, args)
end
function wd._getLabel(entity, args)
return wd.getLabel(entity, args)
end
function wd._formatAndCat(args)
return wd.formatAndCat(args)
end
function wd._formatStatements(args)
return wd.formatStatements(args)
end
return wd