置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Sandbox/850710247liu/Topic list

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [创建] [刷新]
-- 中文Minecraft Wiki同名模块,原作者为Star00和MysticNebula70
-- 授权协议:CC BY-NC-SA 3.0

local p = {}

local getArgs = require('Module:Arguments').getArgs

function conv(talk)
	-- 关键词替换
	-- 如有字符导致生成错误,请在这里添加转换
	talk = talk
		:gsub('===(.-)===', '%1')
		:gsub('Special:用户贡献/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1') -- handle ip user first
		:gsub('Special:Contributions/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1')
		:gsub('Special:Contribs/(%d+%.%d+%.%d+%.%d+)', 'User:ip:%1')
		:gsub('用户', 'User')
		:gsub('user', 'User')
		:gsub('UTC', 'CST')
	return talk
end

function titleStrip(talk)
	-- 论题转换
	talk = talk
		:gsub('===(.-)===', '%1')
	return talk
end

function titleConv(title)
	-- 论题转换
	title = title
		:gsub('<.->', '')
		:gsub('%[%[:?.-|(.-)%]%]', '%1')
		:gsub('%[%[:?(.-)%]%]', '%1')
	return title
end

function table.unique(t, bArray)
	local check = {}
	local n = {}
	local idx = 1
	for k, v in pairs(t) do
		if not check[v] then
			if bArray then
				n[idx] = v
				idx = idx + 1
			else
				n[k] = v
			end
			check[v] = true
		end
	end
	return n
end

function getTimeStyle(time)
	if time == '该讨论主题已被存档' then
		return 'background-color: #fee;'
	end
	local _, _, year, month, day, hour, min = time:find '(%d+)年(%d+)月(%d+)日%s%(.-%)%s(%d+):(%d+)'

	-- divided by 86400 is to convert seconds to days
	local diff = os.difftime(os.time(), os.time {year = year, month = month, day = day, hour = hour, min = min}) / 86400

	if diff >= 30 then
		return 'background-color: #bbb;'
	end
	if diff >= 7 then
		return 'background-color: #ddd;'
	end
	if diff >= 1 then
		return ''
	end
	return 'background-color: #efe;'
end

function close(text)
	if text:match 'closed%-topic%-yes' then
		return 'background-color: #efe;'
	end
	if text:match 'closed%-topic%-no' then
		return 'background-color: #fee;'
	end
	return ""
end

function trim(text)
	-- remove special strip markers and spaces
	text = mw.text.killMarkers(text):gsub('^[%s\t\r\n\f]*(.-)[%s\t\r\n\f]*$', '%1')
	return text
end

function makeUserLink(text)
	if text == '?' then
		return text
	end
	-- 输入用户名以及带有ip:前缀的ip用户。
	local ipUser = text:match 'ip:(.*)'
	if ipUser then
		return '[[Special:用户贡献/' .. ipUser .. '|' .. ipUser .. ']]'
	else
		return '[[User:' .. text .. '|' .. text .. ']]'
	end
end

function getTalkList(pageName)
	-- 输入页面名,返回一个包含文本的讨论信息表
	-- 例如:talklist[1][text]
	local talk = conv(mw.getCurrentFrame():expandTemplate {title = ':' .. pageName}) .. '=='
	local talkList = {}
	for topic in talk:gmatch '==\n(.-)==' do
		talkList[#talkList + 1] = topic
	end

	return talkList
end

function getTitleList(pageName)
	local talk = titleStrip(mw.getCurrentFrame():expandTemplate {title = ':' .. pageName})
	local titleList = {}
	for title in talk:gmatch '==(.-)==' do
		titleList[#titleList + 1] = titleConv(trim(title))
	end

	return titleList
end

function getTalkTime(talk)
	local result = talk:match '[%s%S]*(%d%d%d%d.*) %(CST%)' or '该讨论主题已被存档'

	return result
end

function getUserInfo(text)
	-- 输入讨论的文本,输出和User有关的转换部分table
	local userList = {}
	if text:match '[^\n]*User:([^\n]-)%|[^\n]-CST' == nil then
		return {userNum = '-', uniqueUserNum = '-', firstUser = '-', lastUser = '-'}
	end
	for user in text:gmatch '[^\n]*User:([^\n]-)%|[^\n]-CST' do
		userList[#userList + 1] = user
	end

	local userNum = #userList
	local uniqueUserNum = #(table.unique(userList, true))

	return {userNum = userNum, uniqueUserNum = uniqueUserNum, firstUser = userList[1], lastUser = userList[#userList]}
end

function generateTable(pageName, talkTitle, talkText)
	local body = {
		'{| class="wikitable sortable mw-collapsible talktable" style="text-align: center; margin: 0 auto; width: 100%;"',
		'|-',
		'! # !! 话题 !! 发言条数 !! 参与人数 ',
		'! class="talkpage-topic-list-author" | 发起者',
		'! class="talkpage-topic-list-last-editor" | 最后发言者',
		'! class="talkpage-topic-list-time" | 最后发言时间(CST)'
	}

	local userInfo, time
	local userStyle, uniqueUserStyle, timeStyle, serialStyle

	for i = 1, #talkText do
		time, userInfo = getTalkTime(talkText[i]), getUserInfo(talkText[i])
		-- 对表格添加样式
		userStyle = userInfo.userNum == 1 and 'background-color: #fcc;' or ''
		uniqueUserStyle = userInfo.uniqueUserNum == 1 and 'background-color: #fcc;' or ''
		timeStyle = getTimeStyle(time)
		serialStyle = close(talkText[i])
		-- 组装表格一个话题的部分
		table.insert(
			body,
			table.concat(
				{
					'|-',
					'! style="' .. serialStyle .. '" | ' .. i,
					'| [[' .. pageName .. '#' .. talkTitle[i] .. '|' .. talkTitle[i].. ']]',
					'| style="' .. userStyle .. '" | ' .. userInfo.userNum,
				        '| style="' .. uniqueUserStyle .. '" | ' .. userInfo.uniqueUserNum,
					'| class="talkpage-topic-list-author" | ' .. makeUserLink(userInfo.firstUser),
					'| class="talkpage-topic-list-last-editor" style="' .. timeStyle .. '" | ' .. makeUserLink(userInfo.lastUser),
					'| class="talkpage-topic-list-time" style="' .. timeStyle .. '" | ' .. time
				},
				'\n'
			)
		)
	end
	table.insert(body, '|}')

	return table.concat(body, '\n')
end

function p.main(frame)
	local args = getArgs(frame)
	local f = mw.getCurrentFrame()

	local talkTitle, talkText = getTitleList(args[1]), getTalkList(args[1])
	if #talkTitle ~= #talkText then
		return error 'Topic list获取错误。'
	end
	for i = 1, #talkTitle do
		talkTitle[i] = f:preprocess(talkTitle[i])
	end
	return generateTable(args[1], talkTitle, talkText)
end

return p