Modul:CountryData

Aus Wikivoyage
Zur Navigation springen Zur Suche springen
Template-info.png Dokumentation für das Modul CountryData[Ansicht] [Bearbeiten] [Versionsgeschichte] [Aktualisieren]

Verwendungszweck

Das Modul stellt Funktion zur Bestimmung länderspezifischer Daten wie Wikidata-Qualifikator, ISO-3166-Code, Amtssprache, Landes-Telefonvorwahl und (zukünftig) die Landeswährung zur Verfügung.

Die Werte werden teilweise aus der Tabelle Modul:CountryData/Geography bezogen, um teure Wikidata-Abfragen zu vermeiden.

Versionsbezeichnung auf WikiData: 2020-10-23 Ok!

Funktionen

Für den Einsatz in den Modulen vCard / Marker

function cm.getCountryData( vcEntity )

Parameter: vcEntity: Wikidata-Entity oder nil.

Liefert die landesspezifischen Daten in einer Tabelle zurück.

country = {
	id = '',       -- Wikidata qualifier Q#######, string
	iso_3166 = '', -- ISO 3166-1 code, string, uppercase
	cc = '',       -- country calling code, string starting with +
	lang = '',     -- official language code ISO 639-1, string, lowercase
	currency = ''  -- currency code ISO 4217, string, uppercase
}
function cm.getCountryFromPhones( tab )

Bestimmung der landesspezifischen Daten anhand der Vorwahlnummern aus der Telefonnummerntabelle tab.

function cm.getAdm1st( countryId )

Liefert den ISO-Code 3166-2 für die Verwaltungseinheit erster Ordnung zurück. Übergeben wird die Wikidata-Id für das zugehörige Land, um sicherzustellen, dass die rechenzeitintensive Bestimmung des ISO-Codes nur bei bekanntem Land erfolgt.

function cm.getCategories( formatStr )

Liefert eine Zeichenkette mit den Kategorie-Links aller verwendeten Wikidata-Eigenschaften zurück.

Für den Einsatz im Modul LinkPhone

function cm.getCountryCode()

Liefert die Landes-Telefonvorwahl als Zeichenkette zurück.

Benötigte weitere Module

Dieses Modul benötigt folgende weitere Module: CountryData/Currencies • CountryData/Geography • Languages • Wikidata utilities

Verwendung in anderen Modulen

Dieses Modul ist notwendig für die Ausführung folgender Module. Bei Anpassungen sollte die Funktionstüchtigkeit der folgenden Module geprüft werden. Benutze dazu auch diese Tracking-Kategorie um Fehler zu finden, die sich dann auf Artikel auswirken:

Hinweise
-- documentation
local CountryData = {
	suite  = 'CountryData',
	serial = '2020-10-23',
	item   = 65431301
}

-- CountryData module

require( 'Module:No globals' )
local cg = require( 'Module:CountryData/Geography' )
local cu = mw.loadData( 'Module:CountryData/Currencies' ) -- additional currency symbols
local fw = require( 'Module:Wikidata utilities' )
local lg = require( 'Module:Languages' )

local cm = {}

local function checkTable( id )
	if id == nil or id == '' then
		return nil
	end

	local t = cg.adminEntities[ id ]
	if t then
		return t
	end
	t = cg.countries[ id ]
	return t -- nil or table
end

local function checkTableFromEntity( anEntity )
	local id = nil
	local i, t, w
	if anEntity then
		-- located in the administrative territorial entity
		w = fw.getBestStatements( anEntity, 'P131' )
		if #w > 0 then
			for i = 1, #w, 1 do
				if w[ i ].mainsnak.snaktype == 'value' then
					id = w[ i ].mainsnak.datavalue.value.id
					t = checkTable( id )
					if t then
						return id, t
					end
				end
			end
		end	

		-- country
		w = fw.getValues( anEntity, 'P17', nil )
		if #w > 0 then
			for i = 1, #w, 1 do
				id = w[ i ].id
				t = checkTable( id )
				if t then
					return id, t
				end
			end
		end
	end
	-- id is nil or country id
	return id, nil
end

function cm.getDataFromTables( vcEntity )

	-- article lemma
	local lemma = mw.title.getCurrentTitle().text
	local t = cg.articles[ lemma ]
	if t then
		return cg.countries[ t ]
	end

	-- article id
	local articleId = mw.wikibase.getEntityIdForCurrentPage()
	if not articleId and not vcEntity then
		return nil
	end

	local arId = nil
	if articleId then
		-- article in tables
		t = checkTable( articleId )
		if t then
			return t
		end

		-- country or admin entity in table
		arId, t = checkTableFromEntity( articleId )
		if t then
			return t
		end
	end

	-- vCard entity
	local vcId = nil
	if vcEntity then
		vcId, t = checkTableFromEntity( vcEntity )
		if t then
			return t
		end
	end

	-- not found in tables, get it now all from Wikidata
	return vcId or arId
end

-- getting data for vCard

local function _getCountryData( vcEntity )
	local t = cm.getDataFromTables( vcEntity )
	if type( t ) == 'table' then
		return t
	end

	local country = {
		id = '',
		cont = '',
		iso_3166 = '',
		cc = '',
		lang = '',
		currency = '',
		country = '',
		show = ''
	}
	local ns = mw.title.getCurrentTitle().namespace
	local defaultCountry = nil
	if ns ~= 0 then
		defaultCountry = cg.articles[ '_default' ]
		if defaultCountry then 
			defaultCountry = cg.countries[ defaultCountry ]
		end
	end

	if t == nil or t == '' then
		return defaultCountry or country
	end

	-- getting data from country entity
	country.id = t
	local coEntity = mw.wikibase.getEntity( country.id )
	if coEntity then
		country.fromWD = true
		country.iso_3166 = fw.getValue( coEntity, 'P297' )
		country.iso_3166 = country.iso_3166:upper()
		country.cont = fw.getId( coEntity, 'P30' )
		country.cont = cg.continents[ country.cont ] or ''
		country.cc = fw.getValue( coEntity, 'P474' ) -- country calling code
		t = fw.getId( coEntity, 'P37' ) -- official language id
		if t ~= '' then
			country.lang = fw.getValue( t, 'P218' ) -- ISO 639-1
			country.lang = country.lang:lower()
		end
		t = fw.getId( coEntity, 'P38' ) -- currency id
		if t ~= '' then
			country.currency = fw.getValue( t, 'P498' ) -- ISO 4217
			country.currency = country.currency:upper()
		end
		-- maybe in future also time zone (P421) and daylight saving time
	else
		country = defaultCountry or country
	end

	return country
end

-- getting county data from country calling code

function cm.getCountryFromPhones( tab )
	local country = {
		id = '',
		cont = '',
		iso_3166 = '',
		cc = '',
		lang = '',
		currency = '',
		country = '',
		show = ''
	}

	-- prepare phone numbers
	for i = #tab, 1, -1 do
		tab[ i ] = tab[ i ]:gsub( '^00', '+' )
			:gsub( '^%+%+', '+' )
			:gsub( '[^%+0-9A-Z]', '' )
		if not tab[ i ]:match( '^%+%d%d%d%d' ) then
			table.remove( tab, i )
		end
	end
	if #tab == 0 then
		return country
	end

	-- make county codes table
	local ccodes = {}
	for key, country in pairs( cg.countries ) do
		if country.cc ~= '' then
			ccodes[ country.cc:gsub( '-', '' ) ] = key
		end
	end
	for key, country in pairs( cg.adminEntities ) do
		if country.cc ~= '' then
			ccodes[ country.cc:gsub( '-', '' ) ] = key
		end
	end

	-- look for country code in phone numbers
	local q
	for i, phone in ipairs( tab ) do
		phone = phone:sub( 1, 5 )
		repeat
			q = ccodes[ phone ]
			phone = phone:sub( 1, -2 )
		until phone == '' or q
		if q then
			break
		end
	end
	if q then
		country = cg.countries[ q ] or cg.adminEntities[ q ]
	end
	
	return country
end

function cm.getCountryData( entity, phones )
	local country = _getCountryData( entity )
	if country.id == '' and phones and #phones > 0 then
		country = cm.getCountryFromPhones( phones )
	end

	country.addCurrency = country.currency
	if country.currency ~= '' then
		local c = cu[ country.currency ]
		if c and c ~= '' then
			country.addCurrency = country.addCurrency .. ', ' .. c
		end
	end
	if country.lang ~= '' then
		country.langName = lg.getProperty( country.lang, 'n' )
		country.isRTL = lg.isR2L( country.lang )
		country.unknownLanguage = country.langName == ''
	else
		country.unknownLanguage = true
	end

	return country
end

-- getting first-order administrative-territorial entity code
function cm.getAdm1st( countryId )
	local entityId = mw.wikibase.getEntityIdForCurrentPage()
	if not entityId or not countryId or countryId == '' then
		return nil
	end
	local i = 0
	local iso3166_2 = ''
	while entityId ~= '' and not cg.adminEntities[ entityId ]
		and not cg.countries[ entityId ] and i < 5 do
		-- getting ISO 3166-2 code
		iso3166_2 = fw.getValue( entityId, 'P300' )
		if iso3166_2 ~= '' then
			return iso3166_2
		end
		-- getting next administrative territorial entity
		entityId = fw.getId( entityId, 'P131' )
		i = i + 1
	end
end

function cm.getCategories( formatStr )
	return fw.getCategories( formatStr )
end

-- getting data for LinkPhone

function cm.getCountryCode()
	local t = cm.getDataFromTables( nil )
	if type( t ) == 'table' then
		return t.cc, t.phoneDigits or 2
	end
	if t == nil or t == '' then
		return '', 2
	end
	-- t is country id
	return fw.getValue( t, 'P474' ), 2
end

-- module administration
function cm.getModuleInterface()
	return CountryData
end

function cm.failsafe( version )
	return fw._failsafe( version, CountryData ) or ''
end

return cm