Module:RFX report: Difference between revisions

Content deleted Content added
this should work
rewrite all the code - copied from Module:User:Mr. Stradivarius/sandbox
Line 1:
-- This module is a replacement for the RfX report bot.
--[==[
Bugs:
 
local colours = mw.loadData('Module:User:Mr. Stradivarius/sandbox/colour')
* Add a purge link?
** Or have the bot purge the page every so often, heh.
* Only output bureaucrat header as needed.
* Only output table as needed....
* Extract color logic from {{bureaucrat candidate}}?
 
local deepToString = require( 'Module:User:Anomie/deepToString' ) -- for debugging
----
|{{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|[[Wikipedia:Requests for {{#ifeq:{{{rfa}}}|yes|adminship|bureaucratship}}/{{{candidate}}}{{#if:{{{run|}}}|_{{{run}}}}}|{{{candidate}}}]]
|align="right" {{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|[[Wikipedia:Requests for {{#ifeq:{{{rfa}}}|yes|adminship|bureaucratship}}/{{{candidate}}}{{#if:{{{run|}}}|_{{{run}}}}}#Support|{{{support}}}]]
|align="right" {{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|[[Wikipedia:Requests for {{#ifeq:{{{rfa}}}|yes|adminship|bureaucratship}}/{{{candidate}}}{{#if:{{{run|}}}|_{{{run}}}}}#Oppose|{{{oppose}}}]]
|align="right" {{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|[[Wikipedia:Requests for {{#ifeq:{{{rfa}}}|yes|adminship|bureaucratship}}/{{{candidate}}}{{#if:{{{run|}}}|_{{{run}}}}}#Neutral|{{{neutral}}}]]
|align="right" bgcolor="{{Template:Bureaucrat candidate/expr{{#if:{{{crat|}}}|2}}|{{#ifeq:{{{support|}}}{{{oppose|}}}|0||{{#if:{{{support|}}}{{{oppose|}}}|{{#expr: ({{{support}}} / ({{{support}}} + {{{oppose}}}) ) * 100 round 0 }}}}}}}}" |{{#ifeq:{{{support|}}}{{{oppose|}}}|0||{{#if:{{{support|}}}{{{oppose|}}}|{{#expr: ({{{support}}} / ({{{support}}} + {{{oppose}}}) ) * 100 round 0 }}}}}}
|{{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|{{{end date}}}
|{{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|{{{time left}}}
|{{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|<center>{{{dups}}}</center>
|{{#ifeq:{{{expired}}}|yes|style="background:#F8CDC6"}}|[http://toolserver.org/~tparis/rfa/?p=Wikipedia:Requests_for_{{#ifeq:{{{rfa}}}|yes|adminship|bureaucratship}}/{{urlencode:{{{candidate}}}}} report]
----
]==]
 
local p = {}
local r = {
rfa = {},
rfb = {}
}
 
local function p.retrieve_open_requestsgetLongRfxName( frame rfxType)
if rfxType == 'rfa' then
local pg = mw.title.new( "Wikipedia:Requests for adminship" )
return 'adminship'
local text = pg:getContent()
elseif rfxType == 'rfb' then
return 'bureaucratship'
else
error('invalid rfx code detected - must be either "rfa" or "rfb"', 2)
end
end
 
local function matchRfx(text, rfxType)
return mw.ustring.gmatch( text, '{{[wW]ikipedia:[rR]equests for ' .. getLongRfxName(rfxType) .. '/([^{}]-)}}' )
end
 
local function addRfxToTable(text, rfxType, exceptions)
for rfxPage in matchRfx(text, rfxType) do
local isException = false
if exceptions then
for _, v in ipairs(exceptions) do
if rfxPage == v then
isException = true
end
end
end
if not isException then
table.insert( r[rfxType], { page = 'Wikipedia:Requests for ' .. getLongRfxName(rfxType) .. '/' .. rfxPage } )
end
end
end
 
local function getRfxPages()
local title = mw.title.new( 'Wikipedia:Requests for adminship' )
local text = title:getContent()
addRfxToTable( text, 'rfa', {'Front matter', 'bureaucratship'} )
addRfxToTable( text, 'rfb' )
end
 
local function getRfxSections(page)
local pageObject = mw.title.new(page)
if not pageObject then
error(tostring(page) .. ' is an invalid title', 2)
end
local pageText = pageObject:getContent()
if not pageText then
error('could not get page content from page ' .. pageObject.title, 2)
end
local intro, s, o, n = mw.ustring.match(
pageText,
'^(.-)\n====%s*[nN]omination%s*====.-'
.. '\n=====%s*[sS]upport%s*=====(.-)'
.. '\n=====%s*[oO]ppose%s*=====(.-)'
.. '\n=====%s*[nN]eutral%s*=====(.-)$'
 
)
return intro, s, o, n
end
 
-- Returns a table of usernames that voted in a particular section.
local function getVoteTable(section)
section = mw.ustring.match(section, '^(.-\n#.-)\n[^#]') or section -- Discard subsequent numbered lists.
local t = {}
for vote in mw.ustring.gmatch(section, '\n#[^#*;:][^\n]*') do
local k = 0
local username = false
for x in string.gmatch( text, "\{\{(Wikipedia:Requests for adminship/.-)\}\}") do
for link in mw.ustring.gmatch(vote, '%[%[([^%[%]]-)%]%]') do
if not(mw.title.equals( x, "Wikipedia:Requests for adminship/Front matter") or mw.title.equals(x, "Wikipedia:Requests for adminship/bureaucratship")) then
t[k]-- =If xthere is a pipe, get the text before it.
kif =mw.ustring.match(link, k'|') +1then
link = mw.ustring.match(link, '^(.-)|')
end
-- If there is a slash, get the text before that.
if mw.ustring.match(link, '/') then
link = mw.ustring.match(link, '^(.-)/')
end
-- Decode html entities and percent encodings.
link = mw.text.decode(link, true)
link = mw.uri.decode(link, 'WIKI')
-- If there is a hash, get the text before that.
if mw.ustring.match(link, '#') then
link = mw.ustring.match(link, '^(.-)#')
end
local userLink = mw.ustring.match(link, '^[%s_]*[uU][sS][eE][rR][%s_]*:[%s_]*(.-)[%s_]*$')
local userTalkLink = mw.ustring.match(link, '^[%s_]*[uU][sS][eE][rR][%s_]*[tT][aA][lL][kK][%s_]*:[%s_]*(.-)[%s_]*$')
if userLink then
username = userLink
elseif userTalkLink then
username = userTalkLink
end
end
if not username then
username = mw.ustring.format( 'Error processing vote no. %d. (Random number: %.8f.)', #d, math.random() )
end
table.insert(t, username)
end
return t
end
 
local function pcheckDups(...thingy( s, o, n )
local st = s{}
local otables = o{...}
for i, v in ipairs(tables) do
local n = n
for j, name in ipairs(v) do
local f = "{{Bureaucrat candidate|candidate= MZMcBride|support= %d|oppose= %d|neutral= %d|end date= 03:20, 9 May 2013 |time left=5 days, 22 hours|dups= no|rfa=yes}}"
if t[name] then
return string.format( f, s, o, n )
return true
else
t[name] = true
end
end
end
return false
end
 
local function p.parsegetEndTime( frame intro)
local ret = mw.ustring.match(intro, "Scheduled to end (%d%d:%d%d, %d+ %w+ %d+) %(UTC%)'''")
local pframe = frame:getParent()
return ret
local config = frame.args -- the arguments passed BY the template, in the wikitext of the template itself
end
local args = pframe.args -- the arguments passed TO the template, in the wikitext that transcludes the template
 
-- Page is a string of the page name
local page =function frame.pagegetUser(intro)
local ret = mw.ustring.match(intro, '===%s*%[%[%s*[wW]ikipedia%s*:%s*[rR]equests for %w+/.-|%s*(.-)%s*%]%]%s*===')
local page_object = mw.title.new( "Wikipedia:Requests for adminship/MZMcBride" ) -- idk
return ret
local text = page_object:getContent()
end
--[==[
 
page_text = page.read()
local function getTimeLeft(endTime)
support_find = re.search(r'(=|\'\'\')[ ]*Support[ ]*(=|\'\'\')+\n(.*)(=|\'\'\')[ ]*Oppose[ ]*(=|\'\'\')+\n', page_text, re.I|re.U|re.DOTALL)
local lang = mw.getContentLanguage()
oppose_find = re.search(r'(=|\'\'\')[ ]*Oppose[ ]*(=|\'\'\')+\n(.*)(=|\'\'\')[ ]*Neutral[ ]*(=|\'\'\')+\n', page_text, re.I|re.U|re.DOTALL)
local now = tonumber( lang:formatDate("U") )
neutral_find = re.search(r'(=|\'\'\')[ ]*Neutral[ ]*(=|\'\'\')+\n(.*)', page_text, re.I|re.U|re.DOTALL)
endTime = tonumber( lang:formatDate("U", endTime) )
votes_find = re.compile(r'^#[^:*\n]', re.I|re.U|re.M)
local secondsLeft = endTime - now
supports = len(votes_find.findall(support_find.group(3)))
local daysLeft
opposes = len(votes_find.findall(oppose_find.group(3)))
if secondsLeft <= 0 then
neutrals = len(votes_find.findall(neutral_find.group(3)))
daysLeft = 'expired'
percent = float(supports)/(supports+opposes)*100
else
]==]
daysLeft = mw.ustring.gsub( lang:formatDuration(secondsLeft, {'days', 'hours'}), ' and', ',')
local s_pattern = "'''Support'''"
local o_pattern = "'''Oppose'''"
local n_pattern = "'''Neutral'''"
local s, o, n = 0, 0, 0
for match in mw.ustring.gmatch( text, s_pattern ) do
s = s + 1
end
return daysLeft
for match in mw.ustring.gmatch( text, o_pattern ) do
end
o = o + 1
 
local function makeRfxTables(rfxType)
for i, rfx in ipairs(r[rfxType]) do
local intro, s, o, n = getRfxSections(rfx.page)
s = getVoteTable(s)
o = getVoteTable(o)
n = getVoteTable(n)
r[rfxType][i].user = getUser(intro)
r[rfxType][i].support = #s
r[rfxType][i].oppose = #o
r[rfxType][i].neutral = #n
r[rfxType][i].percent = math.floor( (r[rfxType][i].support / (r[rfxType][i].support + r[rfxType][i].oppose) * 100) + 0.5 )
r[rfxType][i].dups = checkDups(s, o, n)
r[rfxType][i].endTime = getEndTime(intro)
r[rfxType][i].timeLeft = getTimeLeft( r[rfxType][i].endTime )
r[rfxType][i].report = '[//tools.wmflabs.org/xtools/rfa/?p=' .. mw.uri.encode( r[rfxType][i].page ) .. ' report]'
end
for match in mw.ustring.gmatch( text, n_pattern ) do
n = n + 1
end
--return s, o, n
return p.thingy(s, o, n)
end
 
local function p.printmakeReportRows( frame rfxType)
reportret = [===[''
for i, rfx in ipairs(r[rfxType]) do
{| align="right" cellspacing="0" cellpadding="0" style="white-space:wrap; clear: left; margin-top: 0em; margin-bottom: .5em; float: right;padding: .5em 0em 0em 1.4em; background: none;"
local dups
|
if r[rfxType][i].dups then
{| class="wikitable"
dups = "'''yes'''"
! RfA candidate
else
! <abbr title="Supports">S</abbr>
dups = 'no'
! <abbr title="Opposes">O</abbr>
end
! <abbr title="Neutrals">N</abbr>
local style = ''
! <abbr title="Percent supporting">S%</abbr>
if r[rfxType][i].timeLeft == 'expired' then
! Ending ([[Coordinated Universal Time|UTC]])
style = ' style="background:#f8cdc6;"'
! Time remaining
end
! Report
local page = r[rfxType][i].page
local colour = colours[rfxType][ r[rfxType][i].percent ]
ret = ret .. mw.ustring.format( [==[
 
|-
|%s | [[%s|%s]]
| [[Wikipedia:Requests for adminship/Example|Example]]
| align="right"%s | [[Wikipedia:Requests for adminship/Example%s#Support|10%d]]
| align="right"%s | [[Wikipedia:Requests for adminship/Example%s#Oppose|10%d]]
| align="right"%s | [[Wikipedia:Requests for adminship/Example%s#Neutral|10%d]]
| align="right" bgcolorstyle="b1ffbbbackground:#%s;" | 50%d
|%s | %s
| 03:20, 9 May 2013
|%s | %s
| 6 days, 1 hours
|%s | <center>%s</center>
| [http://toolserver.org/~tparis/rfa/?p=Wikipedia:Requests_for_adminship/Example report]
|%s | %s]==],
|-
style, page, r[rfxType][i].user,
| [[Wikipedia:Requests for adminship/Example|Example]]
style, page, r[rfxType][i].support,
| align="right" | [[Wikipedia:Requests for adminship/Example#Support|0]]
style, page, r[rfxType][i].oppose,
| align="right" | [[Wikipedia:Requests for adminship/Example#Oppose|0]]
style, page, r[rfxType][i].neutral,
| align="right" | [[Wikipedia:Requests for adminship/Example#Neutral|0]]
colour, r[rfxType][i].percent,
| align="right" bgcolor="b4ffbb" | 0
style, r[rfxType][i].endTime,
| 23:41, 7 May 2013
style, r[rfxType][i].timeLeft,
| 4 days, 22 hours
style, dups,
| [http://toolserver.org/~tparis/rfa/?p=Wikipedia:Requests_for_adminship/Example report]
style, r[rfxType][i].report
|}
)
|}
end
]===]
return reportret
end
 
local function makeReport(args)
getRfxPages()
makeRfxTables('rfa')
makeRfxTables('rfb')
local align = args.align or 'right'
local clear = args.clear or 'left'
local ret = '{| class="wikitable" '
if args.style then
ret = ret .. args.style
else
ret = ret .. 'align="' .. align .. '" cellspacing="0" cellpadding="0" style="white-space:wrap; clear: ' .. clear .. '; '
.. 'margin-top: 0em; margin-bottom: .5em; float: ' .. align .. ';padding: .5em 0em 0em 1.4em; background: none;"'
end
if #r.rfa > 0 then
ret = ret .. '\n|-\n! RfA candidate !! S !! O !! N !! S% !! Ending (UTC) !! Time left !! Dups? !! Report'
ret = ret .. makeReportRows('rfa')
end
if #r.rfb > 0 then
ret = ret .. '\n|-\n! RfB candidate !! S !! O !! N !! S% !! Ending (UTC) !! Time left !! Dups? !! Report'
ret = ret .. makeReportRows('rfb')
end
ret = ret .. '\n|-\n|}'
return ret
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