Module:Sandbox/Premeditated

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search
local p = {}

local tettstedModule = require('Module:Sandbox/Premeditated/tettsteder')

-- Format date like "2023-01-01" → "1. januar 2023"
local function formatDate(date)
	if not date or #date < 10 then return "" end
	local year, month, day = date:match("(%d+)%-(%d+)%-(%d+)")
	local months = {
		"januar", "februar", "mars", "april", "mai", "juni",
		"juli", "august", "september", "oktober", "november", "desember"
	}
	return tonumber(day) .. ". " .. months[tonumber(month)] .. " " .. year
end

local function getRef(frame, claim)
	if not claim.references or #claim.references == 0 then
		return ''
	end

	local ref = claim.references[1]  -- just use the first reference

	local url = ''
	local title = ''
	local date = ''

	-- Extract URL (P854), title (P1476), and publication date (P577)
	for _, snak in pairs(ref.snaks or {}) do
		if snak[1] then
			if snak[1].property == "P854" then
				url = snak[1].datavalue.value
			elseif snak[1].property == "P1476" then
				title = snak[1].datavalue.value.text
			elseif snak[1].property == "P577" then
				local raw = snak[1].datavalue.value.time
				date = raw:match("(%d+%-%d+%-%d+)")
				if date then
					local y, m, d = date:match("(%d+)%-(%d+)%-(%d+)")
					local months = {
						"januar", "februar", "mars", "april", "mai", "juni",
						"juli", "august", "september", "oktober", "november", "desember"
					}
					date = tonumber(d) .. ". " .. months[tonumber(m)] .. " " .. y
				end
			end
		end
	end

	if url == '' then return '' end

	-- Build the reference tag using #tag parser function
	return frame:callParserFunction{
		name = '#tag:ref',
		args = {
			'{{kilde www |url=' .. url .. '|tittel=' .. title ..
			'|nettside=[[Statistisk sentralbyrå]] |dato=' .. date ..
			'|språk=norsk bokmål}}',
			name = 'SSB-befolkning'
		}
	}
end

-- Resolve SSB ID or label to QID
local function resolveQid(key)
	if tettstedModule.tettsted[key] then
		return tettstedModule.tettsted[key]
	end
	
	if tettstedModule.kommune[key] then
		return tettstedModule.kommune[key]
	end

	local searchId = mw.wikibase.getEntityIdForTitle(key)
	if searchId then
		return searchId
	end

	return nil
end

-- Return preferred or latest population claim
local function getBestPopulationClaim(claims)
	if not claims then return nil end

	for _, claim in ipairs(claims) do
		if claim.rank == "preferred" then
			return claim
		end
	end

	local latestClaim = nil
	local latestDate = "0000-00-00"
	for _, claim in ipairs(claims) do
		if claim.qualifiers and claim.qualifiers.P585 then
			local time = claim.qualifiers.P585[1].datavalue.value.time
			local cleanDate = time:match("(%d+%-%d+%-%d+)")
			if cleanDate and cleanDate > latestDate then
				latestDate = cleanDate
				latestClaim = claim
			end
		end
	end

	return latestClaim
end

function p.befolkning(frame)
	local args = frame.args
	local rawKey = args[1]
	local key = rawKey and rawKey:match("(%d%d%d%d)$") or rawKey
	if not key or key == "" then return "[[Kategori:Utgått eller ugyldig tettstedsnummer]]" end

	-- Detect modes like "år", "d", "ref"
	local mode = { d = false, ["år"] = false, ref = false, N = false }

	for k, v in pairs(args) do
		if tonumber(k) and tonumber(k) >= 2 then
			if v == "d" then mode.d = true
			elseif v == "N" then mode.N = true
			elseif v == "år" then mode["år"] = true
			elseif v == "ref" then mode.ref = true
			end
		end
	end

	local qid = resolveQid(key)
	if not qid then
		return "[[Kategori:Utgått eller ugyldig tettstedsnummer]]" .. frame:expandTemplate{ title = 'Template:Error', args = { '<small>Feil tettstedskode/navn</small>', tag='span' } }
	end

	local entity = mw.wikibase.getEntity(qid)
	if not entity or not entity.claims or not entity.claims.P1082 then
		return "[[Kategori:Utgått eller ugyldig tettstedsnummer]]" .. frame:expandTemplate{ title = 'Template:Error', args = { '<small>Ingen befolkningsdata</small>', tag='span' } }
	end

	local claim = getBestPopulationClaim(entity.claims.P1082)
	if not claim then
		return "[[Kategori:Utgått eller ugyldig tettstedsnummer]]" .. frame:expandTemplate{ title = 'Template:Error', args = { '<small>Ingen gyldig befolkningsoppføring</small>', tag='span' } }
	end

	local pop = claim.mainsnak.datavalue.value.amount or claim.mainsnak.datavalue.value
	pop = tonumber(pop)
	local popFormatted = mw.language.getContentLanguage():formatNum(pop)

	local rawDate = ""
	if claim.qualifiers and claim.qualifiers.P585 then
		rawDate = claim.qualifiers.P585[1].datavalue.value.time:match("(%d+%-%d+%-%d+)")
	end
	local year = rawDate:sub(1, 4)
	local formattedDate = formatDate(rawDate)

	local ref = mode.ref and getRef(frame, claim) or ''
	
	if mode["år"] then
		return year .. (mode.ref and ref or "")
	elseif mode.d then
		return formattedDate .. (mode.ref and ref or "")
	elseif mode.ref then
		return popFormatted .. ref
	elseif mode.N then
		return 5594340 -- https://www.ssb.no/statbank/table/06913
	else
		return popFormatted
	end
end

return p