Module:RFX report

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

local rfx = require( 'Module:Rfx' )
local colours = mw.loadData( 'Module:RFX report/colour' )

local p = {}

local function getTableLength(tbl)
	local length = 0
	for _ in pairs(tbl) do
		length = length + 1
	end
	return length
end

local function getRfxes()
    -- Get the title object for [[Wikipedia:Requests for adminship]].
    local noError, rfa = pcall( mw.title.new, 'Wikipedia:Requests for adminship' )
    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 = { 'Front matter', 'Header', 'bureaucratship' }
    for rfxPage, rfxSubpage in mw.ustring.gmatch( rfaText, '{{[ _]*([wW]ikipedia:[rR]equests for %w+/([^{}]-))[ _]*}}' ) do
        local isException = false
        for _, v in ipairs( exceptions ) do
            if rfxSubpage == v then
                isException = true
            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 status = rfxObject:getStatus()
    local page = rfxObject:getTitleObject().prefixedText
    local user = rfxObject.user or rfxObject:getTitleObject().subpageText
    local supports = rfxObject.supports
    local opposes = rfxObject.opposes
    local neutrals = rfxObject.neutrals
    local percent = rfxObject.percent
    local colour
    if percent then
        colour = colours[ rfxObject.type ][ percent ]
    end
    colour = colour or ''

    local percentStr = mw.ustring.format( '%d', percent )
    if percent == 0 and supports == 0 and opposes == 0 and neutrals == 0 then
        percentStr = 'N/A'
    elseif percent == 100 and opposes ~= 0 then
    	percentStr = '>99'
    end

    local votes
    if supports and opposes and neutrals and percent then
        votes = mw.ustring.format( [==[
        
| class="rfx-report-number" | [[%s#Support|%d]]
| class="rfx-report-number" | [[%s#Oppose|%d]]
| class="rfx-report-number" | [[%s#Neutral|%d]]
| class="rfx-report-number rfx-report-percent" style="background: #%s; color: #202122" | %s]==],
            page, supports,
            page, opposes,
            page, neutrals,
            colour, percentStr
        )
    else
        votes = '\n| colspan="4" class="rfx-report-error" | Error parsing votes'
    end
    if status then
        status = mw.language.getContentLanguage():ucfirst( status )
        if status == 'Pending closure' then
            status = 'Pending closure...'
        end
        status = '\n|' .. status
    else
        status = '\n| class="rfx-report-error" | Error getting status'
    end 
    local endTime = rfxObject.endTime
    local secondsLeft = rfxObject:getSecondsLeft()
    local timeLeft = rfxObject:getTimeLeft()
    local time
    if endTime and timeLeft then
        time = mw.ustring.format( '\n| %s\n| %s', endTime, timeLeft )
    else
        time = '\n| colspan="2" class="rfx-report-error" | Error parsing end time'
    end
    local dupes = rfxObject:dupesExist()
    if dupes then
        dupes = '<span class="rfx-report-dupes-yes">yes</span>'
    elseif dupes == false then
        dupes = 'no'
    else
        dupes = '--'
    end
    local report = rfxObject:getReport()
    if report then
        report = mw.ustring.format( '\n| [%s report]', tostring( report ) )
    else
        report = '\n| class="rfx-report-error" | Report not found'
    end
    local pending_class = ''
    if status == 'pending closure' then
        pending_class = 'class="rfx-report-pending"'
    end
    return mw.ustring.format(
        '\n|-%s\n| [[%s|%s]]%s%s%s\n| class="rfx-report-dupes" | %s%s',
        pending_class, page, user, votes, status, time, dupes, report
    )
end

local function makeHeading( rfxType )
	local frame = mw.getCurrentFrame()
    local rfxCaps
    if rfxType == 'rfa' then
        rfxCaps = 'RfA'
    elseif rfxType == 'rfb' then
        rfxCaps = 'RfB'
    elseif rfxType == 'rrfa' then
    	rfxCaps = 'RRfA'
    else
        return nil
    end
    return mw.ustring.format(
        '\n|-\n! scope="col" | %s candidate !! scope="col" | <abbr title="Support">S</abbr> !! scope="col" | <abbr title="Oppose">O</abbr> !! scope="col" | <abbr title="Neutral">N</abbr> !! scope="col" | <abbr title="Support percentage (%%)">S %%</abbr> !! scope="col" | Status !! scope="col" | Ending (UTC) !! scope="col" | Time left !! scope="col" | <span title="Has duplicate votes?" style="text-decoration:dotted underline">Dups?</span> !! scope="col" | Report',
        rfxCaps
    )
end

local function getRfasRfbsSeparate()
	local rfxes = getRfxes()
    if not rfxes then
        return nil
    end
    -- Get RfX objects and separate RfAs and RfBs.
    local rfas = {}
    local rfbs = {}
    local rrfas = {}
    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 == 'rrfa' then
            	table.insert( rrfas, rfxObject)
            end
        end
    end
    
    return rfas, rfbs, rrfas
end

local function makeReportRows()
	local rfas, rfbs, rrfas = getRfasRfbsSeparate()

    local ret = {}
    if #rfas + #rrfas > 0 then
        table.insert( ret, makeHeading( 'rfa' ) )
        for i, rfaObject in ipairs( rfas ) do
            table.insert( ret, makeRow( rfaObject ) )
        end	        
        for i, rrfaObject in ipairs( rrfas ) do
            table.insert( ret, makeRow( rrfaObject ) )
        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
    return table.concat( ret )
end

local function makeReport( args )
    local purgeLink = mw.title.getCurrentTitle():fullUrl( 'action=purge' )
    local header = mw.ustring.format(
        '\n|+ Requests for [[Wikipedia:Requests for adminship|adminship]] and [[Wikipedia:Requests for bureaucratship|bureaucratship]] <span class="rfx-report-purge plainlinks">[%s update]</span>',
        purgeLink
    )
    local rows = makeReportRows() or ''
    if rows == '' then
        rows = '\n|-\n| colspan="10" | No current discussions. <span class="rfx-report-recent">[[WP:Requests for adminship by year|Recent RfAs]], recent RfBs: ([[Wikipedia:Successful bureaucratship candidacies|successful]], [[Wikipedia:Unsuccessful bureaucratship candidacies|unsuccessful]])</span>'
    end
    
    local float = args.float or args.align
    if not float or mw.text.trim(float) == '' then
    	float = nil
    end
    local clear = args.clear
    if not clear or mw.text.trim(clear) == '' then
    	clear = nil
    end
    
    local style = ''
    if float or clear then
    	style = string.format(
    		'style="%s%s"',
    		clear and ('clear: ' .. clear .. ';') or '',
    		float and ('float: ' .. float .. ';') or ''
    	)
    end

    return mw.getCurrentFrame():extensionTag{
		name = 'templatestyles', args = { src = 'Module:RFX report/styles.css' }
	} .. mw.ustring.format(
    	'\n{| class="wikitable rfx-report" %s%s%s\n|-\n|}',
    	style,
    	header,
    	rows
    )
end

function p.countRfas()
	local rfas, rfbs, rrfas = getRfasRfbsSeparate()
	return getTableLength(rfas)
end

function p.main( frame )
    -- Process the arguments.
    local args
    if frame == mw.getCurrentFrame() then
        args = frame:getParent().args
        for k, v in pairs( frame.args ) do
            args = frame.args
            break
        end
    else
        args = frame
    end    
    return makeReport( args )
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.