2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module:Sandbox/Bbrabbit

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索
Template-info.svg 模块文档  [创建] [刷新]
local luaq = require("Module:Luaq")
local module = {}
local getArgs = require("Module:Arguments").getArgs

-- 从UserGroup模块获取所有萌娘百科维护组成员的用户名
function module._get_userlist(js)
	local _user_mod = require(tostring(mw.title.new("Module:UserGroup")))
	local users = _user_mod.enumerate('')
	local hash_users = {}
	if js ~= nil then
        	return mw.text.jsonEncode(users)
	end
	for _, u in ipairs(users) do
		hash_users[u] = false
	end
	return hash_users
end

-- 根据filter获取每个用户组的人数,filter的定义参考UserGroup模块
function module._get_usercount(f)
	local _user_mod = require(tostring(mw.title.new("Module:UserGroup")))
	local users = _user_mod.enumerate(f)
	return #users
end

-- 计数函数
function module._count(content)
	local count_table = {["管理员"] = {},["巡查姬"] = {}, ["自动确认用户"] = {}, voted = {}, error = {}}
	local role = ""
	local vote = ""
	if content ~= nil then
		local vote_area = mw.text.split(content,"==(=?)(%s+)投票区(.-)==(=?)\n") -- 找到最后一个投票区开始计数
		vote_area = vote_area[#vote_area]
		for line in mw.text.gsplit(vote_area, "\n") do -- 按行处理每一个可能的投票内容
			-- 根据小标题判断投票归类于哪一个用户组
			if mw.ustring.find(line, "===(=?)(%s*)管理员(.-)===(=?)") then 
				role = "管理员"
			elseif mw.ustring.find(line, "===(=?)(%s*)巡查姬(.-)===(=?)") then
				role = "巡查姬"
			elseif mw.ustring.find(line, "===(=?)(%s*)参与讨论的自动确认用户(%s*)===(=?)") then
				role = "自动确认用户"
			elseif mw.ustring.find(line, "===(=?)(%s*)无票权用户意见(%s*)===(=?)") then
				break
			else
				--[[local patterns = {
            '%[%[%s*[Uu][Ss][Ee][Rr]%s*:([^|%]/\\]+)%]%]',
            '%[%[%s*[Uu][Ss][Ee][Rr]%s*:([^|%]/\\]+)|.-%]%]', 
			'%[%[%s*[Uu]%s*:([^|%]/\\]+)|.-%]%]',
			'%[%[%s*:[Uu][Ss][Ee][Rr]%s*:([^|%]/\\]+)%]%]',
            '%[%[%s*:[Uu][Ss][Ee][Rr]%s*:([^|%]/\\]+)|.-%]%]', 
			'%[%[%s*:[Uu]%s*:([^|%]/\\]+)|.-%]%]',
       	 		}]]--
				--[[for _, p in ipairs(patterns) do
					username = mw.ustring.match(line, p)
					if username ~= nil then
						break
					end
				end]]--
				-- 根据投票前的投票模板判断当前投票
				if mw.ustring.find(line, "{{同意}}") then
				vote = "同意"
				elseif mw.ustring.find(line, "{{反对}}") then
				vote = "反对"
				elseif mw.ustring.find(line, "{{弃权}}") then
				vote = "弃权"
				end
				-- 去除用删除线删去的投票
				local del_pattern = {".*<del>.*</del>$",".*<s>.*</s>"}
				if line == "" then
				elseif mw.ustring.match(line, del_pattern[1]) or mw.ustring.match(line, del_pattern[2]) then
				else
					-- 使用Sig2User模块获取投票人的用户名
					local frame = mw.getCurrentFrame()
					local username = frame:callParserFunction{name="#invoke:Sig2User",args={"main", line, suppress="nil"}}
					-- 如果出现解析错误则放入count_table["error"]表中等待人工判断
					if username == "Error: Invalid signature" then
						table.insert(count_table["error"], line)
					else
						-- 否则将投票人的用户名存入count_table中
						if count_table[role] == nil then
							count_table[role] = {}
						end
						if count_table[role][vote] == nil then
							count_table[role][vote] = {}
						end
						table.insert(count_table[role][vote], username)
						table.insert(count_table["voted"], username)	
					end	
				end
			end
		end
	end
	return count_table
end

-- 包装frame:expandTemplate函数,如果expand为false则直接返回模板
function module._expandTemplate(frame, template, expand)
	if expand then
		return frame:expandTemplate{title=template}
	else 
		return "{{"..template.."}}"
	end
end		

function module.main(frame)
	local args = getArgs(frame)
	title = args["title"]
	local users = module._get_userlist()
	local parent = frame:getParent()
	local caller = nil
	local expand = true
	-- 如果title参数为nil则获取当前frame的父frame的title
	if title == nil then
		caller = parent:getTitle()
	else
		-- 否则使用title参数内容
		caller = title
		expand = false
	end
	-- 获取上一步中title的内容
	local content = mw.title.new(caller):getContent()
	local count_table = module._count(content)
	-- 将count_table["voted"]表中的内容和所有萌百维护组用户名一一比对,标记所有投票的维护组成员
	for _, v in ipairs(count_table["voted"]) do
		if users[v] ~= nil then
			users[v] = true
		end
	end
	-- 过滤出所有没有投票的维护组成员
	local filtered = luaq.asQuery(users):where(function(_,_,v) return v==false end):query()
	local not_voted =  ""
	local not_voted_count = 0
	for _ , v in ipairs(filtered) do
		not_voted = not_voted .. v .. ", "
		not_voted_count = not_voted_count + 1
	end
	-- 计算有多少自动确认用户投票,假设所有投票的自动确认用户都有票权
	local ac_users = 0
	for _, v in pairs(count_table["自动确认用户"]) do
		if v ~= nil then
			ac_users = ac_users + #v
		end
	end
	-- 拼接结果字符串
	local vote_result = "投票开始时共有".. module._get_usercount('s') .."名参与站务的管理员;其中,".. "\n" .. 
		"*'''".. #(count_table["管理员"]["同意"] or {}) .."'''人"..module._expandTemplate(parent,"同意",expand).. "\n" ..
		"*'''".. #(count_table["管理员"]["反对"] or {}) .."'''人"..module._expandTemplate(parent,"反对",expand).. "\n" ..
		"*'''".. #(count_table["管理员"]["弃权"] or {}) .."'''人"..module._expandTemplate(parent,"弃权",expand).. "\n" ..
		"投票开始时共有".. module._get_usercount('p') .. "名正式巡查姬;其中,".. "\n" ..
		"*'''".. #(count_table["巡查姬"]["同意"] or {}) .."'''人"..module._expandTemplate(parent,"同意",expand).. "\n" ..
		"*'''".. #(count_table["巡查姬"]["反对"] or {}) .."'''人"..module._expandTemplate(parent,"反对",expand).. "\n" ..
		"*'''".. #(count_table["巡查姬"]["弃权"] or {}) .."'''人"..module._expandTemplate(parent,"弃权",expand).. "\n" ..
		"共有".. ac_users .. "名有票权的自动确认用户参与了投票;其中".. "\n" ..
		"*'''".. #(count_table["自动确认用户"]["同意"] or {}) .."'''人"..module._expandTemplate(parent,"同意",expand).. "\n" ..
		"*'''".. #(count_table["自动确认用户"]["反对"] or {}) .."'''人"..module._expandTemplate(parent,"反对",expand).. "\n" ..
		"*'''".. #(count_table["自动确认用户"]["弃权"] or {}) .."'''人"..module._expandTemplate(parent,"弃权",expand).. "\n" ..
		"共有".. not_voted_count .."人没有参与投票(".. string.sub(not_voted,0, #not_voted-2) ..")".. 
		"<hr/>"..
		"----对"..caller.."的自动计票结束,请人工复核后发布----" .. "\n" 
		-- 如果error表中有值则打印error表内容
		-- 由于目前_count函数不会处理====同意====这类小标题,error表会一直有值
		-- TODO: 处理小标题和模板进入error表的问题
		if #count_table["error"] ~= 0 then
		vote_result = vote_result .. "以下签名无法解析,请手动添加" .. "\n" ..
			mw.dumpObject(count_table["error"]) 
		end
	return vote_result
end

return module