Modul:Wikidata/Filterers
Dokumentaciju za ovaj modul možete napraviti na stranici Modul:Wikidata/Filterers/dok
require "Modul:No globals"
local p = {}
local lib = require 'Modul:Wikidata/lib'
local function checkLimit(sequence, limit)
local limit = limit and tonumber(limit)
if limit then
return #sequence >= limit
end
return true
end
local function applyLimit(sequence, limit)
local limit = limit and tonumber(limit)
if limit then
while #sequence > limit do
table.remove(sequence)
end
end
return sequence
end
local function IsInLanguage(snak, lang)
if snak.datatype ~= 'monolingualtext' then
return error(lib.raiseInvalidDatatype('IsInLanguage', snak.datatype, 'monolingualtext'))
else
return lib.IsSnakValue(snak) and snak.datavalue.value.language == lang
end
end
function p.filterStatementsFromEntity(entity, options)
if not options.property or options.property == '' then
return error(lib.formatError('param-not-provided', 'property'))
end
if not entity or not entity.claims then
return {}
end
local property = mw.ustring.upper(options.property)
if not entity.claims[property] then
return {}
end
return p.filterStatements(entity.claims[property], options)
end
function p.filterStatements(statements, options)
local options = lib.common.cleanArgs(options)
local Statements, oldStatements = statements, {}
-- apply filter by rank
if not options.rank or options.rank ~= "all" then
oldStatements, Statements = Statements, {}
if not options.rank or options.rank == "best" or options.rank == "valid" then
if options.rank == "best" then
for _, statement in pairs(oldStatements) do
if statement.rank == "preferred" then
table.insert(Statements, statement)
end
end
if #Statements == 0 then
for _, statement in pairs(oldStatements) do
if statement.rank == "normal" then
table.insert(Statements, statement)
end
end
end
else
for _, statement in pairs(oldStatements) do
if statement.rank ~= "deprecated" then
table.insert(Statements, statement)
end
end
end
else
for _, statement in pairs(oldStatements) do
if statement.rank == options.rank then
table.insert(Statements, statement)
end
end
end
if #Statements == 0 then return {} end
end
-- apply filter by source
if options.ref then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.references then
if #p.filterReferences(statement.references, options) > 0 then
table.insert(Statements, statement)
end
end
end
if #Statements == 0 then return {} end
end
-- apply filter by snak type
if not lib.IsOptionTrue(options, 'showspecial') then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if lib.IsSnakValue(statement.mainsnak) then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by qualifier property
if options.withqualifier then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if statement.qualifiers and statement.qualifiers[options.withqualifier:upper()] then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by class
if options.instance then
local datatype = Statements[math.random(1, #Statements)].mainsnak.datatype
if datatype == 'wikibase-item' or datatype == 'wikibase-property' then
local Module = require 'Modul:Wikidata/Tree'
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if lib.IsSnakValue(statement.mainsnak) then
local item = lib.getEntityIdFromValue(statement.mainsnak.datavalue.value)
if Module.IsInstance(item, options) then
table.insert(Statement, statement)
end
end
end
if #Statements == 0 then return {} end
else
return error(lib.raiseInvalidDatatype('inClass', datatype, {'wikibase-item', 'wikibase-property'}))
end
end
-- apply filter by language
if options.withlang then
oldStatements, Statements = Statements, {}
for _, statement in pairs(oldStatements) do
if IsInLanguage(statement.mainsnak, options.withlang) then
table.insert(Statements, statement)
end
end
if #Statements == 0 then return {} end
end
-- apply filter by time
if options.date then
local date
local Time = require 'Modul:TimeWikiD'
if type(options.date) == 'table' then
date = options.date
elseif options.date == '#now' then
date = Time.new(os.date('!*t'))
--elseif mw.ustring.find(options.date, '^[Pp][1-9]%d-$') then TODO
else
local Time = require 'Modul:TimeWikiD'
date = Time.newFromIso8601(options.date)
end
if date then
oldStatements, Statements = Statements, {}
local temp_value
local Formatters = require 'Modul:Wikidata/Formatters'
local Date = require 'Modul:Wikidata/datum'
for _, statement in pairs(oldStatements) do
if statement.qualifiers then
local Values = {}
for key, array in pairs(lib.props) do
for _, prop in pairs(array) do
if statement.qualifiers[prop] then
for _, snak in pairs(statement.qualifiers[prop]) do
if lib.IsSnakValue(snak) then
Values[key] = Formatters.getRawValue(snak)
break
end
end
end
end
end
if Values.point then
if not Date.IsSecondLaterThanFirst(date, Values.point) then
if not temp_value then
Statements = { statement }
temp_value = Values.point
else
if Date.IsSecondLaterThanFirst(Values.point, temp_value) then
Statements = { statement }
temp_value = Values.point
elseif Date.AreDatesSame(temp_value, Values.point) then
table.insert(Statements, statement)
end
end
end
else
if Values.begin then
if Date.IsSecondLaterThanFirst(Values.begin, date) then
if not Values.ending then
table.insert(Statements, statement)
elseif Date.IsSecondLaterThanFirst(date, Values.ending) then
table.insert(Statements, statement)
end
end
elseif Values.ending then
if Date.IsSecondLaterThanFirst(date, Values.ending) then
if not Values.begin then
table.insert(Statements, statement)
elseif Date.IsSecondLaterThanFirst(Values.begin, date) then
table.insert(Statements, statement)
end
end
end
end
end
end
if #Statements == 0 then return {} end
else
return error(lib.formatError('invalid-date', options.date))
end
end
if lib.IsOptionTrue(options, 'withlabel') then
local datatype = Statements[math.random(1, #Statements)].mainsnak.datatype
if datatype == 'wikibase-item' or datatype == 'wikibase-property' then
oldStatements, Statements = Statements, {}
local Formatters = require 'Modul:Wikidata/Formatters'
for _, statement in pairs() do
if lib.IsSnakValue(statement.mainsnak) then
local value = Formatters.getRawValue(statement.mainsnak)
if mw.wikibase.label(value) then
table.insert(Statements, statement)
end
end
end
else
return error(lib.raiseInvalidDatatype('withlabel', datatype, {'wikibase-item', 'wikibase-property'}))
end
end
-- sort statements if needed
if options.sort then
local Sorters = require "Modul:Wikidata/Sorters"
Statements = Sorters.sortStatements(Statements, options)
end
-- apply filter by limit
Statements = applyLimit(Statements, options.limit)
return Statements
end
function p.filterQualifiers(qualifiers, options)
local options = lib.common.cleanArgs(options)
local Qualifiers, oldQualifiers = qualifiers, {}
if options['qualifiers withlang'] then
oldQualifiers, Qualifiers = Qualifiers, {}
for _, snak in pairs(oldQualifiers) do
if IsInLanguage(snak, options['qualifiers withlang']) then
table.insert(Qualifiers, snak)
end
end
if #Qualifiers == 0 then return {} end
end
if options['qualifiers class'] then
local datatype = Qualifiers[math.random(1, #Qualifiers)].datatype
if datatype == 'wikibase-item' or datatype == 'wikibase-property' then
oldQualifiers, Qualifiers = Qualifiers, {}
local Module = require 'Modul:Wikidata/Tree'
for _, snak in pairs(oldQualifiers) do
if lib.IsSnakValue(snak) then
local item = lib.getEntityIdFromValue(snak.datavalue.value)
if Module.IsInTree(item, options['qualifiers class'], 'P279', 20, {}) then
table.insert(Qualifiers, snak)
end
end
end
if #Qualifiers == 0 then return {} end
else
return error(lib.raiseInvalidDatatype('inClass', datatype, {'wikibase-item', 'wikibase-property'}))
end
end
if options['sort qualifiers'] then
local Sorters = require "Modul:Wikidata/Sorters"
Qualifiers = Sorters.sortQualifiers(Qualifiers, options)
end
Qualifiers = applyLimit(Qualifiers, options['qualifiers limit'])
return Qualifiers
end
function p.filterReferences(references, options)
local options = lib.common.cleanArgs(options)
if options.ref == '#any' then
return references
end
local oldReferences, References = references, {}
if options.ref == 'valid' then
local props = {'P248', 'P854'} --(require 'Modul:Wikidata/cite').props
for _, ref in pairs(oldReferences) do
for _, prop in pairs(props) do
if ref.snaks[prop] then
table.insert(References, ref)
end
end
end
end
if options.min_ref and not checkLimit(References, options.min_ref) then
return {}
end
return References
end
function p.test(id)
local entity = mw.wikibase.getEntity(id)
for prop, claim in pairs(entity.claims) do
for i, statement in pairs(claim) do
if statement.references then
mw.log(prop, i)
mw.logObject(statement.mainsnak)
mw.logObject(statement.references)
return
end
end
end
end
return p