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 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 -- 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, '' ) 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( [==[           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 = ' yes ' 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\n| class="rfx-report-dupes" | %s%s',        pending_class, page, user, votes, status, time, dupes, report    ) end
 * class="rfx-report-number" | %d
 * class="rfx-report-number" | %d
 * class="rfx-report-number" | %d
 * class="rfx-report-number rfx-report-percent" style="background: #%s; color: #202122" | %s]==],

local function makeHeading( rfxType ) local frame = mw.getCurrentFrame local rfxCaps if rfxType == 'rfa' then rfxCaps = 'RfA' elseif rfxType == 'rfb' then rfxCaps = 'RfB' else return nil end return mw.ustring.format(       '\n|-\n! scope="col" | %s candidate !! scope="col" | S !! scope="col" | O !! scope="col" | N !! scope="col" | S %% !! scope="col" | Status !! scope="col" | Ending (UTC) !! scope="col" | Time left !! scope="col" | Dups? !! 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 = {} 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 ) end end end return rfas, rfbs end

local function makeReportRows local rfas, rfbs = getRfasRfbsSeparate

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 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 adminship and bureaucratship [%s update] ',        purgeLink    ) local rows = makeReportRows or '' if rows == '' then rows = '\n|-\n| colspan="10" | No current discussions. Recent RfAs, recent RfBs: (successful, unsuccessful) ' 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 = 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