Модуль:Autosorting: различия между версиями

Новая страница: «require( 'strict' ) local p = {} local mwLang = mw.getContentLanguage() local getArgs = require( 'Module:Arguments' ).getArgs local config = mw.loadData( 'Module:Autosorting/config' ) local currentTitle = mw.title.getCurrentTitle() local function isEmpty( val ) return val == nil or val == '' end -- Получить название категории local function getCategoryName( str, name, ... ) if isEmpty( name ) then return error( 'Autosorting:...»
 
Нет описания правки
 
Строка 5: Строка 5:
local getArgs = require( 'Module:Arguments' ).getArgs
local getArgs = require( 'Module:Arguments' ).getArgs


local config = mw.loadData( 'Module:Autosorting/config' )
-- Безопасная загрузка конфига (чтобы не было ошибки, если файла конфига нет на сервере)
local hasConfig, config = pcall(mw.loadData, 'Module:Autosorting/config')
if not hasConfig then
    config = { limits = {} }
end


local currentTitle = mw.title.getCurrentTitle()
local currentTitle = mw.title.getCurrentTitle()
Строка 51: Строка 55:
end
end
return propertyLimits[ name ] or propertyLimits.default
return propertyLimits[ name ] or propertyLimits.default or -1
end
end


Строка 73: Строка 77:
end
end


-- Получить num (по умолчанию все) первых значений из свойства в Тептар
-- БЕЗОПАСНАЯ ФУНКЦИЯ-ЗАГЛУШКА
-- Так как базы Викиданных на локальном сервере нет, мы всегда возвращаем пустой массив.
-- Это заставит модуль использовать только локальные дефолтные параметры (например, default-type) без выдачи ошибок.
local function getWikidataProperty( frame, property, entityId, num )
local function getWikidataProperty( frame, property, entityId, num )
frame = frame or mw.getCurrentFrame()
return {}
if isEmpty( property ) then
return error( 'Autosorting: getWikidataProperty без property' )
end
property = string.upper( property )
if isEmpty( entityId ) then
entityId = mw.wikibase.getEntityIdForCurrentPage()
end
local result = {}
local success, statements = pcall( mw.wikibase.getBestStatements, entityId, property )
if success then
for i, propVal in ipairs( statements ) do
if not isEmpty( num ) and #result >= num then
break
end
local val = propVal[ 'mainsnak' ]
local hasValue = val[ 'snaktype' ] == 'value'
-- Media file values: P18 etc.
if hasValue and (val[ 'datatype' ] == 'commonsMedia' or val['datatype'] == 'string') then
local value = val[ 'datavalue' ][ 'value' ]
if not isEmpty( value ) then
table.insert( result, value )
end
end
-- Link values: P17 etc.
if hasValue and val[ 'datatype' ] == 'wikibase-item' then
local valId = val[ 'datavalue' ][ 'value' ][ 'id' ]
local success, label = pcall( mw.wikibase.getLabel, valId )
if success and not isEmpty( label ) then
table.insert( result, label )
end
end
end
end
return result
end
end


Строка 158: Строка 124:
end
end
-- Ограничение количества выводимых категорий
if validCatsCounter >= 3 then
if validCatsCounter >= 3 then
break
break
Строка 165: Строка 130:
end
end
-- Подходящей категории нет, либо в ВД нет рода занятий, но есть дефолтные значения,
-- тогда поставляем категорию на их основе при её наличии
local args = getArgs( frame )
local args = getArgs( frame )
local defaultOccupation = args[ 'default-occupation' ]
local defaultOccupation = args[ 'default-occupation' ]
Строка 178: Строка 141:
end
end
-- Есть род занятий (на ВД или через параметр), но подходящей категории нет,
-- тогда подставляем служебную категорию "не распределён" при её наличии
if result == '' and occupationExists then
if result == '' and occupationExists then
catName = getCategoryName( 'Тептар:%s (тип: человек; род занятий: не распределён)', name )
catName = getCategoryName( 'Тептар:%s (тип: человек; род занятий: не распределён)', name )
Строка 210: Строка 171:
for k, val in pairs( propValues ) do
for k, val in pairs( propValues ) do
catName = getCategoryName( 'Тептар:%s (тип: %s)', name, mwLang:lcfirst( val ) )
catName = getCategoryName( 'Тептар:%s (тип: %s)', name, mwLang:lcfirst( val ) )
-- TODO: переделать на получение Q-элементов, чтобы не зависеть от языка
if val == 'человек' or val == 'human' then
if val == 'человек' or val == 'human' then
local occupations = p._byOccupation( frame, name, entityId )
local occupations = p._byOccupation( frame, name, entityId )
Строка 218: Строка 178:
result = result .. occupations
result = result .. occupations
end
end
validCatsCounter = validCatsCounter + 1 -- "человек" считается всегда валидной
validCatsCounter = validCatsCounter + 1
else
else
if isValidCategory( name, catName, property ) then
if isValidCategory( name, catName, property ) then
Строка 230: Строка 190:
end
end
-- Ограничение количества выводимых категорий
if validCatsCounter >= 3 then
if validCatsCounter >= 3 then
break
break
Строка 236: Строка 195:
end
end
-- Если ничего не нашлось, попытка добавить категорию на основе переданных дефолтных значений
if result == '' and not isEmpty( defaultType ) then
if result == '' and not isEmpty( defaultType ) then
if defaultType == 'человек' and not isEmpty( defaultOccupation ) then -- человек, есть занятие
if defaultType == 'человек' and not isEmpty( defaultOccupation ) then
catName = getCategoryName( 'Тептар:%s (тип: человек; род занятий: %s)', name, defaultOccupation )
catName = getCategoryName( 'Тептар:%s (тип: человек; род занятий: %s)', name, defaultOccupation )
if isValidCategory( name, catName, property ) then
if isValidCategory( name, catName, property ) then
result = result .. getCategory( catName, key )
result = result .. getCategory( catName, key )
else
else
-- человек, есть занятие, но категория для занятия не прошла проверки
result = result .. getCategory( 'Тептар:%s (тип: человек)', key, name )
result = result .. getCategory( 'Тептар:%s (тип: человек)', key, name )
end
end
elseif defaultType == 'человек' then
elseif defaultType == 'человек' then
-- человек, нет занятия
result = result .. getCategory( 'Тептар:%s (тип: человек)', key, name )
result = result .. getCategory( 'Тептар:%s (тип: человек)', key, name )
else
else
-- нечеловек
catName = getCategoryName( 'Тептар:%s (тип: %s)', name, defaultType )
catName = getCategoryName( 'Тептар:%s (тип: %s)', name, defaultType )
if isValidCategory( name, catName, property ) then
if isValidCategory( name, catName, property ) then
Строка 258: Строка 213:
end
end
-- Добавить стандартную категорию только при отсутствии иных
local defaultCatName = getCategoryName( 'Тептар:%s (не распределённые по типам)', name )
local defaultCatName = getCategoryName( 'Тептар:%s (не распределённые по типам)', name )
if result == '' and not isEmpty( defaultCatKey ) then
if result == '' and not isEmpty( defaultCatKey ) then
Строка 360: Строка 314:
frame = frame or mw.getCurrentFrame()
frame = frame or mw.getCurrentFrame()
-- Возможный сброс значения с Тептар
if file ~= nil and mw.text.trim( file ) == '-' then
if file ~= nil and mw.text.trim( file ) == '-' then
file = nil
file = nil
end
end
-- Вывести категории при заполненном несуществующем файле (= файле с Тептар-склада)
if not isEmpty( file ) then
if not isEmpty( file ) then
local success, title = pcall( mw.title.new, 'File:' .. file )
local success, title = pcall( mw.title.new, 'File:' .. file )
-- Игнорировать при заполненном локальном файле
if success and not isEmpty( title ) and title.exists then
if success and not isEmpty( title ) and title.exists then
return nil
return nil
end
end
local catName = 'Тептар:Статьи с изображениями: заполнить свойство %s в Тептар'
local catName = 'Тептар:Статьи с изображениями: добавить локально'
local result = ''
local result = ''
local p18, p18Category = getFileCategory( frame, catName, 'p18', entityId )
local p18, p18Category = getFileCategory( frame, catName, 'p18', entityId )
Строка 388: Строка 339:
end
end
-- Игнорировать при наличии изображений в указанных свойствах
for _, val in pairs( localFileProps ) do
for _, val in pairs( localFileProps ) do
local propValue = getWikidataProperty( frame, val, entityId, 3 )
local propValue = getWikidataProperty( frame, val, entityId, 3 )
Строка 396: Строка 346:
end
end
-- Вывести категории при отсутствии игнорируемых свойств
local catName = 'Тептар:Статьи без изображений'
local catName = 'Тептар:Статьи без изображений (указано в Тептар: %s)'
local result = p._byCountry( frame, 'статьи без изображений', entityId )
local result = p._byCountry( frame, 'статьи без изображений', entityId )
Строка 429: Строка 378:
end
end
-- Игнорирование по умолчанию статей с указанным p18
local uses = args[ 'uses' ]
local uses = args[ 'uses' ]
if isEmpty( uses ) then
if isEmpty( uses ) then