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

local p = {}

local title = mw.title.getCurrentTitle()

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

local function markValue(value, as, opt)
	return '<span class="wd-' .. as .. '">' .. value .. '</span>[[Kategorie:Údržba:'
		.. mw.ustring.format(i18n[as], opt.catbase or ('Vlastnost ' .. opt.property))
		.. '|' .. title.text .. ']]'
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 markValue(value, 'not', options)
	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 markValue(value, 'same', options)
				end
			end
		end
		return markValue(value, 'diff', options)
	elseif datatype == "globe-coordinate" or "wikibase-property" 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 markValue(value, 'same', options)
				end
			end
		end
		return markValue(value, 'diff', options)
	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 markValue(value, 'same', options)
						end
					end
				end
				break -- only the first one
			end
		end
		return markValue(value, 'diff', options)
	elseif datatype == "time" then
		value = mw.ustring.gsub(value, '%[%[%s*([^|%]]+)%s*[^%]]*%]%]', '%1')
		value = mw.ustring.gsub(mw.ustring.lower(value), '\s*%([^%)]+%)', '')
		local Time = require 'Modul:Time'
		local Date = require 'Modul:Wikidata/datum'
		for _, statement in pairs(Statements) do
			if statement.mainsnak.snaktype == "value" then
				local timevalue = Time.newFromWikidataValue(statement.mainsnak.datavalue.value)
				if timevalue 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 Split = mw.text.split(string, '[^%w]+')
						local Table = {}
						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
						}
						local i = 0
						for _, value in pairs(Split) do
							if tonumber(value) then
								table.insert(Table, tonumber(value))
							else
								for month in pairs(Months) do
									if value == month then
										table.insert(Table, Months[value])
										break
									end
								end
							end
						end
						if #Values == 1 then
							if tonumber(Values[1]) then
								Table = Time.new{
									year = tonumber(Values[1])
								}
							end
						elseif #Values == 2 then
							if tonumber(Values[1]) and tonumber(Values[2]) then
								if tonumber(Values[1]) < tonumber(Values[2]) then
									Table = Time.new{
										year = tonumber(Table[2]),
										month = tonumber(Values[1])
									}
								else
									Table = Time.new{
										year = tonumber(Table[1]),
										month = tonumber(Values[2])
									}
								end
							elseif tonumber(Values[1]) or tonumber(Values[2]) then
								Table = Time.new{
									year = tonumber(Values[1]) or tonumber(Values[2]),
									month = (tonumber(Values[1]) and Months[Values[2]]) or Months[Values[1]] or nil
								}
							end
						elseif #Values == 3 then
							if tonumber(Values[3]) and tonumber(Values[1]) then
								Table = Time.new{
									year = tonumber(Values[3]),
									month = tonumber(Values[2]) or Months[Values[2]] or nil,
									day = tonumber(Values[1]) or nil
								}
							end
						end
						if Table then
							if Date.IsSecondSameAsFirst(timevalue, Table) then
								return markValue(value, 'same', options)
							end
						end
					end
					return markValue(value, 'diff', options)
				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 markValue(value, 'diff', options)
		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
					table.insert(Values, firstToUpper(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
						table.insert(Strings, firstToUpper(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
				table.insert(Strings, firstToUpper(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 markValue(value, 'same', options)
	end
	return markValue(value, 'diff', options)
end

return p