Модуль:Autosorting

Материал из Тептар — свободной энциклопедии
Перейти к навигации Перейти к поиску

Новый вариант реализации Шаблон:Сортировка: по типам и Шаблон:Сортировка: по странам, сохраняющая почти всю логику работы, но расширяющая количество утверждений с Тептар-данных до бесконечности и более понятно написанная. Подмодуль конфигурации: Модуль:Autosorting/config. Незаконченные тесты: Шаблон:Сортировка: по типам/тесты и Шаблон:Сортировка: по странам/тесты.


local p = {} -- p stands for package
local config = require('Модуль:Autosorting/config')

function getWikidataProperty(frame, property)
	local value = frame:expandTemplate{
		title = 'wikidata',
		args = {
			property,
			from = frame:getParent().args['from'] or '', -- TODO: remove?
			plain = '1'
		}
	}
	if value == '' then
		return {}
	else
		return mw.text.split(value, ', ')
	end
end

function getLimit(criterion, property)
	local propertyLimits = config.limits[property]
	return propertyLimits[criterion] or propertyLimits.default
end

function getNextLevelLimit(criterion, property)
	local propertyNextLevelLimits = config.nextLevelLimits[property]
	return propertyNextLevelLimits[criterion] or propertyNextLevelLimits.default
end

function upperFirst(str)
	return mw.ustring.gsub(str, '^.', mw.ustring.upper)
end

function lowerFirst(str)
	return mw.ustring.gsub(str, '^.', mw.ustring.lower)
end

function p.sortByType(frame)
	local criterion = upperFirst(frame.args[1])
	local typeLimit = getLimit(criterion, 'P31')
	local occupationLimit = getLimit(criterion, 'P106')
	
	local categories = {}
	local types = getWikidataProperty(frame, 'P31')
	if #types > 0 then
		for _, type in pairs(types) do
			if type == 'человек' then
				local occupations = getWikidataProperty(frame, 'P106')
				if #occupations > 0 then
					for _, occupation in pairs(occupations) do
						local normalCategory = 'Тептар:' .. criterion .. ' (тип: человек; род занятий: ' .. lowerFirst(occupation) .. ')' -- TODO: get rid of lower
						local belowLimitCategory = 'Тептар:' .. criterion .. ' (тип: человек)'
						if mw.title.new('Категория:' .. normalCategory).exists or mw.site.stats.pagesInCategory(normalCategory) > typeLimit then
							table.insert(categories, normalCategory)
						else
							table.insert(categories, belowLimitCategory)
						end
					end
				else
					local typeIsHumanCategory = 'Тептар:' .. criterion .. ' (тип: человек)'
					table.insert(categories, typeIsHumanCategory)
				end
			else
				local normalCategory = 'Тептар:' .. criterion .. ' (тип: ' .. lowerFirst(type) .. ')' -- TODO: get rid of lower
				local pageName = mw.title.getCurrentTitle().text
				local belowLimitCategory = 'Тептар:' .. criterion .. ' (не распределённые по типам)|' .. type .. pageName
				if mw.title.new('Категория:' .. normalCategory).exists or mw.site.stats.pagesInCategory(normalCategory) > occupationLimit then
					table.insert(categories, normalCategory)
				else
					table.insert(categories, belowLimitCategory)
				end
			end
		end
	else
		local noTypeCategory = 'Тептар:' .. criterion .. ' (тип: не указан)' -- TODO: without :
		table.insert(categories, noTypeCategory)
	end
	
	local res = ''
	for _, category in pairs(categories) do
		res = res .. '<<Категория:' .. category .. '>>' -- TODO: < to [
	end
	return res
end

function p.sortByCountry(frame)
	local criterion = upperFirst(frame.args[1])
	local countryNextLevelLimit = getNextLevelLimit(criterion, 'P17')
	local regionLimit = getLimit(criterion, 'P131')
	
	-- TODO: remove
	if frame:getParent().args.nulllimits and frame:getParent().args.nulllimits ~= '' then
		countryNextLevelLimit = -1
		regionLimit = -1
	end
	
	local categorizeByRegion = false
	local categories = {}
	local countries = getWikidataProperty(frame, 'P17')
	if #countries > 0 then
		for _, country in pairs(countries) do
			local countryCategory = 'Тептар:' .. criterion .. ' (страна: ' .. upperFirst(country) .. ')' -- TODO: get rid of upper
			table.insert(categories, countryCategory)
			if mw.site.stats.pagesInCategory(countryCategory) > countryNextLevelLimit then
				categorizeByRegion = true
			end
		end
	else
		-- TODO: add some category?
	end
	
	if categorizeByRegion then -- TODO: only for necessary countries?
		local regions = getWikidataProperty(frame, 'P131')
		if #regions > 0 then
			for _, region in pairs(regions) do
				local regionCategory = 'Тептар:' .. criterion .. ' (АТЕ: ' .. upperFirst(region) .. ')' -- TODO: get rid of upper
				if mw.site.stats.pagesInCategory(regionCategory) > regionLimit then
					table.insert(categories, regionCategory)
				else
					-- TODO: add some category?
				end
			end
		else
			-- TODO: add some category?
		end
	end
	
	local res = ''
	for _, category in pairs(categories) do
		res = res .. '<<Категория:' .. category .. '>>' -- TODO: < to [
	end
	return res
end

return p