跳转到内容

模組:RFX report

维基百科,自由的百科全书

-- This module is a replacement for the RfX report bot.

local rfx = require( 'Module:Rfx' )

local p = {}

local function getRfxes()
    -- Get the title object for [[Wikipedia:Requests for adminship]].
    local noError, rfa = pcall( mw.title.new, 'Wikipedia:申请成为管理人员/申请区' )
    if not noError or ( noError and not rfa ) then
        return nil
    end
    local rfaText = rfa:getContent()
    if not rfaText then
        return nil
    end
    
    -- Return a table with a list of pages transcluded from
    -- [[Wikipedia:Requests for adminship]], minus the exceptions
    -- which are always transcluded there.
    local t = {}
    local exceptions = { 'header' }
    for rfxPage, rfxSubpage in mw.ustring.gmatch( rfaText, '{{[ _]*([wW維维][^:]*[aP科]:申[请請]成[为為][^/]-/([^{}]-))[ _]*}}' ) do
        local isException = false
        for _, v in ipairs( exceptions ) do
            if rfxSubpage == v then
                isException = true
                break
            end
        end
        if not isException then
            table.insert( t, rfxPage )
        end
    end
    return t
end

local function makeRow( rfxObject )
    if not ( type( rfxObject ) == 'table' and rfxObject.getTitleObject and rfxObject.getSupportUsers ) then
        return nil
    end
    local style = ''
    local status = rfxObject:getStatus()
    if status == '已结束' then
        style = ' style="background: var(--background-color-destructive-subtle--hover,#ffdad3); color: inherit;" |'
    end
    local page = rfxObject:getTitleObject().prefixedText
    local user = rfxObject.user or mw.getCurrentFrame():callParserFunction('#titleparts', {rfxObject:getTitleObject().prefixedText, 1, 2})
    local securePollNotStart = false
    -- XXX: 應對安全投票未設置VoteState時獲取的終止時間錯誤
    if status == '尚未開始' and rfxObject:isSecurePoll() then
    	status = '\n| colspan="3" | 投票尚未開始'
    	securePollNotStart = true
    elseif status then
        status = mw.ustring.format( '\n| %s %s', style, status )
    elseif rfxObject:isSecurePoll() then
        status = '\n| style="background: var(--background-color-warning-subtle,#fdf2d5); color: inherit;" | 安全投票無法-{zh-cn:获取;zh-tw:取得}-狀態'
    else
        status = '\n| style="background: var(--background-color-destructive-subtle--hover,#ffdad3); color: inherit;" | 未能-{zh-cn:获取;zh-tw:取得}-狀態'
    end 
    local endTime = mw.language.getContentLanguage():formatDate('Y年n月j日 (D) H:i (T)', rfxObject.endTime)
    local timeLeft = rfxObject:getTimeLeft()
    local time
    if securePollNotStart then
    	time = ''
    elseif endTime and timeLeft then
        time = mw.ustring.format( '\n| %s %s\n| %s %s', style, endTime, style, timeLeft )
    else
        time = '\n| colspan="2" style="background: var(--background-color-destructive-subtle--hover,#ffdad3); color: inherit;" | 未讀出終止時間'
	end
    local report = rfxObject:getReport()
    if report then
    	report = mw.ustring.format( '\n|%s [%s 验票]', style, tostring( report ) )
    elseif rfxObject:isSecurePoll() then
        report = '\n| style="background: var(--background-color-content-added,#a3d3ff); color: inherit;" | 安全投票'
    else
		report = '\n| style="background: var(--background-color-destructive-subtle--hover,#ffdad3); color: inherit;" | 找不到工具'
    end
    
    -- 第 x 次
    local attempt = rfxObject.attempt
    if attempt ~= '1' then
    	user = user .. '<sup>' .. attempt .. '</sup>'
	end
    
    return mw.ustring.format(
        '\n|-\n|%s [[%s|%s]]%s%s %s',
        style, page, user, status, time, report
    )
end

local function makeHeading( rfxType )
    local rfxCaps
    if rfxType == 'rfa' then
        rfxCaps = '管理员'
    elseif rfxType == 'rfb' then
        rfxCaps = '行政员'
    elseif rfxType == 'rfcu' then
        rfxCaps = '用户查核员'
    elseif rfxType == 'rfo' then
        rfxCaps = '监督员'
    elseif rfxType == 'rfia' then
        rfxCaps = '-{zh:界面;zh-hans:界面;zh-hant:介面}-管理员'
    else
        return nil
    end
    return mw.ustring.format(
        '\n|-\n! %s候選人 !! 狀態 !! 完結時間 !! 剩餘時間 !! 驗票',
        rfxCaps
    )
end

local function makeReportRows()
    local rfxes = getRfxes()
    if not rfxes then
        return nil
    end
    -- Get RfX objects and separate RfAs, RfBs, RfCUs, RfOs and RfIAs.
    local rfas, rfbs, rfcus, rfos, rfias = {}, {}, {}, {}, {}
    for i, rfxPage in ipairs( rfxes ) do
        local rfxObject = rfx.new( rfxPage )
        if rfxObject then
            if rfxObject.type == 'rfa' then
                table.insert( rfas, rfxObject )
            elseif rfxObject.type == 'rfb' then
                table.insert( rfbs, rfxObject )
            elseif rfxObject.type == 'rfcu' then
            	table.insert( rfcus, rfxObject )
            elseif rfxObject.type == 'rfo' then
            	table.insert( rfos, rfxObject )
            elseif rfxObject.type == 'rfia' then
            	table.insert( rfias, rfxObject )
            end
        end
    end
    local ret = {}
    if #rfas > 0 then
        table.insert( ret, makeHeading( 'rfa' ) )
        for i, rfaObject in ipairs( rfas ) do
            table.insert( ret, makeRow( rfaObject ) )
        end
    end
    if #rfbs > 0 then
        table.insert( ret, makeHeading( 'rfb' ) )
        for i, rfbObject in ipairs( rfbs ) do
            table.insert( ret, makeRow( rfbObject ) )
        end
    end
    if #rfcus > 0 then
        table.insert( ret, makeHeading( 'rfcu' ) )
        for i, rfcuObject in ipairs( rfcus ) do
            table.insert( ret, makeRow( rfcuObject ) )
        end
    end
    if #rfos > 0 then
        table.insert( ret, makeHeading( 'rfo' ) )
        for i, rfoObject in ipairs( rfos ) do
            table.insert( ret, makeRow( rfoObject ) )
        end
    end
    if #rfias > 0 then
        table.insert( ret, makeHeading( 'rfia' ) )
        for i, rfiaObject in ipairs( rfias ) do
            table.insert( ret, makeRow( rfiaObject ) )
        end
    end
    return table.concat( ret )
end

local function makeReport( args )
    local purgeLink = mw.title.getCurrentTitle():fullUrl( 'action=purge' )
    local header = mw.ustring.format(
        '\n|-\n! colspan="9" style="text-align: center;" | 進行中的[[Wikipedia:申请成为管理人员|管理人员申請]]<span class="plainlinks" style="float: right;"><small>[%s 刷新]</small></span>',
        purgeLink
    )
    local rows = makeReportRows() or ''
    if rows == '' then
        rows = '\n|-\n| colspan="10" | 当前没有提名。请参阅[[Wikipedia:管理人員任免記錄|最近的管理人员任免记录]]。'
    end
    local style = args.style
    if not style then
        local float = args.float or args.align or 'right'
        local clear = args.clear or 'left'
        style = mw.ustring.format(
            'style="white-space:wrap; clear: %s; margin-top: 0em; margin-bottom: .5em; float: %s; padding: .5em 0em 0em 1.4em; background: var(--background-color-base,#ffffff); color: inherit; border-collapse: collapse; border-spacing: 0;"',
            clear, float
        )
    end
    return mw.ustring.format( '\n{| class="wikitable" %s%s%s\n|-\n|}', style, header, rows )
end

local function countVotes( args )
	local title = args.title or mw.title.getCurrentTitle().prefixedText
	local split = args.split or '/'
	local rfxObject = rfx.new(title)
	if not rfxObject then
		return '<span class="error">投票-{zh-cn:解析;zh-tw:剖析}-失败[[Category:投票計算失效的頁面|未]]</span>'
	end
    if rfxObject:isSecurePoll() then
        return '<span class="error">安全投票無法-{zh-cn:解析;zh-tw:剖析}-[[Category:投票計算失效的頁面|安]]</span>'
    end
	local s, o, n = rfxObject.supports, rfxObject.opposes, rfxObject.neutrals
	if s and o and n then
		return string.format('[[%s#支持|%d]]%s[[%s#反對|%d]]%s[[%s#中立|%d]]',
			title, s, split, title, o, split, title, n)
	else
		return '<span class="error">投票-{zh-cn:解析;zh-tw:剖析}-失败[[Category:投票計算失效的頁面|錯]]</span>'
	end
end

local function countVotes2( args )
	local title = args.title or mw.title.getCurrentTitle().prefixedText
	local split = args.split or '/'
	local rfxObject = rfx.new(title)
	if not rfxObject then
		return '<span class="error">投票-{zh-cn:解析;zh-tw:剖析}-失败[[Category:投票計算失效的頁面|未]]</span>'
	end
    if rfxObject:isSecurePoll() then
        return '<span class="error">安全投票無法-{zh-cn:解析;zh-tw:剖析}-[[Category:投票計算失效的頁面|安]]</span>'
    end
	local s, o, n = rfxObject.supports, rfxObject.opposes, rfxObject.neutrals
	if s and o and n then
		return string.format('%d%s%d%s%d',
			s, split, o, split, n)
	else
		return '<span class="error">投票-{zh-cn:解析;zh-tw:剖析}-失败[[Category:投票計算失效的頁面|錯]]</span>'
	end
end

function p.count( frame )
    -- Process the arguments.
    local args
    if frame == mw.getCurrentFrame() then
        args = frame:getParent().args
        if next(frame.args) ~= nil then
            args = frame.args
        end
    else
        args = frame
    end
    return countVotes( args )
end

function p.count2( frame )
    -- Process the arguments.
    local args
    if frame == mw.getCurrentFrame() then
        args = frame:getParent().args
        if next(frame.args) ~= nil then
            args = frame.args
        end
    else
        args = frame
    end
    return countVotes2( args )
end

function p.countCandidate( frame )
    -- 无需参数,一次高消耗
    local rfxes = getRfxes()
    if not rfxes then
        return 0
    end
    return #rfxes
end

function p.main( frame )
    -- Process the arguments.
    local args
    if frame == mw.getCurrentFrame() then
        args = frame:getParent().args
        if next(frame.args) ~= nil then
            args = frame.args
        end
    else
        args = frame
    end
    return makeReport( args )
end

return p