Module:Wikidata/utils
Documentation for this module may be created at Module:Wikidata/utils/doc
Code
-- Higher level functions for maminuplating Wikidata data
local p = {}
local wikidata = require('Module:Wikidata')
local linguistic = require('Module:Linguistic')
local daterange = require('Module:Daterange')
local ppath = require('Module:PropertyPath')
local function itemidfromclaim(claim) -- returns 'Q' + the numeric ID of the mainsnak value of a claim so that it can be used by mw.wikibase.getEntityObject
if claim.mainsnak.snaktype == 'value' and claim.mainsnak.datavalue.value[ "entity-type"] == 'item' then
return 'Q' .. claim.mainsnak.datavalue.value['numeric-id']
else
return nil
end
end
local function checkloop(tocheck, target, property, checked) --check if an item is a value of something
local checked = {}
for i, item in pairs(tocheck) do
if item == target then
return true
end
if not checked[item] then
local newitems = wikidata.getClaims({property = property, item = item, rank= 'valid'})
if newitems then
for i, j in pairs(newitems) do
table.insert(tocheck, itemidfromclaim(j))
end
end
end
checked[item] = true
end
return false
end
local function isinchain(origitem, targetitem, property)
if (not origitem) or (not targetitem) or (not property) then
return error()
end
return checkloop({origitem}, targetitem, property, {})
end
function p.issuperclass(origitem, targetitem)
return isinchain(origitem, targetitem, 'P279')
end
function p.isinstance(origitem, targetitem)
local directinstanceof = wikidata.getClaims({property = 'P31', item = origitem, rank= 'valid'}) -- get the P31 values
if not directinstanceof then
return false
end
for i, j in pairs(directinstanceof) do -- check if they are superclass of the target item
if p.issuperclass(itemidfromclaim(j), targetitem) then
return true
end
end
return false
end
function p.getdate(claim)
--[[
return a "timedata" object as used by the date modules with the date of an item from the p580, p582 and p585 qualifiers
object format:
* timestamp 28 char string value for the timepoint, or if non the beginning or if none, the end (for easy sorting)
* timepoint: snak
* begin: snak
]]--
local timedata = {}
if not claim.mainsnak.snaktype == 'value' then -- TODO: handle unknown dates
return nil
end
if not claim.mainsnak.datavalue.type == 'item' then
return nil -- error() ??
end
local q = claim.qualifiers
if not q or not (q.P585 or q.P580 or q.P582) then
return nil
end
if q.P582 and q.P582[1].snaktype == 'value' then
timedata.endpoint = q.P582[1].datavalue.value
timedata.timestamp = q.P582[1].datavalue.value.time
end
if q.P580 and q.P580[1].snaktype == 'value' then
timedata.startpoint = q.P580[1].datavalue.value
timedata.timestamp = q.P580[1].datavalue.value.time
end
if q.P585 and q.P585[1].snaktype == 'value' then
timedata.timepoint = q.P585[1].datavalue.value
timedata.timestamp = q.P585[1].datavalue.value.time
end
return timedata
end
function p.claimwithdate(claim, displayparams) -- format an avent with date todo: define displayformats
if not claim then
return nil
end
local timedata = p.getdate(claim)
if timedata then
return wikidata.formatStatement(claim, displayparams) .. ' ' .. linguistic.inparentheses(daterange.wikibasedaterange(timedata, displayparams.lang), displayparams.lang)
end
return wikidata.formatStatement(claim, displayparams)
end
function p.isa(frame)
local item = frame.args.item or frame.args[1]
local target = frame.args.target or frame.args[2]
mw.log(item)
mw.log(target)
return ppath.matches(item, "P31/P27*", target)
end
return p