Logo Voyage

Module:FastWikidata Voyage Tips and guide

You can check the original Wikivoyage article Here

    Documentation for this module may be created at Module:FastWikidata/doc

    --[[
    	Source script:	https://de.wikivoyage.org/wiki/Modul:FastWikidata
    	Maintainer:		RolandUnger
    ]]
    local fw = {}
    
    function fw.getEntity( id )
    	local wrongQualifier = false
    	local entity = nil
    	
    	if not id or id == '' then
    		return '', entity, wrongQualifier
    	end
    	if mw.wikibase.isValidEntityId( id ) then
    		-- expensive function call
    		-- redirect ids marked false, too
    		entity = mw.wikibase.getEntity( id )
    	end
    	if not entity then
    		id = ''
    		wrongQualifier = true
    	end
    
    	return id, entity, wrongQualifier
    end
    
    local function getFirstValue( statements )
    	if #statements == 0 then
    		return nil
    	end
    
    	for i = 1, #statements, 1 do
    		if statements[i].mainsnak.snaktype == 'value' then
    			return statements[i].mainsnak.datavalue.value
    		end
    	end
    
    	return nil
    end
    
    local function getNValues( statements, count )
    	local ar = {}
    	if count > #statements then count = #statements end
    	if ( #statements == 0 ) or ( count <= 0 ) then
    		return ar
    	end
    
    	local i = 0
    	repeat
    		i = i + 1
    		if statements[i].mainsnak.snaktype == 'value' then
    			table.insert( ar, statements[i].mainsnak.datavalue.value )
    		end
    	until ( i >= #statements ) or ( #ar >= count )
    
    	return ar
    end
    
    function fw.getBestStatements( entity, p )
    	if type( entity ) == 'string' then
    		return mw.wikibase.getBestStatements( entity, p )
    	else
    		return entity:getBestStatements( p )
    	end
    end
    
    function fw.getStatements( entity, p, count )
    	local ar = {}
    	if ( not entity ) or ( entity == '' ) then
    		return ar
    	end
    
    	local statements = fw.getBestStatements( entity, p )
    
    	count = count or #statements
    	if count > #statements then count = #statements end
    	if ( #statements == 0 ) or ( count <= 0 ) then
    		return ar
    	end
    
    	local i = 0
    	repeat
    		i = i + 1
    		if statements[i].mainsnak.snaktype == 'value' then
    			table.insert( ar, statements[i] )
    		end
    	until ( i >= #statements ) or ( #ar >= count )
    
    	return ar
    end
    
    function fw.getValue( entity, p, catArray )
    	local value = ''
    	if entity and entity ~= '' and p and p ~= '' then
    		value = getFirstValue( fw.getBestStatements( entity, p ) )
    		if value and catArray then
    			catArray[ p ] = ''
    		end
    		value = value or ''
    	end
    	if catArray then
    		return value, catArray
    	else
    		return value
    	end
    end
    
    function fw.getId( entity, p, catArray )
    	local value = ''
    	if entity and entity ~= '' and p and p ~= '' then
    		value = getFirstValue( fw.getBestStatements( entity, p ) )
    		if value then
    			if catArray then catArray[ p ] = '' end
    			value = value.id
    		else
    			value = ''
    		end
    	end
    	if catArray then
    		return value, catArray
    	else
    		return value
    	end
    end
    
    function fw.getValues( entity, p, count, catArray )
    	local values = '', statements
    	if entity and entity ~= '' and p and p ~= '' then
    		statements = fw.getBestStatements( entity, p )
    		values = getNValues( statements, count or #statements )
    		if catArray and #values > 0 then catArray[ p ] = '' end
    	end
    	if catArray then
    		return values, catArray
    	else
    		return values
    	end
    end
    
    function fw.getValuesByLang( entity, p, count, lang, catArray )
    	local ar = '', statements, i, value
    	if entity and entity ~= '' and p and p ~= '' then
    		statements = fw.getBestStatements( entity, p )
    		ar = {}
    		count = count or #statements
    		if #statements > 0 and count > 0 then
    			i = 0
    			repeat
    				i = i + 1
    				if statements[ i ].mainsnak.snaktype == 'value' then
    					value = statements[ i ].mainsnak.datavalue.value
    					if value.language and lang == value.language then
    						table.insert( ar, statements[ i ].mainsnak.datavalue.value.text )
    					end
    				end
    			until ( i >= #statements ) or ( #ar >= count )
    		end
    		if catArray and #ar > 0 then catArray[ p ] = '' end
    	end
    	if catArray then
    		return ar, catArray
    	else
    		return ar
    	end
    end
    
    function fw.getValuesWithQualifierIds( entity, p, qualifierP, defaultId, catArray )
    	local result = {}, statements, value, id, i, j
    	if entity and entity ~= '' and p and p ~= '' and qualifierP and qualifierP ~= '' then
    		statements = fw.getStatements( entity, p, nil )
    		if #statements > 0 then
    			-- defaultId is used if a qualifier is missing
    			if not defaultId or defaultId == '' or type( defaultId ) ~= 'string' then
    				defaultId = 'unknown'
    			end
    
    			if catArray then catArray[ p ] = '' end
    			for i = 1, #statements, 1 do
    				value = statements[ i ].mainsnak.datavalue.value
    				id = defaultId
    				if statements[ i ].qualifiers and statements[ i ].qualifiers[ qualifierP ]
    					and ( #statements[ i ].qualifiers[ qualifierP ] > 0 ) then
    					for j = 1, #statements[ i ].qualifiers[ qualifierP ], 1 do
    						if statements[ i ].qualifiers[ qualifierP ][ j ].snaktype == 'value' then
    							id = statements[ i ].qualifiers[ qualifierP ][ j ].datavalue.value.id
    							break
    						end
    					end
    				end
    				result[ id ] = value
    			end
    		end
    	end
    	if catArray then
    		return result, catArray
    	else
    		return result
    	end
    end
    
    -- get values array for monolingual text
    function fw.getValuesWithLanguages( entity, p, catArray )
    	local result = {}, statements, hyphen, i, lng, value
    	if entity and entity ~= '' and p and p ~= '' then
    		statements = fw.getStatements( entity, p, nil )
    		if #statements > 0 and statements[ 1 ].mainsnak.datatype == 'monolingualtext' then
    			if catArray then catArray[ p ] = '' end
    			for i = 1, #statements, 1 do
    				value = statements[i].mainsnak.datavalue.value
    				lng = value.language
    				hyphen = lng:find( '-' )
    				if hyphen then
    					lng = lng:sub( 1, hyphen - 1 )
    				end
    				if not result[ lng ] then result[ lng ] = value.text end
    			end
    		end
    	end
    	if catArray then
    		return result, catArray
    	else
    		return result
    	end
    end
    
    local function getValueFromDatavalue( datavalue )
    	local v = datavalue.value
    	local t = datavalue.type
    	if type( v ) == 'table' then
    		-- items which can be reduced to a string
    		if t == 'wikibase-entityid' then v = v.id
    		elseif t == 'time' then v = v.time
    		end
    	end
    	return v, t
    end
    
    -- The following function is an experimental one, not for extensive use
    function fw.getValuesWithQualifiers( entity, p, qualifiers, count )
    	local result = {}
    	local statements = fw.getStatements( entity, p, count )
    	if #statements == 0 then return result end
    
    	if qualifiers and ( type( qualifiers ) == 'string' ) then
    		qualifiers = { qualifiers }
    	end
    
    	local array, key, value, i, j
    	for i = 1, #statements, 1 do
    		array = { value = statements[i].mainsnak.datavalue.value,
    			['value-type'] = statements[i].mainsnak.datavalue.type }
    		if statements[i].qualifiers then
    			if not qualifiers then -- all qualifier properties
    				for key, value in pairs( statements[i].qualifiers ) do
    					if #value > 0 then
    						for j = 1, #value, 1 do
    							if value[ j ].snaktype == 'value' then
    								array[ key ], array[ key .. '-type' ] =
    									getValueFromDatavalue( value[ j ].datavalue )
    								break
    							end
    						end
    					end
    				end
    			else -- table of selected qualifier properties
    				for key, value in pairs( qualifiers ) do
    					if statements[i].qualifiers[ value ] and
    						( #statements[i].qualifiers[ value ] > 0 ) then
    						for j = 1, #statements[i].qualifiers[ value ], 1 do
    							if statements[i].qualifiers[ value ][ j ].snaktype == 'value' then
    								array[ value ], array[ value .. '-type' ] =
    									getValueFromgetValueFromDatavalue( statements[i].qualifiers[ value ][ j ].datavalue )
    								break
    							end
    						end
    					end
    				end
    			end
    		end
    		table.insert( result, array )
    	end
    	return result
    end
    
    function fw.typeSearch( p31, list, limit, catArray )
    	-- p31: array of Wikidata values
    	-- list: indexed array of q id - types relations
    	-- limit: maximum levels to analyse
    	if not list or not p31 or #p31 == 0 then
    		return 'error', catArray
    	end
    
    	local function compareIds( ar )
    		local i, t
    		for i = 1, #ar, 1 do
    			t = list[ ar[ i ].id ]
    			if t then
    				return t
    			end
    		end
    		return nil
    	end
    	local aType, i, id, ids, j
    
    	aType = compareIds( p31 ) -- check p31 ids first, maybe step 2 is not nessary
    	if aType then
    		return aType, catArray
    	end
    
    	-- now functions becomes expensive because of multiple fw.getValues calls
    	for i = 1, #p31, 1 do -- step 2: analyse P279 chains of first ids
    		id = p31[ i ].id -- start id
    		j = 0
    		repeat
    			ids, catArray = fw.getValues( id, 'P279', nil, catArray )
    			if #ids > 0 then
    				id = ids[ 1 ].id
    				aType = compareIds( ids )
    				if aType then
    					return aType, catArray
    				end
    			end
    			j = j + 1
    		until j >= limit or #ids == 0
    	end
    
    	return 'error', catArray
    end
    
    function fw.getCategories( catArray, formatStr )
    	result = ''
    	if not catArray then return result end
    	if not formatStr or formatStr == '' then
    		formatStr = '[[Category:%s]]'
    	end
    	for key, value in pairs( catArray ) do
    		result = result .. string.format( formatStr, key )
    	end
    	return result
    end
    
    return fw
    


    Discover



    Powered by GetYourGuide