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