Modul:Wikidata/ValueComparison

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
local WikidataValueComparison = {}

WikidataValueComparison.MaintenanceCategories = function(params)
	local categories = {}

-- check whether the provided P-identifier is useful (provided, valid format, existent in repository, and of 'external-id' datatype)
	if not params['property'] then
		mw.log('WikidataValueComparison.MaintenanceCategories(): no P-identifier provided')
		return categories
	end
	
	if not string.match(params['property'], '^P[1-9][0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?[0-9]?$') then -- P-identifiers with more than 9 digits are generally not recognized by the system
		mw.log('WikidataValueComparison.MaintenanceCategories(): invalid P-identifier "' .. params['property'] ..'" provided')
		return categories
	end

	if mw.wikibase.entityExists(params['property']) then -- attention: https://phabricator.wikimedia.org/T143970 https://phabricator.wikimedia.org/T192462
		propObject = mw.wikibase.getEntity(params['property'])
	else
		mw.log('WikidataValueComparison.MaintenanceCategories(): invalid/non-existent property "' .. params['property'] .. '"')
		return categories
	end
	
	if propObject.datatype ~= 'external-id' then
		mw.log('WikidataValueComparison.MaintenanceCategories(): "' .. params['property'] .. '" is not an external-id property')
		return categories
	end

-- check if local namespace in list of approved namespaces
	local namespaceOk = false
	local ns = mw.title.getCurrentTitle().namespace
	for v in mw.text.gsplit(params['namespaces'] or '0', ',', true) do
		if tonumber(v) == ns then
			namespaceOk = true
		end
	end
	if not namespaceOk then -- skip comparison if not in approved namespace
		mw.log('WikidataValueComparison.MaintenanceCategories(): wrong namespace')
		return categories
	end

-- check whether the article is connected to Wikidata
	local entity = mw.wikibase.getEntity()
	if not entity then -- skip comparison if unconnected
		mw.log('WikidataValueComparison.MaintenanceCategories(): no Wikidata item connected')
		if params['cat_no_item'] then
			table.insert(categories, params['cat_no_item'])
		end
		return categories
	end

-- check whether any claims of the given property are found in the connected item
	local claims = entity.claims or {}
	local hasProp = claims[params['property']]
	if not hasProp then -- no claim of that property
		mw.log('WikidataValueComparison.MaintenanceCategories(): connected item does not have a claim with property "' .. params['property'] .. '"')
		if params['localValue'] ~= '' and params['cat_wd_missing'] then
			table.insert(categories, params['cat_wd_missing'])
		end
		return categories
	end

-- claim(s) of that property found, so do the actual value comparison ...
	if type(hasProp) == 'table' and #hasProp == 1 then -- exactly one claim found, so simply process it
		local claim = claims[params['property']][1]
		if (claim.mainsnak.snaktype == 'novalue' or claim.mainsnak.snaktype == 'somevalue') and claim.rank ~= 'deprecated' and params['localValue'] ~= '' then -- Wikidata: novalue or unknown value, but local value given
			mw.log('WikidataValueComparison.MaintenanceCategories(): novalue/somevalue in Wikidata, custom value locally')
			if params['cat_wd_missing'] then
				table.insert(categories, params['cat_wd_missing'])
			end
			if params['cat_wd_different'] then
				table.insert(categories, params['cat_wd_different'])
			end
			return categories
		end
		if claim.mainsnak.snaktype == 'value' and claim.rank ~= 'deprecated' then -- Wikidata custom value
			mw.log('WikidataValueComparison.MaintenanceCategories(): custom value in Wikidata')
			if params['localValue'] == '' and params['cat_local_missing'] then -- no local value provided
				table.insert(categories, params['cat_local_missing'])
			elseif params['localValue'] ~= claim.mainsnak.datavalue.value and params['cat_wd_different'] then -- different local value provided
				table.insert(categories, params['cat_wd_different'])
			end
			return categories
		end
	else -- more than one claim found, loop over them
		if params['localValue'] == '' then -- no or empty local value provided
			local throw_wp_missing_cat = true
			for i, claim in ipairs(hasProp) do
				if (claim.mainsnak.snaktype == 'novalue' or claim.mainsnak.snaktype == 'somevalue') and claim.rank ~= 'deprecated' then
					throw_wp_missing_cat = false -- disputable
				end
			end
			if throw_wp_missing_cat and params['cat_local_missing'] then
				mw.log('WikidataValueComparison.MaintenanceCategories(): local value missing')
				table.insert(categories, params['cat_local_missing'])
				return categories
			end
		else -- custom local value provided
			local throw_wd_missing_cat = true
			local throw_different_value_cat = true
			for i, claim in ipairs(hasProp) do
				if claim.mainsnak.snaktype == 'value' and claim.rank ~= 'deprecated' and claim.mainsnak.datavalue.value == params['localValue'] then
					throw_wd_missing_cat = false
					throw_different_value_cat = false
				end
			end
			mw.log('WikidataValueComparison.MaintenanceCategories(): custom local value')
			if throw_wd_missing_cat and params['cat_wd_missing'] then
				table.insert(categories, params['cat_wd_missing'])
			end
			if throw_different_value_cat and params['cat_wd_different'] then
				table.insert(categories, params['cat_wd_different'])
			end
			return categories
		end
	end
	mw.log('WikidataValueComparison.MaintenanceCategories(): value comparison successful, but nothing to categorize')
	return categories
end --WikidataValueComparison.MaintenanceCategories()

-- export
local p = {}

function p.compareValues(frame)
	local enableComparison = frame:getParent().args['wikidata_vergleich'] or nil
	if enableComparison=='nein' then
		mw.log('WikidataValueComparison.compareValues(): comparison disabled via template parameter "wikidata_vergleich"')
		return ''
	end

	local params = {}

	params['property'] = frame.args['eigenschaft'] or nil
	params['localValue'] = frame.args['lokaler_identifikator'] or ''
	params['namespaces'] = frame.args['namensräume'] or '0'

-- 	params['cat_no_item'] = frame.args['kat_kein_objekt'] or 'Kategorie:Wikipedia:Artikel ohne Wikidata-Datenobjekt' -- better call {{Wikidata-Registrierung}} explicitly in the template
	params['cat_local_missing'] = frame.args['kat_fehlt_lokal'] or nil -- no equivalent concept in Wikidata

	params['cat_wd_missing'] = frame.args['kat_fehlt_in_wd'] or nil -- conceptually as in Q28858528
	params['cat_wd_different'] = frame.args['kat_wd_verschieden'] or nil -- conceptually as in Q29075121
-- 	params['cat_same_value'] = frame.args['kat_gleicher_wert'] or nil -- conceptually as in Q29075123; undesired at dewiki
--	params['cat_using_wd'] = frame.args['kat_nutzt_wd'] or nil -- conceptually as in Q40218570; at dewiki we don't use identifiers directly yet
	
	local success, categories = pcall(WikidataValueComparison['MaintenanceCategories'], params)
	local wikitext = ''
	for i, category in ipairs(categories) do
		wikitext = wikitext .. '[[' .. category .. ']]'
	end
	return wikitext or ''
end --p.compareValues()

function p.WikidataValueComparison() -- export for use in other modules
	return WikidataValueComparison
end

return p