Přeskočit na obsah

Modul:Wikidata/compare

Tuto stránku mohou editovat jen zavedení uživatelé a správci.
Z Wikipedie, otevřené encyklopedie
(rozdíl) ← Starší revize | zobrazit aktuální verzi (rozdíl) | Novější revize → (rozdíl)

local p = {}

local title = mw.title.getCurrentTitle()

local i18n = {
	diff = 'Vlastnost %s se liší od Wikidat',
	miss = 'Vlastnost %s není na Wikidatech',
	same = 'Vlastnost %s odpovídá Wikidatům',
}

local function addCat(key, prop)
	return '' --'[[Kategorie:Údržba:' .. mw.ustring.format(i18n[key], prop) .. '|' .. title.pagename .. ']]'
end

local function markAsDiff(value, prop)
	return '<span class="wd-diff">' .. value .. '</span>' .. addCat('diff', prop)
end

local function markAsMissing(value, prop)
	return '<span class="wd-not">' .. value .. '</span>' .. addCat('miss', prop)
end

local function markAsSame(value, prop)
	return '<span class="wd-same">' .. value .. '</span>' .. addCat('same', prop)
end

local function firstToUpper(value)
	local Functions = require 'Modul:Functions'
	return Function.firstToUpper(value)
end

function p.compareValues(value, Statements, options)
	local namespace = title.namespace
	if namespace ~= 0 and namespace ~= 14 then
		return value
	end

	if #Statements == 0 then
		return markAsMissing(value)
	end

	local Values, Strings = {}, {}
	local datatype = Statements[1].mainsnak.datatype
	value = mw.ustring.gsub(value, '<([a-z]+)%f[^%w][^>]->.-</%1>%s*', '')
	if datatype == "commonsMedia" or datatype == "string" then
		for _, statement in pairs(Statements) do
			if statement.mainsnak.snaktype == "value" then
				value = mw.ustring.gsub(value, '\s*%([^%)]+%)', '')
				if tostring(statement.mainsnak.datavalue.value) == tostring(value) then --TODO: normalizing
					return markAsSame(value)
				end
			end
		end
		return markAsDiff(value)
	elseif datatype == "globe-coordinate" then
		return value
	elseif datatype == "monolingualtext" then
		for _, statement in pairs(Statements) do
			if statement.mainsnak.snaktype == "value" then
				if statement.mainsnak.datavalue.value.text == value then
					return markAsSame(value)
				end
			end
		end
		return markAsDiff(value)
	elseif datatype == "quantity" then
		if mw.ustring.match(value, '%d+') then
			for value in mw.ustring.gmatch(value, '(%-?%d+)') do
				for _, statement in pairs(Statements) do
					if statement.mainsnak.snaktype == "value" then
						local lowerBound = tonumber(statement.mainsnak.datavalue.value.lowerBound)
						local upperBound = tonumber(statement.mainsnak.datavalue.value.upperBound)
						value = tonumber(value)
						if value >= lowerBound and value <= upperBound then
							return markAsSame(value)
						end
					end
				end
				break -- only the first one
			end
		end
		return markAsDiff(value)
	elseif datatype == "time" then
		value = mw.ustring.gsub(value, '%[%[%s*([^|%]]+)%s*[^%]]*%]%]', '%1')
		value = mw.ustring.gsub(value:lower(), '\s*%([^%)]+%)', '')
		local convertTable = function(Table)
			if #Table > 3 or #Table == 0 then return nil end
			local Months = {
				["leden"] = 1, ["ledna"] = 1,
				["únor"] = 2, ["února"] = 2,
				["březen"] = 3, ["března"] = 3,
				["duben"] = 4, ["dubna"] = 4,
				["květen"] = 5, ["května"] = 5,
				["červen"] = 6, ["června"] = 6,
				["červenec"] = 7, ["července"] = 7,
				["srpen"] = 8, ["srpna"] = 8,
				["září"] = 9,
				["říjen"] = 10, ["října"] = 10,
				["listopad"] = 11, ["listopadu"] = 11,
				["prosinec"] = 12, ["prosince"] = 12
			}
			if #Table == 1 then
				return tonumber(Table[1]) and { year = tonumber(Table[1]) } or nil
			elseif #Table == 2 then
				if tonumber(Table[1]) and tonumber(Table[2]) then
					if tonumber(Table[1]) < tonumber(Table[2]) then
						return { year = tonumber(Table[2]), month = tonumber(Table[1]) }
					else
						return { year = tonumber(Table[1]), month = tonumber(Table[2]) }
					end
				elseif tonumber(Table[1]) or tonumber(Table[2]) then
					return {
						year = tonumber(Table[1]) or tonumber(Table[2]),
						month = (tonumber(Table[1]) and Months[Table[2]]) or Months[Table[1]] or nil
					}
				end
				return nil
			else
				if tonumber(Table[3]) and tonumber(Table[1]) then
					return {
						year = tonumber(Table[3]),
						month = tonumber(Table[2]) or Months[Table[2]] or nil,
						day = tonumber(Table[1]) or nil
					}
				end
				return nil
			end
		end
		local Time = require 'Modul:Time'
		for _, statement in pairs(Statements) do
			if statement.mainsnak.snaktype == "value" then
				local timevalue = Time.newFromWikidataValue(statement.mainsnak.datavalue.value)
				if timevalue and timevalue.precision > 8 then
					for string in mw.text.gsplit(value, '%s*<[^<>%w]-br[^<>%w]->%s*') do
						string = mw.ustring.sub(string, 1, mw.ustring.match(string, '%d?%d%d%d()') or -1)
						local Table = mw.text.split(string, '[^%w]+')
						Table = convertTable(Table)
						if Table and Table.year then
							if timevalue.year == Table.year then
								if timevalue.precision == 9 then
									return markAsSame(value)
								end
								if Table.month and timevalue.month == Table.month then
									if timevalue.precision == 10 then
										return markAsSame(value)
									end
									if Table.day and timevalue.day == Table.day then
										return markAsSame(value)
									end
								end
							end
						end
					end
					return markAsDiff(value)
				end
			end
		end
		return value
	elseif datatype == "url" then
		if mw.ustring.match(value, 'https?://') then
			for string in mw.ustring.gmatch(value, '(https?://[^%[%]%s]+)') do
				table.insert(Strings, string)
			end
			for _, statement in pairs(Statements) do
				if statement.mainsnak.snaktype == "value" then
					table.insert(Values, statement.mainsnak.datavalue.value)
				end
			end
		else
			return markAsDiff(value)
		end
	elseif datatype == "wikibase-item" then
		for _, statement in pairs(Statements) do
			if statement.mainsnak.snaktype == "value" then
				local id = 'Q' .. statement.mainsnak.datavalue.value["numeric-id"]
				local value = mw.wikibase.sitelink(id) or mw.wikibase.label(id)
				if value then
					value = firstToUpper(value)
					table.insert(Values, value)
				end
			end
		end
		if mw.ustring.match(value, '<[^<>%w]-br[^<>%w]->') then
			for string in mw.text.gsplit(value, '<[^<>%w]-br[^<>%w]->') do
				string = mw.ustring.gsub(string, '\s*%([^%(%)]+%)', '')
				if mw.ustring.match(string, '%[%[[^%]%[]-%]%]') then
					for page in mw.ustring.gmatch(string, '%[%[%s*([^|%]]-)%s*[|%]]') do
						string = firstToUpper(string)
						table.insert(Strings, page)
					end
				else
					table.insert(Strings, mw.text.trim(string))
				end
			end
		elseif mw.ustring.match(value, '%[%[[^%]%[]-%]%]') then
			for string in mw.ustring.gmatch(value, '%[%[%s*([^|%]]-)%s*[|%]]') do
				string = firstToUpper(string)
				table.insert(Strings, string)
			end
		end
	end
	local i = 0
	for _, string in pairs(Strings) do
		for _, value in pairs(Values) do
			if string == value then
				i = i + 1
				break
			end
		end
	end
	if #Strings > 0 and #Values > 0 and i == #Strings then
		return markAsSame(value)
	end
	return markAsDiff(value)
end

return p