Модуль:Вікізьвесткі/месца/Беларусь
Дакумэнтацыю да гэтага модуля можна стварыць у Модуль:Вікізьвесткі/месца/Беларусь/Дакумэнтацыя
local WDS = require('Модуль:Сьцьверджаньні Вікізьвестак');
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
local function splitISO8601(str)
if 'table' == type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'невядомы тып аргумэнту: ' .. type(str) .. ': ' .. table.tostring(str)
end
end
local Y, M, D = (function(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match(str, pattern)
return tonumber(Y), tonumber(M), tonumber(D)
end)(str);
local h, m, s = (function(str)
local pattern = "T(%d+):(%d+):(%d+)%Z";
local H, M, S = mw.ustring.match(str, pattern);
return tonumber(H), tonumber(M), tonumber(S);
end)(str);
local oh, om = (function(str)
if str:sub(-1) == "Z" then
return 0, 0
end ;
local pattern = "([-+])(%d%d):?(%d?%d?)$";
local sign, oh, om = mw.ustring.match(str, pattern);
sign, oh, om = sign or "+", oh or "00", om or "00";
return tonumber(sign .. oh), tonumber(sign .. om);
end)(str)
return { year = Y, month = M, day = D, hour = (h + oh), min = (m + om), sec = s };
end
local function parseTimeBoundaries(time, precision)
local s = splitISO8601(time);
if (not s) then
return nil;
end
if (precision >= 0 and precision <= 8) then
local powers = { 1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[precision + 1];
local left = s.year - (s.year % power);
return { tonumber(os.time({ year = left, month = 1, day = 1, hour = 0, min = 0, sec = 0 })) * 1000,
tonumber(os.time({ year = left + power - 1, month = 12, day = 31, hour = 29, min = 59, sec = 58 })) * 1000 + 1999 };
end
if (precision == 9) then
return { tonumber(os.time({ year = s.year, month = 1, day = 1, hour = 0, min = 0, sec = 0 })) * 1000,
tonumber(os.time({ year = s.year, month = 12, day = 31, hour = 23, min = 59, sec = 58 })) * 1000 + 1999 };
end
if (precision == 10) then
local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
local lastDay = lastDays[s.month];
return { tonumber(os.time({ year = s.year, month = s.month, day = 1, hour = 0, min = 0, sec = 0 })) * 1000,
tonumber(os.time({ year = s.year, month = s.month, day = lastDay, hour = 23, min = 59, sec = 58 })) * 1000 + 1999 };
end
if (precision == 11) then
return { tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = 0, min = 0, sec = 0 })) * 1000,
tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = 23, min = 59, sec = 58 })) * 1000 + 1999 };
end
if (precision == 12) then
return { tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = s.hour, min = 0, sec = 0 })) * 1000,
tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = s.hour, min = 59, sec = 58 })) * 1000 + 19991999 };
end
if (precision == 13) then
return { tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = s.hour, min = s.min, sec = 0 })) * 1000,
tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = s.hour, min = s.min, sec = 58 })) * 1000 + 1999 };
end
if (precision == 14) then
local t = tonumber(os.time({ year = s.year, month = s.month, day = s.day, hour = s.hour, min = s.min, sec = 0 }));
return { t * 1000, t * 1000 + 999 };
end
error('Дакладнасьць не падтрымліваецца: ' .. precision);
end
local function getTimeBoundariesFromProperty(context, propertyId)
local dateClaims = WDS.filter(context.entity.claims, propertyId);
if (not dateClaims or #dateClaims == 0) then
return nil;
end
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
return { left, right };
end
local function getTimeBoundariesFromProperties(context, propertyIds)
for _, propertyId in ipairs(propertyIds) do
local result = getTimeBoundariesFromProperty(context, propertyId);
if result then
return result;
end
end
return nil;
end
local function getTimeBoundariesFromQualifiers(context, statement, qualifierId)
local left = nil;
local right = nil;
if (statement.qualifiers and statement.qualifiers[qualifierId]) then
for _, qualifier in pairs(statement.qualifiers[qualifierId]) do
local boundaries = context.parseTimeBoundariesFromSnak(qualifier);
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
local function getParentsInBoundariesSnakImpl(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 endBoundaries = getTimeBoundariesFromQualifiers(context, claim, 'P582');
if (endBoundaries == nil) then
table.insert(results, claim.mainsnak);
end
end
end
end
if #results > 0 then
break ;
end
end
end
return results;
end
local function getParentsInBoundariesSnak(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 = getParentsInBoundariesSnakImpl(context, entity, boundaries, { 'P131' }) -- адміністрацыйная адзінка
if not results or #results == 0 then
results = getParentsInBoundariesSnakImpl(context, entity, boundaries, { 'P17' }) -- краіна
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
function p.getStatus(frame)
local args = frame.args;
local entity = mw.wikibase.getEntityObject();
if (not entity) then
return 'Населены пункт'
end
local filteredClaims = WDS.filter(entity.claims, 'P31[Q91733160]');
if (filteredClaims and #filteredClaims > 0) then
return 'Пасёлак гарадзкога тыпу'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q7930989,Q79323854,Q79324274,Q515]');
if (filteredClaims and #filteredClaims > 0) then
return 'Горад'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q65665664,Q2514025]');
if (filteredClaims and #filteredClaims > 0) then
return 'Пасёлак'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q65661087,Q5084,Q532,Q1989945]');
if (filteredClaims and #filteredClaims > 0) then
return 'Вёска'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q65660829,Q2023000]');
if (filteredClaims and #filteredClaims > 0) then
return 'Хутар'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q91733790]');
if (filteredClaims and #filteredClaims > 0) then
return 'Рабочы пасёлак'
else
filteredClaims = WDS.filter(entity.claims, 'P31[Q91733598]');
if (filteredClaims and #filteredClaims > 0) then
return 'Курортны пасёлак'
else
return 'Населены пункт'
end
end
end
end
end
end
end
end
function p.getRegion(frame)
local args = frame.args;
if not args.regionEntity then
error('адсутнічае regionEntity')
end
local statement = mw.wikibase.getEntityObject();
local context = {
entity = statement }
context.parseTimeBoundariesFromSnak = function(snak)
if (snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision) then
return parseTimeBoundaries(snak.datavalue.value.time, snak.datavalue.value.precision);
end
return nil;
end
local result = '';
local entity = statement;
if (not entity) then
return ''
else
local filteredClaims = WDS.filter(entity.claims, 'P31[' .. args.regionEntity .. ']');
if (not filteredClaims or #filteredClaims == 0) then
local parent = entity;
while (parent ~= nil) do
local newParentSnaks = getParentsInBoundariesSnak(context, parent, { nil, nil });
if (not newParentSnaks or #newParentSnaks == 0) then
parent = nil;
else
local parentSnak = newParentSnaks[1];
mw.log('snak found (' .. parentSnak.datavalue.value['numeric-id'] .. ')');
parent = mw.wikibase.getEntity('Q' .. parentSnak.datavalue.value['numeric-id']);
local regionSnaks = WDS.filter(parent.claims, 'P31[' .. args.regionEntity .. ']')
if (not regionSnaks or #regionSnaks == 0) then
mw.log('snak has not needed type. Continue search');
else
local label = mw.wikibase.label('Q' .. parentSnak.datavalue.value['numeric-id']);
mw.log(args.label);
if (mw.wikibase.sitelink('Q' .. parentSnak.datavalue.value['numeric-id'])) then
if args.phone == '1' then
result = string.sub(label, 0, -10);
else
if args.label == '1' then
result = label;
else
result = '[[' .. mw.wikibase.sitelink('Q' .. parentSnak.datavalue.value['numeric-id']) .. '|' .. label .. ']]';
end
end
else
local title = mw.title.new(label);
if args.label == '1' or (title and not title.exists) then
result = label;
else
result = '[[d:Q' .. parentSnak.datavalue.value['numeric-id'] .. '|' .. label .. ']]';
end
end
return result;
end
end
end
else
result = mw.wikibase.sitelink(mw.wikibase.getEntityIdForCurrentPage()) .. '|' .. mw.wikibase.label(mw.wikibase.getEntityIdForCurrentPage());
return result;
end
end
return result;
end
return p;