Modul:LocationAndCountry

De la Wikipedia, enciclopedia liberă
Jump to navigation Jump to search

Implementează formatul {{Loc, Țară}}, dar poate fi apelat prin intermediul funcției displayFromParams și din alte module pentru a afișa țara atașată de un loc la un anumit moment de timp.


-- will display a wikidata property representing a location, followed by a comma and the name of the country, both with wikilinks
-- the first argument specifies the parameter to be displayed
-- the second argument specifies the entity ID
-- the third argument specifies a timestamp showing the moment in time for which the country is to be identified
-- the fourth argument specifies the maximum number of values to be processed (default 1)
-- the fifth argument specifies the separator to use when displaying multiple values
local getArgs = require('Modul:Arguments').getArgs
local wikidata = require('Modul:Wikidata')
local StringUtils = require('Modul:StringUtils')
local GregorianDate = require('Modul:GregorianDate')
local DateUtils = require('Modul:DateUtils')
local TableTools = require('Modul:TableTools')

local appendToString = StringUtils._appendToString
local emptyToNil = StringUtils._emptyToNil

local p = {}

local function extractGregorianDateFromSnak(snak, hms)
	local afterDate = wikidata.extractDateFromClaim(snak)
	local afterDateGregorian = GregorianDate.convertToGregorianIfInInterval(afterDate)
	afterDateGregorian.hour = hms[1]
	afterDateGregorian.min = hms[2]
	afterDateGregorian.sec = hms[3]
	after = tonumber(mw.language.getContentLanguage():formatDate('U', os.date('%d %B %Y %H:%M:%S', os.time(afterDateGregorian)), nil))
	return after
end

local function getShortOrOfficialNameRetrieverClosure(ts)
	return function(object)
		if not object then return nil end -- just to be safe: this callback should only be called with existing objects
		local correspondingShortNameClaim = wikidata.findClaimForTimestamp(object.id, 'P1813', ts)
		if correspondingShortNameClaim then return correspondingShortNameClaim.mainsnak.datavalue.value.text end
		local correspondingOfficialNameClaim = wikidata.findClaimForTimestamp(object.id, 'P1448', ts)
		if ts and correspondingOfficialNameClaim then return correspondingOfficialNameClaim.mainsnak.datavalue.value.text end
	end
end

local function getOfficialNameRetrieverClosure(ts)
	return function(object)
		if not object then return nil end -- just to be safe: this callback should only be called with existing objects
		local correspondingOfficialNameClaim = wikidata.findClaimForTimestamp(object.id, 'P1448', ts)
		if ts and correspondingOfficialNameClaim then return correspondingOfficialNameClaim.mainsnak.datavalue.value.text end
	end
end

local function getShortNameRetrieverClosure(ts)
	return function(object)
		if not object then return nil end -- just to be safe: this callback should only be called with existing objects
		local correspondingShortNameClaim = wikidata.findClaimForTimestamp(object.id, 'P1813', ts)
		if correspondingShortNameClaim then return correspondingShortNameClaim.mainsnak.datavalue.value.text end
	end
end

p.displayFromParams = function(param, entity, timestamp, maxvalues, separator)
	if param == nil then return '' end
	local claims = nil
	local workingEntityId = nil
	if type(entity) == 'table' then
		workingEntityId = entity.id
		claims = entity:getBestStatements(param)
	else
		workingEntityId = entity
		if not workingEntityId then workingEntityId = mw.wikibase.getEntityIdForCurrentPage() end
		if type(entity) == 'number' then workingEntityId = 'Q' .. tostring(entity) end
		if workingEntityId == nil then return '' end
		claims = mw.wikibase.getBestStatements(workingEntityId, param)
	end
	
	local ts = nil
	if timestamp then
		if type(timestamp) == 'string' and mw.ustring.gmatch(timestamp, 'P%d+') then
			local wdDates = wikidata.findDateValues(timestamp, workingEntityId)
			if wdDates and 0 < #wdDates then
				local wdDateIdx = 1
				while wdDateIdx <= #wdDates and (wdDates[wdDateIdx].claim.type ~= 'statement' or wdDates[wdDateIdx].claim.mainsnak.snaktype ~= 'value') do
					wdDateIdx = wdDateIdx + 1
				end
				if wdDateIdx <= #wdDates and (wdDates[wdDateIdx].claim.type == 'statement' and wdDates[wdDateIdx].claim.mainsnak.snaktype == 'value') then
					wdDates[wdDateIdx] = GregorianDate.convertToGregorianIfInInterval(wdDates[wdDateIdx])
					ts = wdDates[wdDateIdx]
				end
			end
		end
		if ts == nil and type(timestamp) == 'string' then
			ts = DateUtils.parseYear(timestamp)
		elseif ts == nil and type(timestamp) == 'table' and timestamp.year then
			ts = timestamp
		end
	end

	
	local valueList = {}
	local valueCount = 0
	if claims and 0 < #claims then
		for claimIdx, actualClaim in pairs(claims) do
			valueCount = valueCount + 1
			local locationEntitiesIds = {}
			local locationNames = {} 
			if actualClaim.mainsnak and actualClaim.mainsnak.snaktype == 'value' and actualClaim.mainsnak.datavalue.type == 'wikibase-entityid' then
				local locationEntityId =actualClaim.mainsnak.datavalue.value.id
				table.insert(locationEntitiesIds, locationEntityId)
					locationNames[locationEntityId] = wikidata.findLinkToItemWithCallback(locationEntityId, false, getOfficialNameRetrieverClosure(ts))
				
				--attempt to also load administrative unit, but only if present as a qualifier
				local unitQualifier = actualClaim.qualifiers and actualClaim.qualifiers['P131'] and actualClaim.qualifiers['P131'][1]
				if unitQualifier and unitQualifier.snaktype == 'value' then
					table.insert(locationEntitiesIds, unitQualifier.datavalue.value.id)
					locationNames[unitQualifier.datavalue.value.id] = wikidata.findLinkToItemWithCallback(unitQualifier.datavalue.value.id, false, getShortOrOfficialNameRetrieverClosure(ts))
				end
				
				-- attempt to identify country in the qualifier first, but if it's not, go to the entity
				local countryQualifier = actualClaim.qualifiers and actualClaim.qualifiers['P17'] and actualClaim.qualifiers['P17'][1]
				local countryId = nil

				if countryQualifier and countryQualifier.snaktype == 'value' then
					table.insert(locationEntitiesIds, countryQualifier.datavalue.value.id)
					locationNames[countryQualifier.datavalue.value.id] = wikidata.findLinkToItemWithCallback(countryQualifier.datavalue.value.id, false, getShortOrOfficialNameRetrieverClosure(ts))
				else
					local countryClaim = nil
					countryClaim = wikidata.findClaimForTimestamp(locationEntityId, 'P17', ts)
					if countryClaim and countryClaim.mainsnak and countryClaim.mainsnak.snaktype == 'value' then
						countryId = countryClaim.mainsnak.datavalue.value.id
						table.insert(locationEntitiesIds, countryId)
					elseif not countryClaim then
						countryId = wikidata.loadOneValueInChain({locationEntityId, 'P17', 'raw'})
						if countryId and mw.ustring.len(countryId) > 0 then
							table.insert(locationEntitiesIds, countryId)
						end
					end
				end
				locationEntitiesIds = TableTools.removeDuplicates(locationEntitiesIds)
				local locationNamesList = {}
				for _,eachLocationId in ipairs(locationEntitiesIds) do
					if not locationNames[eachLocationId] then
						locationNames[eachLocationId] = wikidata.findLinkToItemWithCallback(eachLocationId, false, getShortNameRetrieverClosure(ts))
					end
					table.insert(locationNamesList, locationNames[eachLocationId])
				end
				if 0 < #locationNamesList then
					table.insert(
						valueList,
						appendToString({
							emptyToNil({table.concat(locationNamesList, ', ')}),
							wikidata.outputReferences(actualClaim)
						})
					)
				end
			end
		end	
	end
	if #valueList == 0 then return '' end
	if separator == nil then separator = '; ' end
	if maxvalues > #valueList then maxvalues = #valueList end
	return table.concat(valueList, separator, 1, maxvalues)
end

p.displayFromArgs = function(args)
	local param = nil
	local entity = nil
	local timestamp = nil
	local maxvalues = 1
	local separator = '; '
	if args[1] or args['param'] then
		param = args[1] or args['param']
	end
	if args[2] or args['entityId'] then
		entity = args[2] or args['entityId']
	end
	if args[3] or args['timestamp'] then
		timestamp = args[3] or args['timestamp']
	end
	if args[4] or args['maxvalues'] then
		maxvalues = tonumber(args[4] or args['maxvalues'])
	end
	if args[5] or args['separator'] then
		separator = args[5] or args['separator']
	end
	return p.displayFromParams(param, entity, timestamp, maxvalues, separator)
end

p.displayFromFrame = function(frame)
	local args = getArgs(frame, { frameOnly = true })
	return p.displayFromArgs(args)
end

p.displayFromParentFrame = function(frame)
	local args = getArgs(frame, { parentOnly = true})
	return p.displayFromArgs(args)
end

return p