Mô đun:Sandbox/Ioe2015/voteCount

Tài liệu mô đun[tạo]
local getArgs = require('Module:Arguments').getArgs
local TableTools = require('Module:TableTools')
local ColorContract = require("Module:Color contrast")
local error = require("Mô đun:Error").error

local p = {}
local inArray = TableTools.inArray

function tprint (tbl, indent) -- Stolen from StackOverflow
  if not indent then indent = 0 end
  local toprint = string.rep(" ", indent) .. "{\r\n"
  indent = indent + 2 
  for k, v in pairs(tbl) do
    toprint = toprint .. string.rep(" ", indent)
    if (type(k) == "number") then
      toprint = toprint .. "[" .. k .. "] = "
    elseif (type(k) == "string") then
      toprint = toprint  .. k ..  "= "   
    end
    if (type(v) == "number") then
      toprint = toprint .. v .. ",\r\n"
    elseif (type(v) == "string") then
      toprint = toprint .. "\"" .. v .. "\",\r\n"
    elseif (type(v) == "table") then
      toprint = toprint .. tprint(v, indent + 2) .. ",\r\n"
    else
      toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n"
    end
  end
  toprint = toprint .. string.rep(" ", indent-2) .. "}"
  return toprint
end

function p.getPage(title)
	local page = mw.title.new(title)
	local content = ""
	if page.exists then
		 content = mw.text.trim(page:getContent())
	else
		error({"Trang không tồn tại"})
	end
	return content
end

function p.getVotingTemplates(content, lowerCase, filtered)
	if lowerCase == nil then
		lowerCase = true
	end
	if filtered == nil then
		filtered = true
	end
	
	local list = {}
	local pattern = "^([#*]:?[^\n]?[^\n]?[^\n]?[^\n]?[^\n]?{{[^\n]-}})"
	local strikethru = false
	for line in mw.text.gsplit(content, '\n', true) do
		line = mw.text.trim(line)
		if line ~= '' then
			
			start, final, match = mw.ustring.find(line, pattern)
			if start then
				--mw.log(match)
				final = start + #match - 1
				strikethru = mw.ustring.match(match, "<s>") ~= nil
				templName = mw.ustring.match(match, "[^\n]*{{([^\n]-)}}")
				--mw.log(templName)
				if (not filtered) or (not strikethru) then
					if lowerCase then
						templName = mw.ustring.lower(templName)
					end
					list[#list + 1] =  templName
				end
			end
		end
	end
	return list
end

function p.isKeepVote(name)
	local names = {"bqg", "phiếu giữ", "giữ", "phiếu giữ nhanh"}
	return inArray(names, name)
end

function p.isDeleteVote(name)
	local names = {"bqx", "phiếu xóa", "bqx2", "phiếu xóa nhanh"}
	return inArray(names, name)
end

function p.isAgreeVote(name)
	local names = {
		"ok",
		"đồng ý",
		"tán thành",
		"agree",
		"ủng hộ",
		"support",
		"đồng ý hai tay",
	}
	return inArray(names, name)
end

function p.isDisagreeVote(name)
	local names = {
		"phản đối",
		"chưa đồng ý",
		"phản đối mạnh",
		"phản đối kịch liệt",
		"chống",
		"ok?",
		"oppose",
		"disagree",
	}
	return inArray(names, name)
end

function p.isCommentTempl(name)
	local names = {
		"yk",
		"ykk",
		"ý kiến",
		"ý kiến khác",
	}
	return inArray(names, name)
end

function p._keep(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isKeepVote(template) then
			count = count + 1
		end
	end
	return count
end

function p._delete(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isDeleteVote(template) then
			count = count + 1
		end
	end
	return count
end

function p._agree(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isAgreeVote(template) then
			count = count + 1
		end
	end
	return count
end

function p._disagree(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isDisagreeVote(template) then
			count = count + 1
		end
	end
	return count
end

function p._comment(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isCommentTempl(template) then
			count = count + 1
		end
	end
	return count
end

function p._all(templates)
	local count = 0
	for _, template in pairs(templates) do
		if p.isKeepVote(template)
			or p.isDeleteVote(template)
			or p.isAgreeVote(template)
			or p.isDisagreeVote(template)
			then
			count = count + 1
		end
	end
	return count
end

local types = {
	agree = p._agree,
	disagree = p._disagree,
	keep = p._keep,
	delete = p._delete,
	comment = p._comment,
	all = p._all,
}

function p.count(frame)
	local args = getArgs(frame, {
		parentFirst = true,
	})
	if not args[2] then
		args[2] = mw.title.getCurrentTitle().fullText
	end
	return p._count(args)
end

function p._count(args)
	local type = args[1]
	local templates = p.getVotingTemplates(p.getPage(args[2]))
	local types = types
	local count = -1
	
	if types[type] ~= nil then
		count = types[type](templates)
	end
	
	return count
end

function p.getCountTable(templates)
	function incTableVal(t, key)
		if t[key] ~= nil then
			t[key] = t[key] + 1
		else
			t[key] = 1
		end
	end
	
	local ret = {}
	for _, template in pairs(templates) do
		if p.isKeepVote(template) then
			incTableVal(ret, "keep")
		elseif p.isDeleteVote(template) then
			incTableVal(ret, "delete")
		elseif p.isAgreeVote(template) then
			incTableVal(ret, "agree")
		elseif p.isDisagreeVote(template) then
			incTableVal(ret, "disagree")
		end
	end
	local total = 0
	for k, v in pairs(ret) do
		total = total + v
	end
	return ret, total
end

function p.display(frame)
	local args = getArgs(frame, {
		parentFirst = true,
	})
	if not args[1] then
		args[1] = mw.title.getCurrentTitle().fullText
	end
	return p._display(args)
end

function p._display(args)
	local container = mw.html.create("div"):css({
		float = "right",
		["text-align"] = "center",
		width = "70px",
		height = "20px",
	})

	local templates = p.getVotingTemplates(p.getPage(args[1]))
	--mw.log(tprint(templates))
	local counts, total = p.getCountTable(templates)

	local len = TableTools.size(counts)
	local colorMap = {
		keep = "blue",
		delete = "orange",
		agree = "green",
		disagree = "red",
	}
	for type, count in pairs(counts) do
		container:tag("span"):css({
			float = "left",
			width = mw.ustring.format("%.2f%%", count / total * 100),
			height = "100%",
			display = "inline-flex",
			["align-items"] = "center",
			["justify-content"] = "center",
			["background-color"] = colorMap[type],
			color = ColorContract._greatercontrast(
				{colorMap[type], "white", "black"}
			)
		}):wikitext(count):done()
	end

	return tostring(container:allDone())
end

-- =p._display({"Thành viên:Ioe2015/Bản mẫu/Thử"})

return p