Модуль:Wikidata/Boundaries
Перейти к навигации
Перейти к поиску
local WDS = require( 'Module:WikidataSelectors' );
local p = {};
local function min( prev, next )
if ( prev == nil ) then return next;
elseif ( prev > next ) then return next;
else return prev; end
end
local function max( prev, next )
if ( prev == nil ) then return next;
elseif ( prev < next ) then return next;
else return prev; end
end
function p.getTimeBoundariesFromProperty( frame, context, propertyId )
mw.log( 'Get time boundaries for ' .. propertyId .. '...');
local dateClaims = WDS.filter( context.entity.claims, propertyId );
if ( not dateClaims or #dateClaims == 0 ) then return nil; end
mw.log( 'Get time boundaries for ' .. propertyId .. '... Got ' .. #dateClaims .. ' date claim(s)');
-- only support exact date so far, but need improvment
local left = nil;
local right = nil;
for _, claim in pairs( dateClaims ) do
if ( not claim.mainsnak ) then return nil; end
local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak );
if ( not boundaries ) then return nil; end
left = min( left, boundaries[1] );
right = max( right, boundaries[2] );
end
if ( not left or not right ) then return nil; end
mw.log( 'Time boundaries for ' .. propertyId .. ' are ' .. left .. ' and ' .. right );
return { left, right };
end
function p.getTimeBoundariesFromProperties( frame, context, propertyIds )
for _, propertyId in ipairs( propertyIds ) do
local result = p.getTimeBoundariesFromProperty( frame, context, propertyId );
if result then
return result;
end
end
return nil;
end
function p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId )
-- only support exact date so far, but need improvment
local left = nil;
local right = nil;
mw.logObject( statement, 'statement' )
mw.logObject( qualifierId, 'qualifierId' )
if ( statement.qualifiers and statement.qualifiers[qualifierId] ) then
mw.logObject( statement.qualifiers[qualifierId], 'statement.qualifiers[qualifierId]' )
for _, qualifier in pairs( statement.qualifiers[qualifierId] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier );
mw.logObject( qualifier, 'qualifier' )
mw.logObject( boundaries, 'boundaries' )
if ( not boundaries ) then return nil; end
left = min( left, boundaries[1] );
right = max( right, boundaries[2] );
end
end
if ( not left or not right ) then
return nil;
end
return { left, right };
end
function p.getTimeBoundariesFromQualifiers( frame, context, statement, qualifierIds )
for _, qualifierId in ipairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( frame, context, statement, qualifierId );
if result then
return result;
end
end
return nil;
end
function p.getParentsInBoundariesSnakImpl( frame, context, entity, boundaries, propertyIds )
local results = {};
if not propertyIds or #propertyIds == 0 then
return results;
end
if entity.claims then
for _, propertyId in ipairs( propertyIds ) do
local filteredClaims = WDS.filter( entity.claims, propertyId .. '[rank:preferred, rank:normal]' );
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries or not propertyIds or #propertyIds == 0 then
table.insert( results, claim.mainsnak );
else
local startBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P580' );
local endBoundaries = getTimeBoundariesFromQualifiers( context, claim, 'P582' );
if ( (startBoundaries == nil or startBoundaries[2] <= boundaries[1] )
and ( endBoundaries == nil or endBoundaries[1] >= boundaries[2] ) ) then
table.insert( results, claim.mainsnak );
end
end
end
end
if #results > 0 then
break;
end
end
end
return results;
end
function p.getParentsInBoundariesSnak( frame, context, entity, boundaries )
if ( not entity ) then error('entity must be specified'); end
if ( type(entity) ~= 'table' ) then error('entity must be table'); end
if ( not boundaries ) then error('boundaries must be specified'); end
if ( type(boundaries) ~= 'table' ) then error('boundaries must be table'); end
local results = p.getParentsInBoundariesSnakImpl( frame, context, entity, boundaries, {'P131'} ) -- located in
if not results or #results == 0 then
results = p.getParentsInBoundariesSnakImpl( frame, context, entity, boundaries, {'P17'} ) -- country
end
for r, result in pairs( results ) do
if result.snaktype ~= 'value' then
return nil;
end
local resultId = 'Q' .. result.datavalue.value['numeric-id'];
if ( resultId == entity.id ) then
return nil;
end
end
return results;
end
-- get current of historic name of place
function p.getLabel( frame, context, entity, boundaries )
if not entity then
return nil;
end
local lang = mw.language.getContentLanguage();
local langCode = lang:getCode();
-- name from label
-- TODO: lang:getFallbackLanguages()
local label = nil;
if entity.labels then
if entity.labels[langCode] and entity.labels[langCode].value then
label = entity.labels[langCode].value;
elseif entity.labels.en and entity.labels.en.value then
label = entity.labels.en.value;
end
end
-- name from properties
local results = p.getParentsInBoundariesSnakImpl( frame, context, entity, boundaries, {
'P1813[language:' .. langCode .. ']',
'P1448[language:' .. langCode .. ']',
'P1705[language:' .. langCode .. ']'
} );
for r, result in pairs( results ) do
if result.datavalue
and result.datavalue.value
and result.datavalue.value.text then
label = result.datavalue.value.text;
break;
end
end
return label;
end
return p;