Hopp til innhold

Modul:Wikidata2

Fra Wikipedia, den frie encyklopedi

local p = {}
require('strict')
--local WikidataDato = require( 'Module:WikidataDato' )

-- Wrapper for pcall which returns nil on failure.
local function quickPcall(func)
	local success, result = pcall(func)
	if success then
		return result
	end
end

-- Count words by ','
local function countpattern(x) 
	local _, count = x:gsub(", ","") 
	return count 
end

local function parseInput(frame)
	local qid = frame.args.qid
	if qid and (#qid == 0) then qid = nil end
	local propertyID = mw.text.trim(frame.args[1] or "")
	local input_parm = mw.text.trim(frame.args[2] or "")
	if input_parm ~= "hent_wikidata" then
		return false, input_parm, nil, nil
	end
	local entity = mw.wikibase.getEntityObject(qid)
	local claims
	if entity and entity.claims then
		claims = entity.claims[propertyID]
		if not claims then
			return false, "", nil, nil
		end
	else
		return false, "", nil, nil
	end
	return true, entity, claims, propertyID
end

local function isType(claims, type)
		return claims[1] and claims[1].mainsnak.snaktype == "value" and claims[1].mainsnak.datavalue.type == type
end

local function getValue(entity, claims, propertyID, delim, labelHook) 
	if labelHook == nil then
		labelHook = function (qnumber)
			return nil;
		end
	end
	if isType(claims, "wikibase-entityid") then
		local out = {}
		for k, v in pairs(claims) do
			local qnumber = "Q" .. v.mainsnak.datavalue.value["numeric-id"]
			local sitelink = mw.wikibase.sitelink(qnumber)
			local label = labelHook(qnumber) or mw.wikibase.label(qnumber) or qnumber
			if sitelink then
				out[#out + 1] = "[[" .. sitelink .. "|" .. label .. "]]"
			else
				out[#out + 1] = label
			end
		end
		return table.concat(out, delim)
	else
		-- just return best values
		return entity:formatPropertyValues(propertyID).value
	end
end

-- This is used to get a normal wiki-linked value, or a comma separated list of them if multiple values exist
p.getValue = function(frame)
	if not mw.wikibase then
        return ""
    end
    local propertyID = mw.text.trim(frame.args[1] or "")
    local input_parm = mw.text.trim(frame.args[2] or "")
    local table_separator = mw.text.trim(frame.args[3] or ",")
    if input_parm == "hent_wikidata" then
        local entity = mw.wikibase.getEntityObject()
        if not entity then
        	return ""
    	end
        if entity.claims and entity.claims[propertyID] ~= nil then
            local out = {}
            for k, v in pairs(entity.claims[propertyID]) do
            	if v.mainsnak.datavalue then
            		local numericId = v.mainsnak.datavalue.value["numeric-id"]
            		if numericId then
                    	if (mw.wikibase.sitelink("Q" .. numericId)) and mw.wikibase.label("Q" .. numericId) then
                        	out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. numericId) .. "|" .. mw.wikibase.label("Q" .. numericId) .. "]]"
                    	elseif (mw.wikibase.sitelink("Q" .. numericId)) then
                            out[#out + 1] = "[[" .. mw.wikibase.sitelink("Q" .. numericId) .. "]]"
                        else
                            out[#out + 1] = mw.wikibase.label("Q" .. numericId)
                        end
                    end
                end
            end
            return table.concat(out, table_separator .. ' ')
        else
            return ""
        end
    else
        return input_parm
    end
end

-- This is used to get a value like 'male' (for property p21) which won't be linked
p.getRawValue = function(frame)
	if not mw.wikibase then
        return ""
    end
    local propertyID = mw.text.trim(frame.args[1] or "")
    local input_parm = mw.text.trim(frame.args[2] or "")
    local table_separator = mw.text.trim(frame.args[3] or ",")
    if input_parm == "hent_wikidata" then
        local entity = mw.wikibase.getEntityObject()
                if not entity then
        	return ""
    	end
        if entity.claims[propertyID] ~= nil then
            local out = {}
            for k, v in pairs(entity.claims[propertyID]) do
                out[#out + 1] = mw.wikibase.label("Q" .. v.mainsnak.datavalue.value["numeric-id"])
            end
            return table.concat(out, table_separator .. ' ')
        else
            return ""
        end
    else
        return input_parm
    end
end

p.getValueShortName = function(frame)
	local go, errorOrentity, claims, propertyID = parseInput(frame)
	if not go then
		return errorOrentity
	end
	local entity = errorOrentity
	-- if wiki-linked value output as link if possible
	local function labelHook (qnumber)
		local label
		local claimEntity = mw.wikibase.getEntity(qnumber)
		if claimEntity ~= nil then
			if claimEntity.claims.P1813 then
				for k2, v2 in pairs(claimEntity.claims.P1813) do
					if v2.mainsnak.datavalue.value.language == "nb" then
						label = v2.mainsnak.datavalue.value.text
					end
					if v2.mainsnak.datavalue.value.language == "en" then
						label = v2.mainsnak.datavalue.value.text
					end
				end
			end
		end
		if label == nil or label == "" then return nil end
		return label
	end
	return getValue(errorOrentity, claims, propertyID, ", ", labelHook);
end

-- This is used to get a date value for date_of_birth (p569), etc. which won't be linked -- consolidate by testing if entity.claims[propertyID].mainsnak.datavalue.type is "time"
p.getDateValue = function(frame)
	if not mw.wikibase then
        return ""
    end
    local propertyID = mw.text.trim(frame.args[1] or "")
    local input_parm = mw.text.trim(frame.args[2] or "")
    local table_separator = mw.text.trim(frame.args[3] or "")
    if input_parm == "hent_wikidata" then
        local entity = mw.wikibase.getEntityObject()
                if not entity then
        	return ""
    	end
        if entity.claims[propertyID] ~= nil then
        	local date_temp = 'ISOtilNorskdato'
            local out = {}
            local dt = {}
            for k, v in pairs(entity.claims[propertyID]) do
                local d = v.mainsnak.datavalue.value.time
                lyear = string.sub(d, 9, 12)
                lmonth = string.sub(d, 14, 15)
                lday = string.sub(d, 17, 18)
                out[#out + 1] = mw.getCurrentFrame():expandTemplate{ title = date_temp, args = { lyear .. "-" .. lmonth ..  "-" .. lday, 'n' } }
            end
            return table.concat(out, table_separator .. ' ')
        else
            return ""
        end
    else
        return input_parm
    end
end

-- Get the rank of statement
local function getRank(prop)
	local rank = prop.rank
	if rank == 'preferred' then
		return 1
	elseif rank == 'normal' then
		return 0
	elseif rank == 'deprecated' then
		return -1
	else
		return 0 -- No rank or undefined rank is treated as "normal".
	end
end

-- Get the Q-id from the site or arg.
local function getId(id)
    local artikkel
    if not mw.wikibase then
        return ''
    end
    if id then
    	artikkel = mw.wikibase.getEntity(id)
    else
    	artikkel = mw.wikibase.getEntity()
    end
    if not artikkel then
    	return ''
    end
    return artikkel
end

-- Gets all values and add a dot (".") to it.
p.getFile_extension = function(frame)
 	local exts = {}
	
    local artikkel = getId(frame.args[1])
	local fileExten = artikkel:getBestStatements('P1195')
	
	for i, ext in ipairs(fileExten) do
	    exts[#exts+1] = ("." .. ext.mainsnak.datavalue.value)
	end
	return mw.text.nowiki(table.concat(exts, ', '))
end

local function formatEntityId(entityId,i)
    local label
    local link = mw.wikibase.sitelink( entityId )
	if i == 1 then
    	label = mw.wikibase.label( entityId )
    	label = label:gsub("^%l", string.upper)
    else
    	label = mw.wikibase.label( entityId )
    end
    if link then
        if label then
            return '[[' .. link .. '|' .. label .. ']]'
        else
            return '[[' .. link .. ']]'
        end
    elseif label then
        return label --TODO what if no links and label + fallback language?
    else
        return ''
    end
end

-- Gets all values and if multip. add [[Multi paradigm]]: if more then two q-values...
p.paradigme = function(frame)
 	local paradigms = {}
	
    local artikkel = getId(frame.args[1])
    if artikkel == "" then
    	return ""
    end
	local paradigm = artikkel:getBestStatements('P3966')
	local count = 0
	for i, paradig in ipairs(paradigm) do
		if paradig.mainsnak.datavalue.value.id ~= 'Q4306983' then --multi-paradigm programming
			count = count + 1
	    	paradigms[#paradigms+1] = formatEntityId(paradig.mainsnak.datavalue.value.id,count)
	    end
	end

	if paradigms[2] then
		local values = table.concat(paradigms, ', ')
		local multi = '[[' .. mw.wikibase.sitelink('Q188267') .. '|' .. 'Multi-paradigme' .. ']]' .. ': '
		if count >= 5 then
			return string.format([[<div class="mw-collapsible mw-collapsed"><div class="sentrert">%s paradigmer</div> <div class="mw-collapsible-content">%s</div></div>]], 
			count, multi .. values)
    	else
    		return multi .. values
    	end
	elseif paradigms[1] then
    	return paradigms[1]
    elseif paradigm[1] then
    	return '[[' .. mw.wikibase.sitelink('Q188267') .. '|' .. 'Multi-paradigme' .. ']]'
    else
    	return ""
	end
end

-- Filter on rank and qqid. Then return with "," between statements.
local function findBestProperty(entity, pid, qqid, ppid)
    local props = {}
    local propsAlt = {}

    local prop = quickPcall(function ()
	return entity['claims'][pid]
    end)

    if not prop then
        return ''
    end
	
    for i, pro in ipairs(prop) do
        local rank = getRank(pro)
        if rank == 1 and pro.qualifiers and pro.qualifiers[ppid] and pro.qualifiers[ppid][1].datavalue.value.id == qqid  then
            	if pro.qualifiers.P577[1].datatype == 'time' then
            		props[#props+1] = pro.mainsnak.datavalue.value .. ' / ' .. mw.wikibase.renderSnak(pro.qualifiers.P577[1])
            	else
            		props[#props+1] = pro.mainsnak.datavalue.value
            	end
        elseif rank == 0 and pro.qualifiers and pro.qualifiers[ppid] and pro.qualifiers[ppid][1].datavalue.value.id == qqid then
        		propsAlt[#propsAlt+1] = pro.mainsnak.datavalue.value
        			
    	end
    end
	if props[1] then 
		return quickPcall(function () 
			return table.concat(props, ', ') 
			end) 
	elseif propsAlt[1] then 
		return quickPcall(function () 
			return table.concat(propsAlt, ', ') 
			end)
	else
		return ''
	end
end

-- Find the version that you are looking for. Adds it to a collapsed class if over 5.
p.getVersion = function(frame)
    local artikkel = getId(frame.args[1]) -- Args[1] is the Q-id (alt)
    local pid = frame.args.pid -- Property (Pxx) under Q-value (Qxxxx)
    local qQid = frame.args.qqid -- Secound Q-id
    local pPid = frame.args.ppid -- Secound P-id (Property)
    local alle = frame.args.alle -- if 'ja' and if findBestProperty() return nil, get all statements
	
    local priVersions = quickPcall(function () 
			return findBestProperty(artikkel,pid,qQid,pPid)
			end)
    if priVersions == '' and alle == 'ja' and artikkel ~= "" then
		local temp = artikkel:formatPropertyValues( pid, mw.wikibase.entity.claimRanks )
		priVersions = temp['value']
	elseif priVersions == '' or priVersions == nil then
		return ''
    end
    if countpattern(priVersions) > 5 then
		return string.format([[<div class="mw-collapsible mw-collapsed"><div class="sentrert">%s versjoner</div> <div class="mw-collapsible-content">%s</div></div>]], 
		countpattern(priVersions), priVersions)
    else
		return mw.text.nowiki(priVersions)
    end
end

return p