שינויים
קפיצה לניווט
קפיצה לחיפוש
מ
אין תקציר עריכה
--[[
Cross validation with wikidata: parse the wikitext of a value related to wikidata and see if they are close enough.
]]
local Date = require('יחידה:תאריך')
local CrossValidate = {}
CrossValidate.CrossValidateResult = {
INVALID_WIKITEXT='לא ידוע', --wikitext is empty or too complex
MISSING_WIKIDATA='חסר', -- data doesnt exist in wikidata (no entity/no claim)
INCOMPATIBLE='לא מתאים',
COMPATIBLE='מתאים',
MISSING_WIKIDATA_LABEL='חסרה תווית עברית'
}
function CrossValidate.maintainceCategory(value, propertyName)
if value==CrossValidate.CrossValidateResult.INVALID_WIKITEXT then return '' end
return '[[קטגוריה: ויקינתונים - השוואת ערכים: ' .. value.. ']]' .. '[[קטגוריה: ויקינתונים - השוואת ערכים: ' .. value.. ': '..(mw.wikibase.label( propertyName) or propertyName)..']]'
end
--function CrossValidate.crossValidate( wikitext, propertyName, allowMulti, allowNA, entityId, multiSeperator, optionalQualifier, genderAware )
function CrossValidate.crossValidate( wikitext, propertyName, entityId )
if wikitext == nil or wikitext == '-' or #wikitext ==0 or propertyName ==nil or #propertyName==0 then
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- comparing to null wikitext is meaningless
end
if entityId == nil then
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
if entityId == nil then
if mw.title.getCurrentTitle().namespace==0 then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA
else
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
end
local propertyVals = mw.wikibase.getBestStatements(entityId, propertyName)
if (not propertyVals) or (#propertyVals==0) then return CrossValidate.CrossValidateResult.MISSING_WIKIDATA end --no such property for this item
-- parsing the wikidata value gives similar result to wikitext
local formattedValue = require('Module:PropertyLink').getPropertyByOptions(propertyName, entityId, {allowMulti=1 })
if formattedValue == wikitext then
return CrossValidate.CrossValidateResult.COMPATIBLE
else
-- try to remove links
if mw.ustring.gsub(wikitext, '[%[%]]', '') == formattedValue or mw.ustring.gsub(wikitext, '%[%[[^%|%[%]]+%|(.+)%]%]', '%1') == formattedValue then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
end
local resTable = {}
for i, property in ipairs(propertyVals) do
local propValue = property.mainsnak and property.mainsnak.datavalue
if not propValue then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA -- no value/someone etc are considered as missing
end
if propValue['type'] == 'wikibase-entityid' then
local localLabel, langLabel = mw.wikibase.getLabelWithLang( "Q" .. propValue.value['numeric-id'] )
local isLocalLabel = langLabel=='he'
if not isLocalLabel then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA_LABEL
end
local isCompatible = mw.ustring.find(wikitext, localLabel, 1, true)
if not isCompatible then
local sitelink = mw.wikibase.sitelink( "Q" .. propValue.value['numeric-id'] )
isCompatible = sitelink and mw.ustring.find(wikitext, sitelink, 1, true)
end
if not isCompatible then
local entityObject = mw.wikibase.getEntity( "Q" .. propValue.value['numeric-id'] )
local entityAliases = entityObject and entityObject.aliases and entityObject.aliases['he']
if entityAliases then
for _, curAlias in ipairs(entityAliases) do
isCompatible = isCompatible or mw.ustring.find(wikitext, curAlias.value, 1, true)
end
end
end
if not isCompatible then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
elseif propValue['type'] == 'string' then
local isImage = (property.mainsnak.datatype=='commonsMedia')
if isImage then
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- images are too complex
else
if not (mw.ustring.find(wikitext, propValue.value, 1, true)) then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
end
elseif propValue['type'] == 'monolingualtext' then
if not mw.ustring.find(wikitext, propValue.value.text, 1, true) then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
elseif propValue['type'] == 'quantity' then
local noramlizeUnit = mw.ustring.gsub(wikitext, '[%[%]]', '')
noramlizeUnit = mw.ustring.gsub(noramlizeUnit, '(.+) מטרים', '%1 מטר')
noramlizeUnit = mw.ustring.gsub(noramlizeUnit, '(.+) ק"ג$', '%1 קילוגרם')
if noramlizeUnit == formattedValue then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
if mw.ustring.match(noramlizeUnit, '^[%d.,]+ מטר$') then
local ConvertModule = require('Module:Convert')
local success, wikidataMeter = pcall(ConvertModule.convert, mw.getCurrentFrame():newChild{ args = {
['input'] = propertyName,
[2] = 'מטר',
['disp'] = 'out',
['qid'] = entityId,
['abbr']='off'
} }:newChild{})
if success then
wikidataMeter = mw.ustring.gsub(wikidataMeter, '(.+) מטרים', '%1 מטר')
if wikidataMeter==noramlizeUnit then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
end
end
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- TODO: parse quantity and units
elseif propValue['type'] == 'time' then
local success, res = pcall(Date.newFromWikitext, wikitext )
if success and property.mainsnak.datavalue and property.mainsnak.datavalue.value then
local wikidataVal = Date.newFromWikidataValue(property.mainsnak.datavalue.value)
if wikidataVal.precision == res.precision then
if wikidataVal:toIso8601() == res:toIso8601() then
return CrossValidate.CrossValidateResult.COMPATIBLE
else
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
else
-- TODO: handle different precision
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
else
-- ignore parsing errors
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
else
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- ignore other types
end
end
return CrossValidate.CrossValidateResult.COMPATIBLE
end
return CrossValidate
Cross validation with wikidata: parse the wikitext of a value related to wikidata and see if they are close enough.
]]
local Date = require('יחידה:תאריך')
local CrossValidate = {}
CrossValidate.CrossValidateResult = {
INVALID_WIKITEXT='לא ידוע', --wikitext is empty or too complex
MISSING_WIKIDATA='חסר', -- data doesnt exist in wikidata (no entity/no claim)
INCOMPATIBLE='לא מתאים',
COMPATIBLE='מתאים',
MISSING_WIKIDATA_LABEL='חסרה תווית עברית'
}
function CrossValidate.maintainceCategory(value, propertyName)
if value==CrossValidate.CrossValidateResult.INVALID_WIKITEXT then return '' end
return '[[קטגוריה: ויקינתונים - השוואת ערכים: ' .. value.. ']]' .. '[[קטגוריה: ויקינתונים - השוואת ערכים: ' .. value.. ': '..(mw.wikibase.label( propertyName) or propertyName)..']]'
end
--function CrossValidate.crossValidate( wikitext, propertyName, allowMulti, allowNA, entityId, multiSeperator, optionalQualifier, genderAware )
function CrossValidate.crossValidate( wikitext, propertyName, entityId )
if wikitext == nil or wikitext == '-' or #wikitext ==0 or propertyName ==nil or #propertyName==0 then
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- comparing to null wikitext is meaningless
end
if entityId == nil then
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
if entityId == nil then
if mw.title.getCurrentTitle().namespace==0 then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA
else
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
end
local propertyVals = mw.wikibase.getBestStatements(entityId, propertyName)
if (not propertyVals) or (#propertyVals==0) then return CrossValidate.CrossValidateResult.MISSING_WIKIDATA end --no such property for this item
-- parsing the wikidata value gives similar result to wikitext
local formattedValue = require('Module:PropertyLink').getPropertyByOptions(propertyName, entityId, {allowMulti=1 })
if formattedValue == wikitext then
return CrossValidate.CrossValidateResult.COMPATIBLE
else
-- try to remove links
if mw.ustring.gsub(wikitext, '[%[%]]', '') == formattedValue or mw.ustring.gsub(wikitext, '%[%[[^%|%[%]]+%|(.+)%]%]', '%1') == formattedValue then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
end
local resTable = {}
for i, property in ipairs(propertyVals) do
local propValue = property.mainsnak and property.mainsnak.datavalue
if not propValue then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA -- no value/someone etc are considered as missing
end
if propValue['type'] == 'wikibase-entityid' then
local localLabel, langLabel = mw.wikibase.getLabelWithLang( "Q" .. propValue.value['numeric-id'] )
local isLocalLabel = langLabel=='he'
if not isLocalLabel then
return CrossValidate.CrossValidateResult.MISSING_WIKIDATA_LABEL
end
local isCompatible = mw.ustring.find(wikitext, localLabel, 1, true)
if not isCompatible then
local sitelink = mw.wikibase.sitelink( "Q" .. propValue.value['numeric-id'] )
isCompatible = sitelink and mw.ustring.find(wikitext, sitelink, 1, true)
end
if not isCompatible then
local entityObject = mw.wikibase.getEntity( "Q" .. propValue.value['numeric-id'] )
local entityAliases = entityObject and entityObject.aliases and entityObject.aliases['he']
if entityAliases then
for _, curAlias in ipairs(entityAliases) do
isCompatible = isCompatible or mw.ustring.find(wikitext, curAlias.value, 1, true)
end
end
end
if not isCompatible then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
elseif propValue['type'] == 'string' then
local isImage = (property.mainsnak.datatype=='commonsMedia')
if isImage then
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- images are too complex
else
if not (mw.ustring.find(wikitext, propValue.value, 1, true)) then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
end
elseif propValue['type'] == 'monolingualtext' then
if not mw.ustring.find(wikitext, propValue.value.text, 1, true) then
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
elseif propValue['type'] == 'quantity' then
local noramlizeUnit = mw.ustring.gsub(wikitext, '[%[%]]', '')
noramlizeUnit = mw.ustring.gsub(noramlizeUnit, '(.+) מטרים', '%1 מטר')
noramlizeUnit = mw.ustring.gsub(noramlizeUnit, '(.+) ק"ג$', '%1 קילוגרם')
if noramlizeUnit == formattedValue then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
if mw.ustring.match(noramlizeUnit, '^[%d.,]+ מטר$') then
local ConvertModule = require('Module:Convert')
local success, wikidataMeter = pcall(ConvertModule.convert, mw.getCurrentFrame():newChild{ args = {
['input'] = propertyName,
[2] = 'מטר',
['disp'] = 'out',
['qid'] = entityId,
['abbr']='off'
} }:newChild{})
if success then
wikidataMeter = mw.ustring.gsub(wikidataMeter, '(.+) מטרים', '%1 מטר')
if wikidataMeter==noramlizeUnit then
return CrossValidate.CrossValidateResult.COMPATIBLE
end
end
end
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- TODO: parse quantity and units
elseif propValue['type'] == 'time' then
local success, res = pcall(Date.newFromWikitext, wikitext )
if success and property.mainsnak.datavalue and property.mainsnak.datavalue.value then
local wikidataVal = Date.newFromWikidataValue(property.mainsnak.datavalue.value)
if wikidataVal.precision == res.precision then
if wikidataVal:toIso8601() == res:toIso8601() then
return CrossValidate.CrossValidateResult.COMPATIBLE
else
return CrossValidate.CrossValidateResult.INCOMPATIBLE
end
else
-- TODO: handle different precision
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
else
-- ignore parsing errors
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT
end
else
return CrossValidate.CrossValidateResult.INVALID_WIKITEXT -- ignore other types
end
end
return CrossValidate.CrossValidateResult.COMPATIBLE
end
return CrossValidate