Module:Person categorizer

From Soyjak Wiki, the free ensoyclopedia
Jump to navigationJump to search



local p = {}
local core = require('Module:Infobox categorizer')
local yesno = require('Module:Yesno')
local config = mw.loadData('Module:Person categorizer/config')
local countryData = mw.loadData('Module:Infobox categorizer/countries')
local stateData = mw.loadData('Module:Infobox categorizer/states')

local where = 'Module:Person categorizer/config'
local dims = core.need(config, 'dimensions', where)
local maintenance = core.need(config, 'maintenance', where)
local invalidOverrideCat = core.need(maintenance, 'invalidOverride', where .. '.maintenance')
local usingOverrideCat = core.need(maintenance, 'usingOverride', where .. '.maintenance')
local misuseCfg = core.need(config, 'namefagMisuse', where)
local misuseNamespace = core.need(misuseCfg, 'namespace', where .. '.namefagMisuse')

local D = {}
for _, key in ipairs({
	'wikiAccount',
	'booruAccount',
	'nationality',
	'state', -- USA
	'birth',
	'death',
	'jakked',
	'gender',
}) do
	D[key] = core.need(dims, key, where .. '.dimensions')
end

local countries = core.compileAliasSet({ countryData })
local states = core.compileAliasSet({ stateData })
local genders = core.compileAliasSet({ core.need(config, 'genders', where) })

local countryCode = {}
local countryName = {}

for _, entry in ipairs(countryData) do
	countryCode[string.upper(entry.category)] = entry.category
	countryName[entry.category] = entry.name or entry.category

	for _, code in ipairs(entry.codes or {}) do
		countryCode[string.upper(code)] = entry.category
	end
end

local function countryCanon(value)
	local code = string.upper(core.trim(value))
	if code == '' then return nil end
	local prefix = string.match(code, '^(%w+)%-')
	return countryCode[code] or (prefix and countryCode[prefix]) or nil
end

local stateName = {}

for _, entry in ipairs(stateData) do
	stateName[string.upper(entry.category)] = entry.name or entry.category
end

local function stateCanon(value)
	local code = string.upper(core.trim(value))
	if stateName[code] then return code end
	return nil
end

local function aliasOverride(compiled)
	return function(value)
		return core.parseAliasSetOverride(value, compiled)
	end
end

local function maint(dim, key)
	return dim and dim.maintenance and dim.maintenance[key]
end

local function bail()
	local title = mw.title.getCurrentTitle()
	if title.namespace == 0 and title.isSubpage then return true end
	return mw.ustring.find(mw.ustring.lower(title.text), '^lists? of ') ~= nil
end

function p._state(args)
	local codes = core.readDataAttr(args.nationality, 'nationality')
	local nationality = core.resolve {
		candidates = #codes > 0 and codes or core.matchAliasSets(args.nationality, countries),
		override = args.category_nationality,
		parse = aliasOverride(countries),
		canon = countryCanon,
	}
	local state = core.resolve {
		candidates = codes,
		override = args.category_state,
		parse = aliasOverride(states),
		canon = stateCanon,
	}
	local birth = core.resolve {
		candidates = core.findYears(args.birth_date),
		override = args.category_birth,
		parse = core.parseYearOverride,
		max = 1,
	}
	local death = core.resolve {
		candidates = core.findYears(args.death_date),
		override = args.category_death,
		parse = core.parseYearOverride,
		max = 1,
	}
	local gender = core.resolve {
		candidates = core.matchAliasSets(args.gender, genders),
		override = args.category_gender,
		parse = aliasOverride(genders),
	}

	return {
		wikiAccount = core.trim(args.wiki_account) ~= '',
		booruAccount = core.trim(args.booru_account) ~= '',
		jakked = yesno(core.trim(mw.text.split(core.clean(args['IAS?']), ',', true)[1])),
		nationality = nationality,
		state = state,
		birth = birth,
		death = death,
		gender = gender,
	}
end

function p._categories(args)
	local out = core.newList()
	if bail() then return out end -- bail out on mainspace subpages and list of (doxes) pages to avoid catspam
	if mw.title.getCurrentTitle().namespace == misuseNamespace then
		mw.addWarning(misuseCfg.warning)
		out:add(misuseCfg.maintenance)
	end
	local state = p._state(args)

	local function has(field)
		return core.trim(args[field]) ~= ''
	end

	local function emit(dim, dimState, names)
		if not dim then return end
		for _, value in ipairs(dimState.values) do
			out:add(core.fill(dim.name, names and names[value] or value))
		end
	end

	-- if state.wikiAccount then out:add(D.wikiAccount.name) end
	-- if state.booruAccount then out:add(D.booruAccount.name) end

	emit(D.nationality, state.nationality, countryName)
	if state.nationality.source == 'detected' and has('nationality') and state.nationality.undetected then
		out:add(maint(D.nationality, 'unrecognized'))
	end

	emit(D.state, state.state, stateName)

	emit(D.birth, state.birth)
	if state.birth.overflow then out:add(maint(D.birth, 'overflow')) end
	if state.birth.source == 'detected' and has('birth_date') and state.birth.undetected then
		out:add(maint(D.birth, 'unrecognized'))
	end

	emit(D.death, state.death)
	if state.death.overflow then out:add(maint(D.death, 'overflow')) end
	if state.death.source == 'detected' and has('death_date') and state.death.undetected then
		out:add(maint(D.death, 'unrecognized')) -- this might be too trigger happy
	end

	if state.jakked == true then out:add(D.jakked.name) end
	if has('IAS?') and state.jakked == nil then out:add(maint(D.jakked, 'unrecognized')) end

	emit(D.gender, state.gender)

	if core.anyCustomized(state.nationality, state.state, state.birth, state.death, state.gender) then
		out:add(usingOverrideCat)
	end
	if core.anyInvalid(state.nationality, state.state, state.birth, state.death, state.gender) then
		out:add(invalidOverrideCat)
	end
	return out
end

p.main = core.makeMain(p._categories, config.namespaces)

return p