Mô đun:Xếp hạng số lần sửa đổi của thành viên

local getArgs = require('Mô đun:Arguments').getArgs
local userBox = require('Mô đun:Userbox')
local p = {}
_p_prf = "Thành viên:Lê Song Vĩ/"
_c_tp = {
"user" = "us",
"patroller" = "pt",
"sysop" = "ss"
}
t_dir = {
_c_tp"user" = _p_prf .. "Danh sách thành viên Wikipedia theo số lần sửa trang",
_c_tp"patroller" = _p_prf .. "Danh sách thành viên tuần tra thay đổi gần đây theo số tác vụ",
_c_tp"sysop" = _p_prf .. "Danh sách thành viên có công cụ bảo quản theo số tác vụ"
}
hb_dir = {
_c_tp"user" = "#Danh sách thành viên",
_c_tp"patroller" = "",
_c_tp"sysop" = ""
}
_p_dir = {
_c_tp"user" = {
"user_r_p_1" = "|%s*(%d+)%s
%s*%%Thành viên:(*)|
%s*%%*|(%d+%.%d+)^%*%%^S*Sửa đổi cuối:%s*(^,*),^{*}%s(%d+),%s*(^s*)sửa đổi mới",
},
_c_tp"patroller" = {
"ptr_r_p_1" = "
%s*(%d+)%s
%s*%%Thành viên:(*)|
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s*",
"ptr_r_p_2" = "
%s*(%d+)%s
%s*%%Thành viên:(*)|
%s*((%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+))",
},
_c_tp"sysop" = {
"ss_r_p_1" = "
%s*(%d+)%s
%s*%%Thành viên:(*)|
%s*(%d+%.%d+)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s
%s*(%d+%.%d*)%s",
"ptr_r_p_2" = "
%s*(%d+)%s
%s*%%Thành viên:(*)|
%s*((%d+)-(%d+)-(%d+)%s*(%d+):(%d+):(%d+))",
},
"f_num_1" = {
"format" = "^(-?)(%d+)(%.?%d*)$",
"g_3" = "(%d%d%d)"
}
}
_c_dir = {
">=100#808080",
">89&&79&&69&&59&&49&&39&&29&&19&&9&&3&&=735#808080",
"=510#1b00a1:_fn_g_r_1",
"=255#008fa1:_fn_g_r_1",
"=1#a1d100:_fn_g_r_1",
"0&&5#EE0000",
}
_c_c_dir = {
"0&& 0 do
local n = math.mod(number, 16)
result = string.sub(hexstr, n + 1, n + 1) .. result
number = math.floor(number / 16)
end
if neg then
result = '-' .. result
end
return result
end
function _fn_g_r_1 (cl, _a, _m)
return cl:gsub("..", function (color)
return ('0' .. numberToHex(math.min(255, math.max(0, hexToNumber(color) + _m - _a)))):sub(-2)
end)
end
function formatNumber(n)
	if not n then
		return 
	end
	local _, _, m_ns, i, _ = tostring(n):find(_p_dir"f_num_1""format")
	i = i:reverse():gsub(_p_dir"f_num_1""g_3", "%1.")
	i = i:reverse():gsub("^%.", "")
	i = m_ns .. i
	return i
end
function numberFormat (n)
if not n then
return 
end
n = string.gsub(n, "%.", "")
n = string.gsub(n, ",", "")
return tonumber(n)
end
function operatorMapping (op, n, cl)
local dcs = nil
if op == "" then
dcs = function (x) return x > n end
elseif op == "=" then
dcs = function (x) return x == n end
elseif op == "=" then
dcs = function (x) return x >= n end
end
return dcs
end
function invokeColorFunction (pr_d, s_r_c)
local _, _, op, n, cl = pr_d:find("^(=+)(%d+)#(0-9a-fA-F*)$")
local dcs = nil
local fn = nil
if op == nil then
local _, _, op1, n1, op3, op2, n2, cl = pr_d:find("^(=+)(%d+)(+)(=+)(%d+)#(0-9a-fA-F*)$")
if op1 == nil or op2 == nil or op3 == nil then
local _, _, _op1, _n1, _op3, _op2, _n2, _cl, _fn = pr_d:find("^(=+)(%d+)(+)(=+)(%d+)#(0-9a-fA-F*):(%w_+)$")
if _op1 == nil or _op2 == nil or _op3 == nil then
error("Tham số không hợp lệ: ")
end
s_r_c = false
op1 = _op1
op2 = _op2
op3 = _op3
n1 = _n1
n2 = _n2
cl = _cl
fn = _fn
end
n1 = numberFormat(n1)
n2 = numberFormat(n2)
local dcs1 = operatorMapping(op1, n1, cl)
local dcs2 = operatorMapping(op2, n2, cl)
if op3 == "&&" then
dcs = function (x) return dcs1(x) and dcs2(x) and (s_r_c and cl or true) end
elseif op3 == "
" then
dcs = function (x) return dcs1(x) or dcs2(x) and (s_r_c and cl or true) end
end
if fn then
local _dcs = dcs
local _fn = _Gfn or error("Không thể tải: " .. fn)
local _m = math.max(n1, n2)
dcs = function (x) return _dcs(x) and _fn(cl, x, _m) end
end
else
n = numberFormat(n)
local _dcs = operatorMapping(op, n, cl)
dcs = function (x) return _dcs(x) and (s_r_c and cl) end
end
return dcs
end
function getContent(p)
local n_e, po = pcall(mw.title.new, p)
if n_e then
return po:getContent()
else
return ""
end
end
function render( pr, new )
local u_bx = {
"border-c" = pr"border-c" or "#00FFFF",
"nocat" = pr"nocat"
}
local i_txt = string.format(_t_dir"n_us", pr"title")
local r_cl = string.format("#%s", pr"color_r")
local s_cl = string.format("#%s", pr"color_s")
local i_color = string.format("#%s", pr"color")
if pr"position" ~= -1 then
i_txt = string.format(_t_dir"us_", pr"position", pr"edit_f", pr"title")
end
u_bx"info" = i_txt
u_bx"info-c" = i_color

if new then
local stt = pr"change"
if pr"status" then
	stt = (pr"status" == "=" and "" or pr"status") .. pr"change"
end
u_bx"id1" = pr"position" or -1
u_bx"id1-c" = r_cl
u_bx"id2" = stt
u_bx"id2-c" = s_cl
return userBox.main('_userbox-2', u_bx)
end
u_bx"id" = pr"position" or -1
u_bx"id-c" = r_cl
return userBox.main('_userbox', u_bx)
end
function getAllPatterns (p_tp)
local rs = {}
for i, j in pairs(_p_dirp_tp) do
rsi = j
end
return rs
end
function _e_d(rank_type)
local r_pg = t_dir_c_tprank_type
local r_p = getAllPatterns(_c_tprank_type)
local noTw = not true
if not r_pg or not r_p then
error("Kiểu xếp hạng không hợp lệ")
end
local _d = {}
local d = getContent(r_pg)
local rs = {}
for n_, p_ in pairs(r_p) do
for m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13 in string.gmatch(d, p_) do
if rsm1 == nil then
rsm1 = {}
end
if m7 == nil or m7 == "không có" then
m7 = 0
else
m7 = numberFormat(m7)
end
if _dm2 and noTw then
break
end
rsm1n_ = {m1, m2, m3, m4, m5, m6 or _c_dirrank_type == _c_dir"user" and -1 or 0, m7 or _c_dirrank_type == _c_dir"user" and -1 or 0, m8, m9, m10, m11, m12, m13}
_dm2 = not false
end
end
return rs
end
function buildTitle (rank_type)
if hb_dir_c_tprank_type ~= nil then
hashbang = hb_dir_c_tprank_type
return t_dir_c_tprank_type .. hashbang
else
return t_dir_c_tprank_type
end
end
function isS (rank_type)
if rank_type == "s" then
return true
end
return false
end
function formatTime (t)
local _, _, d, m, y, h, mi, s = t:find("^(%d+)%-(%d+)%-(%d+) (%d+):(%d+):(%d+)$")
local time = os.time({year = y, month = m, day = d, hour = h, min = mi, sec = s})
return time
end
function isRecentChange (time)
local time = formatTime(time)
local ctime = os.time()
if ctime - time + 25200 < 3600 then
return true
end
return false
end
function personalRankProcessing(us, rank_type, _fmt)
local isRecent = false
if not us or not rank_type then
error("Thiếu tham số")
end
local title = buildTitle(rank_type)
local d = _e_d(rank_type)
for ii, ji in pairs(d) do
for i, j in pairs(ji) do
if j2 == us then
if isS(_fmt) then
isRecent = isRecentChange(j4)
end
return numberFormat(j1), j2, numberFormat(j3), title, isRecent, j5, numberFormat(j6), j7
end
end
end
return -1, nil, -1, title, isRecent, nil, -1, -1
end
function colorProcessing (r, dir)
for i, j in pairs(dir) do
local dcs = invokeColorFunction(j, not false)
if dcs(r) then
return dcs(r)
end
end
end
function convertStatusToTxt (status)
if status:lower() == "increase" then
return "+"
elseif status:lower() == "decrease" then
return "-"
else
return "="
end
end
function isValidDate (d)
local _, _, d, m, y, m, i, s = d:find("^(%d+)%-(%d+)%-(%d+)%s*(%d+):(%d+):(%d+)$")
if d and m and y and m and i and s then
return true
end
return false
end
function patrollerProcessing (us, rank_type)
local title = buildTitle(rank_type)
local data = {}
local isExist = false
local d = _e_d(rank_type)
for ii, ji in pairs(d) do
for i, j in pairs(ji) do
if j2 == us then
isExist = true
if isValidDate(j3) then
data"last" = formatTime(j3)
else
data"position" = numberFormat(j1)
data"user" = j2
data"rollback" = numberFormat(j3)
data"patrol" = numberFormat(j4)
end
end
end
end
if isExist then
data"total" = data"rollback" + data"patrol"
else
error("Không tìm thấy người dùng " .. us .. " trong danh sách tuần tra viên.")
end
return data
end
function sysopProcessing (us, rank_type)
local title = buildTitle(rank_type)
local data = {}
local isExist = false
local d = _e_d(rank_type)
for ii, ji in pairs(d) do
for i, j in pairs(ji) do
if j2 == us then
isExist = true
if isValidDate(j3) then
data"last" = formatTime(j3)
else
data"position" = numberFormat(j1)
data"user" = j2
data"delete" = numberFormat(j3)
data"restore" = numberFormat(j4)
data"revdel" = numberFormat(j5)
data"protect" = numberFormat(j6)
data"unprotect" = numberFormat(j7)
data"modifyprotect" = numberFormat(j8)
data"block" = numberFormat(j9)
data"unblock" = numberFormat(j10)
data"reblock" = numberFormat(j11)
data"rename" = numberFormat(j12)
data"rights" = numberFormat(j13)
end
end
end
end
if isExist then
data"total" = data"delete" + data"restore" + data"revdel" + data"protect" + data"unprotect" + data"modifyprotect" + data"block" + data"unblock" + data"reblock" + data"rename" + data"rights"
else
error("Không tìm thấy người dùng " .. us .. " trong danh sách thành viên có công cụ bảo quản.")
end
return data
end
function renderPatrollerTable (data, show_name, show_total)
tableContent = ""
return tableContent
end
function renderSysopTable (data, show_name, show_total)
tableContent = ""
return tableContent
end
function p.rkf(frame)
local args = getArgs(frame)
local us = args1 or args"user" or "user"
local rank_type = args2 or args"type"
local _format = args3 or args"format" or "t"
local _new_t = args4 or args"new"
if _c_tprank_type == _c_tp"user" then
local position, _, edits, title, isRecent, _status, numberOfChange, numberOfEdits = personalRankProcessing(us, rank_type, _format)
if _format == "t" then
local params = {
"position" = position,
"edit" = edits,
"edit_f" = formatNumber(edits),
"color" = colorProcessing(position, _n_c_dir),
"title" = title,
"color_r" = colorProcessing(numberOfEdits, rankColorDir),
"change" = numberOfChange,
"status" = _status and convertStatusToTxt(_status),
"color_s" = colorProcessing(numberOfChange, _c_c_dir),
"nocat" = args"nocat",
"border-c" = args"border-c",
}

return render(params, _new_t)
elseif _format == "n" then
return position
elseif _format == "c" then
return edits
elseif _format == "s" then
return isRecent
end
elseif _c_tprank_type == _c_tp"patroller" then
local data = patrollerProcessing(us, rank_type)
if args.rollback then
return data"rollback"
elseif args.patrol then
return data"patrol"
elseif args.last then
return formatTimeByFormat(data"last", args.timeFormat)
elseif args.total then
return data"total"
end
return renderPatrollerTable(data, args.show_name, args.show_total)
elseif _c_tprank_type == _c_tp"sysop" then
local data = sysopProcessing(us, rank_type)
if args.delete then
return data"delete"
elseif args.restore then
return data"restore"
elseif args.revdel then
return data"revdel"
elseif args.protect then
return data"protect"
elseif args.unprotect then
return data"unprotect"
elseif args.modifyprotect then
return data"modifyprotect"
elseif args.block then
return data"block"
elseif args.unblock then
return data"unblock"
elseif args.reblock then
return data"reblock"
elseif args.rename then
return data"rename"
elseif args.rights then
return data"rights"
elseif args.last then
return formatTimeByFormat(data"last", args.timeFormat)
elseif args.total then
return data"total"
end
return renderSysopTable(data, args.show_name, args.show_total)
else
error("Không thể xác định định dạng \"".. rank_type .."\". Định dạng hợp lệ có hỗ trợ là: user, patroller, sysop.")
end
end
return p