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

De Lagny-sur-Marne Wiki
Aller à : navigation, rechercher
(Annulation des modifications 118504918 de Zolo (d))
Ligne 3 : Ligne 3 :
 
local basic = require "Module:Wikibase"
 
local basic = require "Module:Wikibase"
 
local entities = require "Module:Wikidata/Formatage entité"
 
local entities = require "Module:Wikidata/Formatage entité"
 +
local datemod = require "Module:Date complexe"
  
 
local function severalProperties(args)
 
local function severalProperties(args)
Ligne 16 : Ligne 17 :
  
 
function notSpecial(claim)
 
function notSpecial(claim)
return basic.isValue(claim.mainsnak)
+
return basic.isValue(claim.mainsnak)
 
end
 
end
  
Ligne 147 : Ligne 148 :
 
     end
 
     end
 
     return newclaims
 
     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 basic.isValue(vals[1]) then
 +
return basic.getValue(vals[1]).time
 +
end
 +
end
 
end
 
end
  
 
local function chronosort(claims, inverted)
 
local function chronosort(claims, inverted)
local function getTimestamp(claim)
+
table.sort(
local claimqualifs = claim.qualifiers
+
claims,
if not claimqualifs then
+
function(a,b)
return nil
+
local timeA = valinQualif(a, datequalifiers) or ''
end
+
local timeB = valinQualif(b, datequalifiers) or ''
for _, qualif in pairs(datequalifiers) do
+
if inverted then
local vals = claimqualifs[qualif]
+
return timeA < timeB -- marche sauf pour les dates < 10 000 av-JC utiliser datemod.before produit un bug
if vals and basic.isValue(vals[1]) then
+
else
return basic.getValue(vals[1]).time
+
return timeB > timeA
 
end
 
end
end
 
end
 
table.sort(claims, function(a,b)
 
local timeA = getTimestamp(a) or ''
 
local timeB = getTimestamp(b) or ''
 
if inverted then
 
return timeA > timeB
 
else
 
return timeB > timeA
 
end
 
 
end
 
end
 
)
 
)
 
return claims
 
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
 
end
  
Ligne 189 : Ligne 202 :
 
return claims
 
return claims
 
end
 
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
 
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 filters = { -- liste des arguments déclenchat un filtre des données
+
local newclaims = {}
    --[numéro] = {
+
for i, claim in pairs(claims) do
    --param déclencheue,
+
if filterfunction(claim, args[funargs[1]], args[funargs[2]], args[funargs[3]]) then
    -- fonction à utiliser,
+
table.insert(newclaims, claim)
    -- {paramètres à utiliser}
 
[1] = {
 
'targetvalue',
 
hastargetvalue,
 
{'targetvalue'}
 
},
 
[3] = {
 
'qualifier',
 
hasqualifier,
 
{'qualifier', 'qualifiervalue'}
 
},
 
[4] = {
 
'source',
 
hassource,
 
{'source', 'sourceproperty'}
 
},
 
[5] = {
 
'withdate',
 
hasdate,
 
{},
 
},
 
[6] = {
 
'excludespecial',
 
notSpecial,
 
{},
 
},
 
[7] = { --vers la fin, peut-être coûteux
 
'withlink',
 
haslink,
 
{'withlink', 'linklang'},
 
},
 
}
 
for i, filter in pairs(filters) do
 
if args[filter[1]] then
 
local newclaims = {}
 
local filterfun = filter[2]
 
local filterarg1, filterarg2, filterarg3 = args[filter[3][1]], args[filter[3][2]], args[filter[3][3]]
 
for pos, claim in pairs(claims) do
 
if filterfun(claim, filterarg1, filterarg2, fiterarg3) == true then
 
table.insert(newclaims, claim)
 
end
 
 
end
 
end
claims = newclaims
 
 
end
 
end
 +
for i, j in pairs(newclaims) do if type(j) == nil then return error(i) end end
 +
claims = newclaims
 
end
 
end
+
 
 +
filter('targetvalue', hastargetvalue, {'targetvalue'} )
 +
filter('atdate', atDate, {'atdate'} )
 +
filter('qualifier', hasqualifier, {'qualifier', 'qualifiervalue'} )
 +
filter('source', hassource, {'source', 'sourceproperty'} )
 +
filter('withdate', hasdate, {} )
 +
filter('targetvalue', hastargetvalue, {'targetvalue'} )
 +
filter('excludespecial', notSpecial, {} )
 +
filter('withlink', haslink, {'withlink', 'linklang'} )
 +
 
 
claims = withrank(claims, args.rank or 'best')
 
claims = withrank(claims, args.rank or 'best')
 
if args.sorttype then
 
if args.sorttype then

Version du 9 septembre 2015 à 22:13

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

local p = {}
local datequalifiers = {'P585', 'P571', 'P580', 'P582'}
local basic = require "Module:Wikibase"
local entities = require "Module:Wikidata/Formatage entité"
local datemod = require "Module:Date complexe"

local function severalProperties(args)
	local newargs = args
	for i, j in pairs(args.property) do
		newargs.property = j
		local claims = p.getClaims(newargs)
		if claims then
			return claims
		end
	end
end

function notSpecial(claim)
	return basic.isValue(claim.mainsnak)
end

local function hastargetvalue(claim, target)
	return basic.getMainId(claim) == target
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, qualifier, qualifiervalues)
	local claimqualifs = claim.qualifiers
   	if (not claimqualifs) or not(claimqualifs[qualifier]) then
   		return false
   	end

   	if (not qualifiervalues) or (qualifiervalues == {}) then
   		return true -- si aucune valeur spécifique n'est exigée, c'est bon
   	end

   if type(qualifiervalues) == 'string' then
   		qualifiervalues = {qualifiervalues}
   	end

   	for i, j in pairs(claim.qualifiers[qualifier]) do
   		local val = basic.getId(j)
   		for k, l in pairs(qualifiervalues) do
   			if l == val then
   				return true
   			end
   		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
	for _, source in pairs(claim.references[sourceproperty]) do
		if basic.getId(source) == targetsource then
			return true
		end
	end
	return true
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(basic.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 = basic.getMainId(claim)
	local link = entities.getLink(id, site, lang)
	if link then
		return true
	end
end

local function isinlanguage(snak, lang) -- ne fonctionne que pour les monolingualtext / étendre aux autres types en utilisant les qualifiers ?
	if basic.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 basic.isValue(vals[1]) then
			return basic.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

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('atdate', atDate, {'atdate'} )
	filter('qualifier', hasqualifier, {'qualifier', 'qualifiervalue'} )
	filter('source', hassource, {'source', 'sourceproperty'} )
	filter('withdate', hasdate, {} )
	filter('targetvalue', hastargetvalue, {'targetvalue'} )
	filter('excludespecial', notSpecial, {} )
	filter('withlink', haslink, {'withlink', 'linklang'} )

	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.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
	if not args.property then
	return error( 'property-param-not-provided' )
	end
	if type(args.property) == 'table' then
		return severalProperties(args)
	end
	--Get entity
	local entity = args.entity
 	if type(entity) ~= 'table' then
        entity = mw.wikibase.getEntityObject( args.entity )
    end
	if (not entity) or (not entity.claims) then
		return nil
	end
	local property = string.upper(args.property)
	if not entity.claims[property] then
		return nil
	end
	local claims = entity.claims[property]
	if not claims then
		return nil
	end
	return p.filterClaims(claims, args)
end

return p