Module:Wikidata/Récup : Différence entre versions

De Lagny-sur-Marne Wiki
Aller à : navigation, rechercher
(possiblité de plusieurs targetvalues)
m
Ligne 16 : Ligne 16 :
  
 
local function hastargetvalue(claim, targets)
 
local function hastargetvalue(claim, targets)
local targets = splitStr(target)
+
local targets = splitStr(targets)
 
local id = tools.getMainId(claim)
 
local id = tools.getMainId(claim)
 +
if claim.mainsnak.snaktype ~= 'value' then -- c'est excludespecial qui l'enlèvera si nécessaire
 +
return true
 +
end
 
for i, target in pairs(targets) do
 
for i, target in pairs(targets) do
 
if id == target then
 
if id == target then
Ligne 243 : Ligne 246 :
  
 
function p.filterClaims(claims, args) --retire de la tables de claims celles qui sont éliminés par un des filters de la table des filters
 
function p.filterClaims(claims, args) --retire de la tables de claims celles qui sont éliminés par un des filters de la table des filters
 
 
local function filter(condition, filterfunction, funargs)
 
local function filter(condition, filterfunction, funargs)
 
if not args[condition] then
 
if not args[condition] then
Ligne 266 : Ligne 268 :
 
filter('source', hassource, {'source', 'sourceproperty'} )
 
filter('source', hassource, {'source', 'sourceproperty'} )
 
filter('withdate', hasdate, {} )
 
filter('withdate', hasdate, {} )
filter('targetvalue', hastargetvalue, {'targetvalue'} )
 
 
filter('excludespecial', notSpecial, {} )
 
filter('excludespecial', notSpecial, {} )
 
filter('excludevalues', excludevalues, {'excludevalues'})
 
filter('excludevalues', excludevalues, {'excludevalues'})

Version du 4 avril 2016 à 14:44

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

local p = {}
local datequalifiers = {'P585', 'P571', 'P580', 'P582'}
local tools = require "Module:Wikidata/Outils"
local datemod = require "Module:Date complexe"

local function splitStr(val) -- transforme en table les chaînes venant du Wikitexte qui utilisent des virgules de séparatin
	if type(val) == 'string' then
		val = mw.text.split(val, ",")
	end
	return val
end

local function notSpecial(claim)
	return tools.isValue(claim.mainsnak)
end

local function hastargetvalue(claim, targets)
	local targets = splitStr(targets)
	local id = tools.getMainId(claim)
	if claim.mainsnak.snaktype ~= 'value' then -- c'est excludespecial qui l'enlèvera si nécessaire
		return true
	end
	for i, target in pairs(targets) do
		if id == target then
			return true
		end
	end
	return false
end

local function bestranked(claims)
	if not claims then
		return nil
	end
	local preferred, normal = {}, {}
	for i, j in pairs(claims) do
		if j.rank == 'preferred' then
			table.insert(preferred, j)
		elseif j.rank == 'normal' then
			table.insert(normal, j)
		end
	end
	if #preferred > 0 then
		return preferred
	else
		return normal
	end
end

local function withrank(claims, target)
	if target == 'best' then
		return bestranked(claims)
	end
	local newclaims = {}
	for pos, claim in pairs(claims)  do
		if target == 'valid' then
			if claim.rank ~= 'deprecated' then
				table.insert(newclaims, claim)
			end
		elseif claim.rank == target then
			table.insert(newclaims, claim)
		end
	end
	return newclaims
end

local function hasqualifier(claim, acceptedqualifs, acceptedvals, excludequalifiervalues)
	local claimqualifs = claim.qualifiers
	
	if (not claimqualifs) then
		return false
	end

	acceptedqualifs = splitStr(acceptedqualifs)
	acceptedvals = splitStr( acceptedvals)


	local function ok(qualif) -- vérification pour un qualificatif individuel
		if not claimqualifs[qualif] then
			return false
		end
		if not (acceptedvals) then  -- si aucune valeur spécifique n'est demandée, OK
			return true
		end
		for i, wanted in pairs(acceptedvals) do
			for j, actual in pairs(claimqualifs[qualif]) do
				if tools.getId(actual) == wanted then
					return true
				end
			end
		end
	end

	for i, qualif in pairs(acceptedqualifs) do
		if ok(qualif) then
			return true
		end
	end
	return false
 end

local function hassource(claim, targetsource, sourceproperty)
	sourceproperty = sourceproperty or 'P248'
	if not claim.references or not claim.references[sourceproperty] then
		return false
	end
	if not targetsource then -- si toutes les sources sont valides, du moment qu'elles utilisent sourceproperty
		return true
	end
	targetsource = splitStr(targetsource)
	for _, source in pairs(claim.references[sourceproperty]) do
		local s = tools.getId(source)
		for i, target in pairs(targetsource) do
			if s == target then return true end
		end
	end
	return true
end

local function excludequalifier(claim, qualifier, qualifiervalues)
	return not hasqualifier(claim, qualifier, qualifiervalues)
end


local function hasdate(claim)
	local claimqualifs = claims.qualifiers
	if not claimqualifs then
		return false
	end
	for _, qualif in pairs(claimqualifs) do
		if claimsqualifs[qualif] and claimsqualifs[qualif][1].snaktype == 'value' then
			return true
		end
	end
	return false
end

local function haslink(claim, site, lang)
	if not(tools.isValue(claim.mainsnak)) then -- ne pas supprimer les valeurs spéciales, il y a une fonction dédiée pour ça
		return true
	end
	local id = tools.getMainId(claim)
	local link = tools.siteLink(id, site, lang)
	if link then
		return true
	end
end

local function isinlanguage(claim, lang) -- ne fonctionne que pour les monolingualtext / étendre aux autres types en utilisant les qualifiers ?
	local snak = claim.mainsnak
	if tools.isSpecial(snak) then
		return false
	end
	if snak.datavalue.type == 'monolingualtext' and snak.datavalue.value.language == lang then
		return true
	end
	return false
end

local function firstvals(claims, numval) -- retourn les numval premières valeurs de la table claims
    local numval = tonumber(numval) or 0 -- raise a error if numval is not a positive integer ?
    if not claims then
    	return nil
    end
    if #claims <= numval then
    	return claims
    end
    local newclaims = {}
    while #newclaims < numval do
    	table.insert(newclaims, claims[#newclaims + 1])
    end
    return newclaims
end

local function valinQualif(claim, qualifs)
	local claimqualifs = claim.qualifiers
	if not claimqualifs then
		return nil
	end
	for i, qualif in pairs(qualifs) do
		local vals = claimqualifs[qualif]
		if vals and tools.isValue(vals[1]) then
			return tools.getValue(vals[1]).time
		end
	end
end

local function chronosort(claims, inverted)
	table.sort(
		claims,
		function(a,b)
			local timeA = valinQualif(a, datequalifiers) or ''
			local timeB = valinQualif(b, datequalifiers) or ''
			if inverted then
				return timeA > timeB -- marche sauf pour les dates < 10 000 av-JC utiliser datemod.before produit un bug
			else
				return timeB > timeA
			end
		end
	)
	return claims
end

local function atDate(claim, mydate)
	local newclaims = {}
	local mindate = valinQualif(claim, {'P580'}) 
	local maxdate = valinQualif(claim, {'P582'})
	if datemod.before(mydate, mindate) and datemod.before(maxdate, mydate) then
		return true
	end
end

local function excludevalues(claim, values)
	values = splitStr(values)
	local id = tools.getMainId(claim)
	for i, j in pairs(values) do
		if j == id then
			return false
		end
	end
	return true
end

local function check(claim, condition)
	if type(condition) ~= 'function' then
		return -- ? error
	end
	return condition(claim)
end

function p.sortclaims(claims, sorttype)
	if not claims then
		return nil
	end
	if sorttype == 'chronological' then
		return chronosort(claims)
	elseif sorttype == 'inverted' then
		return chronosort(claims, true)
	elseif type(sorttype) == 'function' then
		table.sort(claims, sorttype)
		return claims
	end
	return claims
end


function p.filterClaims(claims, args) --retire de la tables de claims celles qui sont éliminés par un des filters de la table des filters
	local function filter(condition, filterfunction, funargs)
		if not args[condition] then
			return
		end

		local newclaims = {}
		for i, claim in pairs(claims) do
			if filterfunction(claim, args[funargs[1]], args[funargs[2]], args[funargs[3]]) then
				table.insert(newclaims, claim)
			end
		end
		for i, j in pairs(newclaims) do if type(j) == nil then return error(i) end end
		claims = newclaims
	end

	filter('targetvalue', hastargetvalue, {'targetvalue'} )
	filter('isinlang', isinlanguage, {'isinlang'} )
	filter('atdate', atDate, {'atdate'} )
	filter('qualifier', hasqualifier, {'qualifier', 'qualifiervalue'} )
	filter('excludequalifier', excludequalifier, {'excludequalifier', 'excludequalifiervalue'} )
	filter('source', hassource, {'source', 'sourceproperty'} )
	filter('withdate', hasdate, {} )
	filter('excludespecial', notSpecial, {} )
	filter('excludevalues', excludevalues, {'excludevalues'})
	filter('withlink', haslink, {'withlink', 'linklang'} )
	filter('condition', check, {'condition'})

	claims = withrank(claims, args.rank or 'best')
	if args.sorttype then
		claims = p.sortclaims(claims, args.sorttype)
	end
	if #claims == 0 then
		return nil
	end
	if args.numval then
		claims = firstvals(claims, args.numval)
	end
	return claims

end

function p.loadEntity(entity, cache)
	if type(entity) ~= 'table' then
		if cache then
			if not cache[entity] then 
				cache[entity] = mw.wikibase.getEntity(entity)
				mw.log("cached")
     		end
			return cache[entity]
        else
        	return mw.wikibase.getEntity(entity)
        end
    else 
    	return entity
    end
end


function p.getClaims( args ) -- returns a table of the claims matching some conditions given in args
	if args.claims then -- if claims have already been set, return them
		return args.claims
	end
	local properties = splitStr(args.property)

	if not properties then
		return error( 'property-param-not-provided' )
	end

	--Get entity
	local entity = args.entity
 	entity = p.loadEntity(args.entity, args.cache)
    
	if (not entity) or (not entity.claims) then
		return nil
	end
	local claims = {}
	for i, prop in pairs(properties) do
		prop = string.upper(prop)
		for j, claim in pairs(entity.claims[prop] or {}) do
			table.insert(claims, claim)
		end
	end

	if (#claims == 0) then
		return nil
	end
	return p.filterClaims(claims, args)
end

return p