Moduł:Kontrola autorytatywna

Z Wikipedii, wolnej encyklopedii
Przejdź do nawigacji Przejdź do wyszukiwania
Template-info.png Dokumentacja modułu [zobacz] [edytuj] [historia] [odśwież]
Moduł wykorzystywany przez szablon {{Kontrola autorytatywna}}.
local m = {}

local resources = {
	title = "[[Pomoc:Kontrola autorytatywna|Kontrola autorytatywna]]",
	editLabelLink = '<span class="wdlink">&#x5B;[[:d:%s|<span  title="Brak polskiej etykiety">e</span>]]&#x5D;</span>[[Kategoria:Kontrola autorytatywna potrzebuje polskiej etykiety]]',
	fallbackLabels = { "en", "de", "fr", "it", "cs", "lt", "pt", "es" },
	-- type descriptions
	descriptions = {
		p = "osoba",
		k = "organizacja",
		v = "wydarzenie",
		w = "dzieło",
		s = "słowo kluczowe",
		g = "obiekt geograficzny",
	},
}

local sources = {
	{
		name     = "ISNI",
		hint     = ":en:International Standard Name Identifier",
		property = "P213",
		custom   = function(args, parent)
			local id = args.ISNI or parent.ISNI
			if id then
				return string.sub(id, 1, 4).." "..string.sub(id,5,8).." "..string.sub(id,9,12).." "..string.sub(id,13,16)
			end
		end,
		link     = function(id)
			local linkId, _ = string.gsub(id, " ", "")
			return "http://isni-url.oclc.nl/isni/"..linkId
		end,
		show     = function(id)
			local showId, _ = string.gsub(id, " ", "&thinsp;")
			return showId				
		end,
	},
	{
		name     = "ORCID",
		hint     = ":en:ORCID",
		property = "P496",
		custom   = function(args, parent)
			return args.ORCID or parent.ORCID
		end,
		link     = function(id)
			id = string.gsub(id, "-", "")
			return "http://orcid.org/"..string.sub(id, 1, 4).."-"..string.sub(id,5,8).."-"..string.sub(id,9,12).."-"..string.sub(id,13,16)
		end,
		show     = function(id)
			id = string.gsub(id, "-", "")
			return string.sub(id, 1, 4).."-"..string.sub(id,5,8).."-"..string.sub(id,9,12).."-"..string.sub(id,13,16)
		end,
	},
	{
		name     = "VIAF",
		hint     = "Online Computer Library Center",
		property = "P214",
		custom   = function(args, parent)
			return args.VIAF or parent.VIAF
		end,
		link     = function(id)
			return "http://viaf.org/viaf/"..id
		end,
	},
	{
		name     = "ULAN",
		hint     = ":en:Union List of Artist Names",
		property = "P245",
		custom   = function(args, parent)
			return args.ULAN or parent.ULAN
		end,
		link     = function(id)
			return "http://www.getty.edu/vow/ULANFullDisplay?find=&role=&nation=&subjectid="..id
		end,
	},
	{
		name     = "Europeana",
		hint     = "Europeana",
		property = "P727",
		link     = function(id)
			return "http://www.europeana.eu/portal/record/"..id..".html"
		end,
	},
	{
		name     = "LCCN",
		hint     = "Biblioteka Kongresu",
		property = "P244",
		custom   = function(args, parent)
			local id = args.LCCN or parent.LCCN
			if id then
				return FixCustomLccn(id)
			end
		end,
		link     = function(id)
			return "http://lccn.loc.gov/"..id
		end,
	},
	{
		name     = "GND",
		hint     = "Gemeinsame Normdatei",
		property = "P227",
		custom   = function(args, parent)
			return args.GND or parent.GND or parent.PND
		end,
		link     = function(id)
			return "http://d-nb.info/gnd/"..id
		end,
	},
	{
		name     = "NDL",
		hint     = ":de:Web NDL Authorities",
		property = "P349",
		custom   = function(args, parent)
			return args.NDL or parent.NDL
		end,
		link     = function(id)
			return "http://id.ndl.go.jp/auth/ndlna/"..id
		end,
	},
	{
		name     = "LIBRIS",
		hint     = "LIBRIS",
		property = "P5587",
		link     = function(id)
			return "https://libris.kb.se/katalogisering/"..id
		end,
	},
	{
		name     = "SELIBR",
		hint     = "LIBRIS",
		property = "P906",
		custom   = function(args, parent)
			return args.SELIBR or parent.SELIBR
		end,
		link     = function(id)
			return "http://libris.kb.se/auth/"..id
		end,
	},
	{
		name     = "BnF",
		hint     = "Biblioteka Narodowa Francji",
		property = "P268",
		custom   = function(args, parent)
			return args.BNF or parent.BNF
		end,
		link     = function(id)
			return "http://catalogue.bnf.fr/ark:/12148/cb"..id
		end,
	},
	{
		name     = "SUDOC",
		hint     = ":fr:Système universitaire de documentation",
		property = "P269",
		custom   = function(args, parent)
			return args.SUDOC or parent.SUDOC
		end,
		link     = function(id)
			return "http://www.idref.fr/"..id
		end,
	},
	{
		name     = "SBN",
		hint     = ":it:Servizio bibliotecario nazionale",
		property = "P396",
		link     = function(id)
			return "http://id.sbn.it/af/"..id
		end,
	},
	{
		name     = "NLA",
		hint     = ":en:National Library of Australia",
		property = "P409",
		link     = function(id)
			return "http://nla.gov.au/anbd.aut-an"..id
		end,
	},
	{
		name     = "BNCF",
		hint     = ":it:Biblioteca Nazionale Centrale di Firenze",
		property = "P508",
		link     = function(id)
			return "http://thes.bncf.firenze.sbn.it/termine.php?id="..id
		end,
	},
	{
		name     = "NKC",
		hint     = "Biblioteka Narodowa Republiki Czeskiej",
		property = "P691",
		link     = function(id)
			return "http://aut.nkp.cz/"..id
		end,
	},
	{
		name     = "DBNL",
		hint     = ":nl:Digitale Bibliotheek voor de Nederlandse Letteren",
		property = "P723",
		link     = function(id)
			return "http://www.dbnl.org/auteurs/auteur.php?id="..id
		end,
	},
	{
		name     = "RSL",
		hint     = ":ru:Российская государственная библиотека",
		property = "P947",
		link     = function(id)
			return "http://aleph.rsl.ru/F?func=find-b&find_code=SYS&adjacent=Y&local_base=RSL11&request="..id
		end,
	},
	{
		name     = "BNE",
		hint     = ":es:Biblioteca Nacional de España",
		property = "P950",
		link     = function(id)
			return "http://catalogo.bne.es/uhtbin/authoritybrowse.cgi?action=display&authority_id="..id
		end,
	},
	{
		name     = "BNR",
		hint     = ":ro:Biblioteca Națională a României",
		property = "P1003",
		link     = function(id)
			return "http://alephnew.bibnat.ro:8991/F?func=find-b&request="..id.."&find_code=SYS&adjacent=Y&local_base=NLR10"
		end,
	},
	{
		name     = "NTA",
		hint     = ":nl:Koninklijke Bibliotheek (Nederland)",
		property = "P1006",
		link     = function(id)
			return "http://opc4.kb.nl/PPN?PPN="..id
		end,
	},
	{
		name     = "BIBSYS",
		hint     = ":no:BIBSYS",
		property = "P1015",
		link     = function(id)
			return "http://ask.bibsys.no/ask/action/result?cmd=&kilde=biblio&cql=bs.autid+%3D+"..id.."&feltselect=bs.autid"
		end,
	},
	{
		name     = "CALIS",
		hint     = ":zh:中国高等教育文献保障系统",
		property = "P270",
		link     = function(id)
			return "http://opac.calis.edu.cn/aopac/ajsp/detail.jsp?actionfrom=1&actl=CAL++"..id.."%23"
		end,
	},
	{
		name     = "CiNii",
		hint     = ":jp:CiNii",
		property = "P271",
		link     = function(id)
			return "http://ci.nii.ac.jp/author/"..id
		end,
	},
	{
		name     = "Open Library",
		hint     = ":en:Open Library",
		property = "P648",
		link     = function(id)
			return "https://openlibrary.org/books/"..id
		end,
	},
	{
		name     = "NLP",
		hint     = "Biblioteka Narodowa (Warszawa)",
		property = "P1695",
		link     = function(id)
			return "http://mak.bn.org.pl/cgi-bin/KHW/makwww.exe?BM=01&IM=04&NU=01&WI="..id
		end,
	},
	{
		name     = "OBIN",
		hint     = ":en:Dictionary of National Biography",
		property = "P1415",
		link     = function(id)
			return "http://www.oxforddnb.com/index/"..id.."/"
		end,
	},
}

local show = function(args, parent, foreign, entity)
	local claims = (entity and entity.type == "item") and entity.claims or {}
	local namespace = foreign and -1 or mw.title.getCurrentTitle().namespace --TODO remove foreign constrait when entities API is available for them
	
	function FixCustomLccn(id)
		local a, b, c = string.match(id, "([%a%d]*)/([%a%d]*)/([%a%d]*)")
		if not c then
			return id
		end
		
		local pad = 6 - string.len(c)
		if pad > 0 then
			c = string.rep("0", pad)..c
		end
		
		return a..b..c
	end
	
	function identifiers(info)
		local result = {}
		local new = false
		local custom = nil
		if info.custom then
			custom = info.custom(args, parent)
			new = custom and (#custom > 0)
		end
		
		local data = claims[info.property]
		if data then
			for _, v in ipairs(data) do
				if v.mainsnak.snaktype == "value" then
					local id = v.mainsnak.datavalue.value
					table.insert(result, id)
					if new and (id == custom) then
						new = false
					end
				end
			end
		end
	
		if new then
			table.insert(result, custom)
		end
		
		return result
	end
	
	function insertWorldCat(result)
		local worldCatId = args.WORLDCATID or parent.WORLDCATID
		if worldCatId == "" then
			-- disable link
			return
		elseif worldCatId then
			table.insert(result, "<li>[http://www.worldcat.org/identities/" .. worldCatId .. " WorldCat]</li>")
			return
		end
		
		-- try LCCN
		local lccn = args.LCCN or parent.LCCN
		if (not lccn or (#lccn == 0)) and claims.P244 then
			local snak = claims.P244[1].mainsnak
			if snak.snaktype == "value" then
				lccn = snak.datavalue.value
			end
		elseif lccn then
			lccn = FixCustomLccn(lccn)
		end
		
		if lccn and (#lccn > 0) then
			table.insert(result, "<li>[http://www.worldcat.org/identities/lccn-" .. lccn .. " WorldCat]</li>")
			return
		end
		
		-- try VIAF
		local viaf = args.VIAF or parent.VIAF
		if (not viaf or (#viaf == 0)) and claims.P214 then
			if claims.P214[1].mainsnak.snaktype == "value" then
				viaf = claims.P214[1].mainsnak.datavalue.value
			end
		end
		
		if viaf and (#viaf > 0) then
			table.insert(result, "<li>[http://www.worldcat.org/identities/viaf-" .. viaf .. " WorldCat]</li>")
			return
		end
		
		-- there is no link available
	end
	
	function determineCustomType()
		local value = args.TYP or parent.TYP
		if value == "" then
			return "", nil
		end
		
		local description = resources.descriptions[value]
		if value and description then
			return value, description
		end
	end

	function determineDnbType()
		if claims.P1687 or claims.P1963 then
			return "s"
		elseif claims.P21 and (claims.P21[1].mainsnak.snaktype == "value") then
			local v = claims.P21[1].mainsnak.datavalue.value["numeric-id"]
			if (v == 6581097) or (v == 6581072) then
				return "p"
			end
		elseif claims.P27 or claims.P26 or claims.P25 or claims.P22 or claims.P40 or claims.P106 or claims.P1317 then
			return "p"
		elseif claims.P50 or claims.P170 or claims.P86 or claims.P87 or claims.P676 or claims.P435 then
			return "w"
		elseif claims.P112 or claims.P159 or claims.P169 or claims.P488 or claims.P355 or claims.P740 then
			return "k"
		elseif claims.P150 or claims.P610 or claims.P1589 or claims.P85 or claims.P35 or claims.P36 or claims.P47 or claims.P984 or claims.P474 or claims.P982 or claims.P300 or claims.P901 then
			-- claims.P625 cannot be used, there are some organizations, events, and even persons with this property
			return "g"
		end
	end

	function determineWDType()
		-- determine type using recomended way
		local wikiInfo = claims.P31 or claims.P279
		if not wikiInfo or (wikiInfo[1].mainsnak.snaktype ~= "value") then
			return nil
		end

		-- determine non-standard type for display purposes only
		local id = wikiInfo[1].mainsnak.datavalue.value["numeric-id"]
		local wikiid = "Q"..id
		local site = mw.wikibase.sitelink(wikiid)
		local label = mw.wikibase.label(wikiid)
		if site and label then
			return "[["..site.."|"..label.."]]"
		elseif site then
			return "[["..site.."]]"
		else
			return label
		end
	end

	function determineType()
		local customValue, customDescription = determineCustomType()
		if customValue and (#customValue > 0) then
			return customValue, customDescription
		end
		
		local dnbType = determineDnbType()
		local wdType = determineWDType()
		return dnbType or "fehlt", dnbType == "p" and resources.descriptions[dnbType] or (wdType or resources.descriptions[dnbType])
	end
	
	local formats = {
		classic = function(info, identifiers)
			local result = {}
			table.insert(result, "[[")
			table.insert(result, info.hint)
			table.insert(result, "|")
			table.insert(result, info.name)
			table.insert(result, "]]")
			local show = info.show or function(id) return id end
			for i, id in ipairs(identifiers) do
				table.insert(result, (i == 1) and ":" or ",")
				table.insert(result, "&thinsp;<span class=\"uid\">[")
				table.insert(result, info.link(id))
				table.insert(result, " ")
				table.insert(result, show(id))
				table.insert(result, "]</span>")
			end
			
			return table.concat(result, "")
		end,
		
		mini = function(info, identifiers)
			local result = {}
			if #identifiers == 1 then
				-- simple link with authority name
				local id = identifiers[1]
				table.insert(result, "[")
				table.insert(result, info.link(id))
				table.insert(result, " ")
				table.insert(result, string.format(info.format or "<span title=\"%s\">%s</span>", id, info.name))
				table.insert(result, "]")
				return table.concat(result, "")
			end

			table.insert(result, info.name)
			for i, id in ipairs(identifiers) do
				table.insert(result, (i == 1) and ":" or ",")
				table.insert(result, "&thinsp;[")
				table.insert(result, info.link(id))
				table.insert(result, " ")
				table.insert(result, string.format("<span title=\"%s\">%s</span>", id, tostring(i)))
				table.insert(result, "]")
			end
			
			return table.concat(result, "")
		end,
	}
	
	local result = {}
	local formatItems = formats[args.style] or formats.classic
	for _, info in ipairs(sources) do
		local list, cat = identifiers(info)
		if #list > 0 then
			table.insert(result, "<li>"..formatItems(info, list).."</li>")
		end
	end

	insertWorldCat(result)
	if #result > 0 then
		local typ, description = determineType()
		local editLabelLink = ""
		if foreign then
			local site, label
			if entity then
				site = entity:getSitelink()
				label = entity:getLabel()
				if not label then
					editLabelLink = string.format(resources.editLabelLink, foreign)
					for _, l in ipairs(resources.fallbackLabels) do
						label = entity:getLabel(l)
						if label then
							break
						end
					end
				end
			end
			if site and label then
				description = "[["..site.."|"..label.."]]"
			elseif site then
				description = "[["..site.."]]"
			elseif label then
				description = label
			else
				description = foreign
			end
		end
		
		table.insert(result, 1, "<div id=\"normdaten\" class=\"catlinks normdaten-typ-"..typ.."\">"..resources.title)
		if description and (#description > 0) then
			table.insert(result, 2, "&nbsp;(" .. description.. ")" .. editLabelLink .. ":<ul>")
		else
			table.insert(result, 2, ":<ul>")
		end
		table.insert(result,"</ul></div>")
		return table.concat(result, "");
	end
end

m["Dokumentacja"] = function(frame)
	local result = {}
	table.insert(result, "{| class=wikitable\n!nazwa\n!cecha\n!parametr\n!dostawca\n")
	for i, v in ipairs(sources) do
		if i > 0 then
			table.insert(result, "|-\n")
		end
		
		table.insert(result, "|")
		table.insert(result, v.name)
		table.insert(result, "\n")
		
		table.insert(result, "|[[:d:Property:")
		table.insert(result, v.property)
		table.insert(result, "|")
		table.insert(result, v.property)
		table.insert(result, "]]\n")
		
		table.insert(result, "|")
		table.insert(result, v.custom and ("<tt>"..string.upper(v.name).."</tt>") or "—")
		table.insert(result, "\n")
		
		table.insert(result, "|[[")
		table.insert(result, v.hint)
		table.insert(result, "]]\n")
	end
	
	table.insert(result, "|}")
	
	return table.concat(result, "")
end

m["Pokaż"] = function (frame)
	
	local args = frame.args
	local parent = frame:getParent().args
	
	local foreign = args[1] or parent[1]
	local entity = mw.wikibase.getEntityObject(foreign)

	local result = {
		-- typical result
		show(args, parent, foreign, entity)	
	}
	
	if entity and entity.claims and entity.claims.P31 then
		local group = false
		local idGroupOfHumans = 'Q16334295'
		for _, v in ipairs(entity.claims.P31) do
			if v.mainsnak.snaktype == "value" then
				local id = v.mainsnak.datavalue.value.id
				if id == idGroupOfHumans then
					group = true
					break
				end
				
				local status, result = pcall(mw.wikibase.getReferencedEntityId, id, 'P279', { idGroupOfHumans })
				if not status then
					-- za dużo wywołań, max 3
					break
				end
				
				if result then
					group = true
					break
				end
			end
		end

		if group and entity.claims.P527 then
			for i, v in ipairs(entity.claims.P527) do
				if i > 5 then
					-- za dużo wyników, polegajmy tylko na pierwszym
					return result[1]
				end
				
				if v.snaktype == "value" then
					local id = "Q"..tostring(v.mainsnak.datavalue.value["numeric-id"])
					local data = mw.wikibase.getEntityObject(id)
					if data then
						local s = show({}, {}, id, data)
						if s then
							table.insert(result, s)
						end
					end
				end
			end
		end
	end
	
	if #result > 0 then
		return table.concat(result, "")
	end
end

return m