Moduł:Wikidane/select

Z Wikipedii, wolnej encyklopedii
 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)
	
	local function currentUtcTime() return os.date("!+%FT%TZ") end

	for k, v in pairs(filters) do
		local qualifiers = item.qualifiers and item.qualifiers[k]
		if not qualifiers then
			return v.missing or false
		end
		
		local accepted = false
		for _, w in ipairs(qualifiers) do
			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
				elseif (w.datatype == "time") and (w.datavalue.type == "time") and (w.datavalue.value.calendarmodel == "http://www.wikidata.org/entity/Q1985727") then
					if v.before and (currentUtcTime() < w.datavalue.value.time) then
						accepted = true
						break
					elseif v.after and (currentUtcTime() > w.datavalue.value.time) then
						accepted = true
						break
					end
				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

local rankLoaders =
{
	["najlepsza"] = {
		get = mw.wikibase.getBestStatements,
	},
	["preferowana lub zwykła"] = {
		get = mw.wikibase.getAllStatements,
		group = function(rank) return ((rank == "preferred") or (rank == "normal")) and 1 or false end,
	},
	["dowolna"] = {
		get = mw.wikibase.getAllStatements,
		group = function(rank) if rank == "preferred" then return 1 elseif rank == "normal" then return 2 else return 3 end end,
	},
	["preferowana"] = {
		get = mw.wikibase.getAllStatements,
		group = function(rank) return rank == "preferred" and 1 or false end,
	},
	["zwykła"] = {
		get = mw.wikibase.getAllStatements,
		group = function(rank) return rank == "normal" and 1 or false end,
	},
	["przestarzała"] = {
		get = mw.wikibase.getAllStatements,
		group = function(rank) return rank == "deprecated" and 1 or false end,
	},
	["wszystkie"] = {
		get = mw.wikibase.getAllStatements,
	},
}

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, rank)
	qid = qid or mw.wikibase.getEntityIdForCurrentPage()
	if not qid then
		mw.log(moduleData.warnNoEntity)
		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 loader = rankLoaders[rank or "najlepsza"]
	if not loader then
		return pid, false
	end
	
	mw.log("\n== selectProperty ==")
	mw.logObject(rank, "rank")
	mw.logObject(loader, "loader")
	mw.logObject(filters, "filters")
	
	local prop = loader.get( qid, pid )
	if not prop or (#prop == 0) then
		mw.log(string.format(moduleData.warnNoStatements, pid))
		return pid, false
	end
	
	mw.logObject(#prop, "#prop A")
	local hasFilters = false
	for _, _ in pairs(filters) do
		hasFilters = true
		break
	end
	
	if loader.group or hasFilters then
		local group = loader.group or function() return 1 end
		local results = {{},{},{},{},{}}
		for _, p in ipairs(prop) do
			local g = group(p.rank)
			if g and results[g] and checkFilters(p, filters) then
				table.insert(results[g], p)
			end
		end
		
		for i, v in ipairs(results) do
			prop = results[i]
			if #prop > 0 then
				break
			end
		end
		
		mw.logObject(#prop, "#prop B")
	end

	if #prop > 0 then
		return pid, qid, take(prop, tonumber(maximumNumberOfItems))
	end
	
	return pid, false
end,

}