Przejdź do zawartości

Moduł:Wikidane/select

Z Wikibooks, biblioteki wolnych podręczników.
 Dokumentacja modułu [stwórz] [odśwież]
local moduleData = mw.loadData("Module:Wikidane/data")
 
local function loadArg(frame,id)
	local result = frame.args[id]
	if not result or (#result == 0) then
		result = frame:getParent().args[id]
		if not result or (#result == 0) then
			return nil
		end
	end
 
	return result
end
 
local function checkFilters(item, filters)
	for k, v in pairs(filters) do
		mw.log(k)
		local qualifiers = item.qualifiers and item.qualifiers[k]
		if not qualifiers and not v.missing then
			mw.log("missing not available")
			return false
		end
		
		local accepted = false
		for _, w in ipairs(qualifiers) do
			mw.logObject(w, "w")
			if (w.snaktype == "novalue") and v.novalue then
				accepted = true
				break
			end
			
			if (w.snaktype == "somevalue") and v.somevalue then
				accepted = true
				break
			end
			
			if w.snaktype == "value" then
				if (w.datatype == "wikibase-item") and (w.datavalue.type == "wikibase-entityid") and (w.datavalue.value["entity-type"] == "item") and v["Q"..w.datavalue.value["numeric-id"]] then
					accepted = true
					break
				elseif (w.datatype == "globe-coordinate") and (w.datavalue.type == "globecoordinate") and v.globe then
					accepted = true
					break
				end
			end
		end
	
		if not accepted then
			return false
		end
	end

	return true
end

local function take(sequence, maxCount)
	if not maxCount or (type(sequence) ~= "table") or (maxCount < 1) or (#sequence < maxCount) then
		return sequence
	end
	
	local result = {}
	for i = 1, maxCount do
		result[i] = sequence[i]
	end
	
	return result
end

return {
	
prepareFilters = function(frame)
	local result = {}
	for i, v in ipairs(moduleData.qualifiedFilters) do
		local selectors = frame.args[v]
		if selectors and (#selectors > 0) then
			local map = {}
			local any = false
			for _, w in ipairs(mw.text.split(selectors, "%s")) do
				map[w] = true
				any = true
			end
			
			if any then
				result[v] = map
			end
		end
	end
	
	return result
end,

selectProperty = function(pid, filters, qid, maximumNumberOfItems)
	local entity = mw.wikibase.getEntityObject(qid)
	if not entity then
		mw.log(moduleData.warnNoEntity)
		return pid, false
	end
 
 	qid = entity.id
 	
	local claims = entity.claims
	if not claims then
		mw.log(moduleData.warnNoClaims)
		return pid, false
	end
 
	local P, ddd = pid:match"^([Pp]?)(%d%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?%d?)$"
	if not P then
		mw.log(string.format(moduleData.warnPropertyByName, pid))
		P = mw.wikibase.resolvePropertyId(pid)
		if not P then
			return pid, false
		end
		pid = P
	elseif #P == 0 then
		pid = "P" .. pid
	elseif P == "p" then
		pid = "P" .. ddd
	end
 
	local prop = claims[pid]
	if not prop then
		mw.log(string.format(moduleData.warnNoStatements, pid))
		return pid, false
	end
	
	-- load best statements
	local preferred = {}
	local normal = {}
	for i, p in ipairs(prop) do
		if checkFilters(p, filters) then
			if p.rank == "preferred" then
				table.insert(preferred, p)
			elseif p.rank == "normal" then
				table.insert(normal, p)
			end
		end
	end

	if #preferred > 0 then
		return pid, qid, take(preferred, tonumber(maximumNumberOfItems))
	elseif #normal > 0 then
		mw.log(string.format(moduleData.warnUsingNormalRank, pid))
		return pid, qid, take(normal, tonumber(maximumNumberOfItems))
	else
		mw.log(string.format(moduleData.warnNoAcceptableRank, pid))
		return pid, false
	end
end,

}