Aller au contenu

« Module:Wikidata » : différence entre les versions

De Wreck
Modèle:Infobox>Zolo
Aucun résumé des modifications
Modèle:Infobox>Zolo
bugfixes, modularisation, option pour retourner une date en format table
Ligne 1 : Ligne 1 :
--script that retries basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua
--script that retrieves basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua


local p = {}
local p = {}
Ligne 19 : Ligne 19 :
         ["value-module-not-found"] = "The module pointed by value-module not found.",
         ["value-module-not-found"] = "The module pointed by value-module not found.",
         ["value-function-not-found"] = "The function pointed by value-function not found.",
         ["value-function-not-found"] = "The function pointed by value-function not found.",
         ["ambigous"] = "Ambigu : plusieurs valeurs possible",
         ["ambigous"] = "Ambigu : plusieurs valeurs possibles",
     },
     },
     ["somevalue"] = "inconnu",
     ["somevalue"] = "inconnu",
     ["novalue"] = "pas de données"
     ["novalue"] = "pas applicable"
}
}


Ligne 28 : Ligne 28 :
function getEntityFromId( id )
function getEntityFromId( id )
     return mw.wikibase.getEntity() --TODO support for getting other entities
     return mw.wikibase.getEntity() --TODO support for getting other entities
end
function getId( id ) -- gets the ID of the page
entity =  getEntityFromId( id )
return  entity.id
end
end


Ligne 57 : Ligne 52 :
     end
     end
claims = entity.claims[property]
claims = entity.claims[property]
if args.excludespecial == 'true' then
if args.excludespecial == 'true' then
    oldclaims = claims
claims = p.excludespecial(claims)
    claims = {}
    for i, statement in pairs(oldclaims) do
    if statement.mainsnak.snaktype == 'value' then
    table.insert(claims, statement)
    end
end
end
end
if args.targetvalue then
if args.targetvalue then
targetvalue = args.targetvalue
claims = p.withtargetvalue(claims, args.targetvalue)
oldclaims = claims
end
claims = {}
if args.qualifier then
for i, statement in pairs(oldclaims) do
claims = p.withqualifier(claims, args.qualifier, args.qualifiervalue)
if p.getDatavalue(statement.mainsnak, 'raw') == targetvalue then
end
if args.source then
claims = p.withsource(claims, args.source, args.sourproperty)
end
return claims
end
 
function p.excludespecial(claims)
local oldclaims = claims
    local claims = {}
    for i, statement in pairs(oldclaims) do
    if statement.mainsnak.snaktype == 'value' then
    table.insert(claims, statement)
    end
end
return claims
end
 
function p.withtargetvalue(claims, targetvalue)
local oldclaims = claims
    local claims = {}
    for i, statement in pairs(oldclaims) do
if p.getRawvalue(statement.mainsnak) == targetvalue then
table.insert(claims, statement)
table.insert(claims, statement)
end
end
end
end
end
if args.qualifier then -- ne marche que pour les propriétés de type item
return claims
qualifier = args.qualifier
end
qualifiervalue = args.qualifiervalue
 
oldclaims = claims
function p.withqualifier(claims, qualifier, qualifiervalue)
claims = {}
local oldclaims = claims
for i, statement in pairs(oldclaims) do
    local claims = {}
if statement.qualifiers and statement.qualifiers[qualifier] then
    for i, statement in pairs(oldclaims) do
if qualifiervalue then
if statement.qualifiers and statement.qualifiers[qualifier] then
for j, qualif in pairs(statement.qualifiers[qualifier]) do
if qualifiervalue then
if p.getDatavalue(qualif, 'raw') == qualifiervalue then  
for j, qualif in pairs(statement.qualifiers[qualifier]) do
table.insert(claims, statement)
if p.getRawvalue(qualif) == qualifiervalue then  
end
table.insert(claims, statement)
end
end
else
table.insert(claims, statement)
end
end
else
table.insert(claims, statement)
end
end
end
end
end
end
if args.source then
return claims
if args.sourceproperty then
end
sourceproperty = args.sourceproperty
 
else
function p.withsource(claims, source, sourceproperty)
sourceproperty = "p248"
local oldclaims = claims
end
local claims = {}
sourcevalue  = args.source
if not sourceproperty then
oldclaims = claims
sourceproperty = 'p248' -- stated in
claims = {}
end
for i, statement in pairs(oldclaims) do
for i, statement in pairs(oldclaims) do
if statement.references then
if statement.references then
for j, reference in pairs(statement.references) do
for j, reference in pairs(statement.references) do
for k, prop in pairs(reference.snaks) do
for prop, content in pairs(reference.snaks) do
if k == sourceproperty then
if prop == sourceproperty then
for l, m in pairs(prop) do
for l, m in pairs(content) do
if p.getDatavalue(m) == "Q" .. sourcevalue then
if p.getRawvalue(m) == source then
table.insert(claims, statement)
table.insert(claims, statement)
end
end
end
end
end
Ligne 120 : Ligne 128 :
end
end
end
end
end
end
return claims
return claims
end
function p.getRawvalue(snak)
return p.getDatavalue(snak, 'raw')
end  
end  


function p.getDatavalue(snak, formatting)
function p.getDatavalue(snak, formatting)
if snak.snaktype ~= 'value' then
return nil
end
datatype = snak.datavalue.type
datatype = snak.datavalue.type
Ligne 158 : Ligne 172 :
elseif claims == {} then  
elseif claims == {} then  
return 0
return 0
elseif claims[0] then -- table Wikibase non modifiée avec une clé 0 (buggy)
elseif claims[0] then -- table Wikibase non modifiée avec une clé 0
return #claims + 1
return #claims + 1
else
else
return #claims
return #claims
end
end
end
function p.numOfClaims(frame)
    return numOfClaims( p.getClaims(frame.args) )
end
end


Ligne 248 : Ligne 266 :
end
end


function p.formatTimevalue(value, formatting) -- exemple format Wikibase "datavalue.value.time: +00000001809-02-12T00:00:00Z"
function p.formatTimevalue(value, formatting) -- exemple de format Wikibase : "datavalue.value.time: +00000001809-02-12T00:00:00Z"
d = value.time
local d = value.time
precision = value.precision
local precision = value.precision
calendar = 'gregorian' -- calendar for display, not storage
local calendar = 'gregorian' -- calendar for display, not storage
if value.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
if value.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
calendar = 'julian'
calendar = 'julian'
end
local era = '+' -- (after Christ)
if string.sub(d,1,1) == '-' or  string.sub(d,2,12) == '00000000000' then  -- Before Christ or year 0 (see datamodel)
era = '-'
end
local year = nil
if precision >= 9 then
year = string.sub(d, 9, 12)
if era == '-' then -- remove one Year for BC years because of year 0
year = tostring(tonumber(year) + 1)
end
end
era = ''
end
if string.sub(d,1,1) == '-' or  string.sub(d,2,12) == '00000000000' then  -- Before Christ or year 0 (see datamodel)
local month = nil
era = '-'
if precision >= 10 then
end  
month = string.sub(d, 14, 15)
year = ''
end
if precision >= 9 then
local day = nil
year = string.sub(d, 9, 12)
if precision >= 11 then
if era == '-' then -- remove one Year for BC years because of year 0 in the datamodel
day = string.sub(d, 17, 18)
year = tostring(tonumber(year) + 1)
end
end
end
-- formats qui retournent une date en calendrier grégorien
month = ''
if formatting == 'raw' then -- allows easy comparisons  
if precision >= 10 then
return d  
month = string.sub(d, 14, 15)
elseif formatting ==  'ISO' then -- only defined for years > 1582
end
if era == '+' and year > 1582 then
day = ''
if precision >= 11 then
day = string.sub(d, 17, 18)
end
if formatting == 'raw' then -- allows easy comparisons  
return d  
elseif formatting ==  'ISO' then -- only defined for years > 1582
return formatDate.dateISO({annee=year, mois=month, jour=day})
return formatDate.dateISO({annee=year, mois=month, jour=day})
else
else
if calendar =='julian' then
return "date non valide en format ISO"
local y, m, d = formatDate.gregorianToJulian( era .. year, month, day )
end
return formatDate.modeleDate{ d, m, y }
end
else
return formatDate.modeleDate({day, month, era .. year})
-- formats qui retournent une date dans le calendrier précisé sur Wikidata
end
if calendar =='julian' then
year, month, day = formatDate.gregorianToJulian( era .. year, month, day )
end
if formatting == 'datetable' then
return {day= day, month=month, year=year, precision=precision, calendar=calendar}
else -- formate la date en format Wiki
return formatDate.modeleDate{ day, month, era .. year }
end
end
end
end
function p.id(frame)
        return getId(frame.args[1])
end
function p.numOfClaims(frame)
    return numOfClaims( p.getClaims(frame.args) )
end


return p
return p

Version du 4 octobre 2013 à 10:32

La documentation pour ce module peut être créée à Module:Wikidata/doc

--script that retrieves basic data stored in Wikidata, for the datamodel, see https://www.mediawiki.org/wiki/Extension:Wikibase_Client/Lua

local p = {}

local formatDate = require( 'Module:Date')
local formatCoord = require( 'Module:Coordinates')
local Outils = require( 'Module:Outils' )

local i18n = {
    ["errors"] = {
        ["property-param-not-provided"] = "Paramètre propriété non renseigné.",
        ["qualifier-param-not-provided"] = "Paramètre qualifier non renseigné.",
        ["entity-not-found"] = "Entité non trouvée.",
        ["unknown-claim-type"] = "type d'affirmation inconnu.",
        ["unknown-snak-type"] = "Type de snak inconnu.",
        ["unknown-datavalue-type"] = "Type de donnée non reconnu.",
        ["unknown-entity-type"] = "Type d'entité non reconnu.",
        ["unknown-value-module"] = "You must set both value-module and value-function parameters.",
        ["value-module-not-found"] = "The module pointed by value-module not found.",
        ["value-function-not-found"] = "The function pointed by value-function not found.",
        ["ambigous"] = "Ambigu : plusieurs valeurs possibles",
    },
    ["somevalue"] = "inconnu",
    ["novalue"] = "pas applicable"
}


function getEntityFromId( id )
    return mw.wikibase.getEntity() --TODO support for getting other entities
end

function formatError( key )
    return '<span class="error">' .. i18n.errors[key] .. '</span>'
end

function p.getClaims( frame ) -- returns a table of the claims matching some conditions given in args
	local args = Outils.extractArgs( frame )
    if not args.property then
        return formatError( 'property-param-not-provided' )
    end
    --Get entity
    local entity = nil
    local property = string.lower(args.property)
    if args.entity and type( args.entity ) == "table" then
        entity = args.entity
    else
        entity = getEntityFromId( args.entityId )
    end

    if not entity or not entity.claims or not entity.claims[property] then
        return nil
    end
	claims = entity.claims[property]
	if args.excludespecial == 'true' then
		claims = p.excludespecial(claims)
	end
	if args.targetvalue then
		claims = p.withtargetvalue(claims, args.targetvalue)
	end
	if args.qualifier then
		claims = p.withqualifier(claims, args.qualifier, args.qualifiervalue)
	end
	if args.source then 
		claims = p.withsource(claims, args.source, args.sourproperty)
	end
	return claims
end

function p.excludespecial(claims)
	local oldclaims = claims
    local claims = {}
    for i, statement in pairs(oldclaims) do
    	if statement.mainsnak.snaktype == 'value' then
    		table.insert(claims, statement)
    	end
	end
	return claims
end

function p.withtargetvalue(claims, targetvalue)
	local oldclaims = claims
    local claims = {}
    for i, statement in pairs(oldclaims) do
		if p.getRawvalue(statement.mainsnak) == targetvalue then
				table.insert(claims, statement)
		end
	end
	return claims
end

function p.withqualifier(claims, qualifier, qualifiervalue)
	local oldclaims = claims
    local claims = {}
    for i, statement in pairs(oldclaims) do
		if statement.qualifiers and statement.qualifiers[qualifier] then
			if qualifiervalue then
				for j, qualif in pairs(statement.qualifiers[qualifier]) do
					if p.getRawvalue(qualif) == qualifiervalue then 
						table.insert(claims, statement)
					end
				end
			else
				table.insert(claims, statement) 
			end
		end
	end
	return claims
end

function p.withsource(claims, source, sourceproperty)
	local oldclaims = claims
	local claims = {}
	if not sourceproperty then 
		sourceproperty = 'p248' -- stated in 
	end
	for i, statement in pairs(oldclaims) do
		if statement.references then
			for j, reference in pairs(statement.references) do
				for prop, content in pairs(reference.snaks) do
					if prop == sourceproperty then
						for l, m in pairs(content) do
							if p.getRawvalue(m) == source then
								table.insert(claims, statement)
							end
						end
					end
				end
			end
		end
	end
	return claims
end

function p.getRawvalue(snak)
	return p.getDatavalue(snak, 'raw')
end 

function p.getDatavalue(snak, formatting)
	if snak.snaktype ~= 'value' then 
		return nil
	end
	datatype = snak.datavalue.type
	
	if datatype == 'wikibase-entityid' then
		if formatting == 'raw' then 
			return "Q" .. tostring(snak.datavalue.value['numeric-id'])
		else
			return p.formatEntityId("Q" .. tostring(snak.datavalue.value['numeric-id']))
		end
		
	elseif datatype == 'string' then
		return snak.datavalue.value
		
	elseif datatype == 'time' then -- format example: +00000001809-02-12T00:00:00Z
		return p.formatTimevalue(snak.datavalue.value, formatting)

	elseif datatype == 'globecoordinate' then
		latitude = tostring(snak.datavalue.value.latitude)
		longitude = tostring(snak.datavalue.value.longitude)
		-- precision = snak.datavalue.value.precision
		--globe =  to do transform string like http://www.wikidata.org/entity/Q2 into the globe parameter of Module:Coordinates
		coordparam = {latitude,  longitude}
		return formatCoord.coord(coordparam)
		
	else return formatError( 'unknown-datavalue-type' )
	end
end

function numOfClaims( claims )
	if type(claims) ~= "table" then
		return 0
	elseif claims == {} then 
		return 0
	elseif claims[0] then -- table Wikibase non modifiée avec une clé 0
		return #claims + 1
	else
	return #claims
	end
end

function p.numOfClaims(frame)
    return numOfClaims( p.getClaims(frame.args) )
end

function p.getQualifier( frame )
	local args = Outils.extractArgs( frame )
	claims = p.getClaims( args )
	if args.qualifier then
		qualifier = args.qualifier
	else
		return formatError( 'qualifier-param-not-provided' )
	end
	if not claims or numOfClaims(claims) == 0 then
		return nil
	else 
		result = {}
		for i, j in pairs(claims) do
			for k, l in pairs( j.qualifiers[qualifier] ) do
				table.insert(result, p.getDatavalue(l, 'standard'))
			end
		end
	end
	return mw.text.listToText(result)
end

function p.formatStatements( frame )--Format statement and concat them cleanly
	local args = Outils.extractArgs( frame )
	local formattedStatements = {}
	local rawStatements = p.getClaims( args )
	if notrawStatements or numOfClaims(rawStatements) == 0 then
			return nil
	end
    for i, statement in pairs( rawStatements ) do
        if args.rank == 'one' then
            return formatStatement( statement, args ) --Output only one value
        else
            table.insert( formattedStatements, formatStatement( statement, args ) )
        end
    end
    return mw.text.listToText( formattedStatements, args.separator, args.conjunction )
end

function formatStatement( statement, args )
    if not statement.type or statement.type ~= 'statement' then
        return formatError( 'unknown-claim-type' )
    end

    mainsnak = p.formatSnak( statement.mainsnak, args )
    
    if args.showqualifiers then -- to be improved
    	qualifier = args.showqualifiers 
    	if statement.qualifiers and statement.qualifiers[qualifier] then
    		qualifvalues = {}
    		for i, j in pairs (statement.qualifiers[qualifier]) do
    			table.insert(qualifvalues, p.getDatavalue(j))
    		end
    		return mainsnak .. ' (' .. mw.text.listToText(qualifvalues) .. ')'
    	end
    end
    return mainsnak
end

function p.formatSnak( snak, args )
    if snak.snaktype == 'somevalue' then
        return i18n['somevalue']
    elseif snak.snaktype == 'novalue' then
        return i18n['novalue']
    elseif snak.snaktype == 'value' then
        return p.getDatavalue( snak, args.formatting)
    else
        return formatError( 'unknown-snak-type' )
    end
end

function p.formatEntityId( entityId, formatting )
	local label = mw.wikibase.label( entityId )
    if not label then
    	label = entityId --TODO what if no links and label + fallback language?
    end
    local link = mw.wikibase.sitelink( entityId )
    if link then
            return '[[' .. link .. '|' .. label .. ']]'
    else
        return '[[wikidata:' ..  entityId .. '|' .. label .. ']]'
    end
end

function p.formatTimevalue(value, formatting) -- exemple de format Wikibase : "datavalue.value.time: +00000001809-02-12T00:00:00Z"
	local d = value.time
	local precision = value.precision
	local calendar = 'gregorian' -- calendar for display, not storage
	if value.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
		calendar = 'julian'
	end
	local era = '+' -- (after Christ)
	if string.sub(d,1,1) == '-' or  string.sub(d,2,12) == '00000000000' then  -- Before Christ or year 0 (see datamodel)
		era = '-' 
	end 
	local year = nil
	if precision >= 9 then 
		year = string.sub(d, 9, 12)
		if era == '-' then -- remove one Year for BC years because of year 0
			year = tostring(tonumber(year) + 1)
		end
	end
	local month = nil
	if precision >= 10 then
		month = string.sub(d, 14, 15)
	end
	local day = nil
	if precision >= 11 then
		day = string.sub(d, 17, 18)
	end
	
	-- formats qui retournent une date en calendrier grégorien
	if formatting == 'raw' then -- allows easy comparisons 
		return d 
	elseif formatting ==  'ISO' then -- only defined for years > 1582
		if era == '+' and year > 1582 then
			return formatDate.dateISO({annee=year, mois=month, jour=day})
		else
			return "date non valide en format ISO"
		end
	end
	
	-- formats qui retournent une date dans le calendrier précisé sur Wikidata
	if calendar =='julian' then
		year, month, day = formatDate.gregorianToJulian( era .. year, month, day )
	end
	if formatting == 'datetable' then
		return {day= day, month=month, year=year, precision=precision, calendar=calendar}
	else -- formate la date en format Wiki
		return formatDate.modeleDate{ day, month, era .. year }
	end
end

return p