Module:Votings-global/sandbox
Appearance
This is the module sandbox page for Module:Votings-global (diff). |
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
Usage
[edit]
-- For attribution: [[:vi:Module:CurrentCandidateList]]
local p = {}
local perm = {'GRN', 'GP', 'GS', 'GR'}
local title = 'Steward requests/Global permissions' -- Here's our title...
local content = mw.title.new(title):getContent() -- ...and here's our content.
function p.list(frame) -- {{#invoke:Votings-global|list}} will output a pipe-separated list of numbers of requests.
local list = { -- Data.
GR = {
pat = 'roll%s*backe?r?',
num = 0,
boo = false
},
GS = {
pat = 'sysop',
num = 0,
boo = false
},
GRN = {
pat = 'renamer?',
num = 0,
boo = false
},
GP = {
num = 0
}
}
local b = { -- Originally "b" means "boolean". Now it's a table that contains boolean values.
a = false,
b = false,
c = {}
}
-- These statuses mark the requests as no longer active.
local s = {'done', '+', 'cannot', 'notdone', '-', 'alreadydone', 'withdrawn', 'redundant'}
for k, v in pairs(list) do -- Iterate the "list" table.
if k ~= 'GP' then -- "GP" stands for "Other global permissions". The old template used it; I don't know why.
for l in mw.text.gsplit(content, '\n') do -- Iterate lines of SRGP
if p.catch(l, list, k) then -- See p.catch (case 1), then come back here.
list[k].boo = true -- We're going through GR/GS/GRN h3 section(s).
end
if list[k].boo and mw.ustring.match(l, '%s*%|%s*status%s*=%s*.*') and not p.inc(p.status(l), s) then -- See p.inc and p.status.
list[k].num = list[k].num + 1 -- If the line contains status param and its value is not one of "s", add one to total.
list[k].boo = false -- One subsection can only contain one request.
elseif mw.ustring.match(l, '===%s*.+%s*===') and not p.catch(l, list, k) then -- No longer in that subsection.
list[k].boo = false -- Nothing caught, nothing added.
end
end
else
for l in mw.text.gsplit(content, '\n') do -- Iterate lines of SRGP, again.
if mw.ustring.match(l, '==%s*Requests%s*for%s*other%s*global%s*permissions%s*==') ~= nil then -- We're going through the h2 section for other GPs.
b.a = true -- Use a boolean value to remark that.
end
if p.catch(l) ~= nil then -- Case 2 of p.match, which returns <username>[|<username>] and let us know if we're in a subsection.
b.b = true -- Subsection remarked.
b.c = p.ins(b.c, p.getun(p.catch(l))) -- Add the name caught to a table. This doesn't affect anything.
end
if b.a and b.b and mw.ustring.match(l, '%s*%|%s*status%s*=%s*.*') and not p.inc(p.status(l), s) then -- Get status.
list.GP.num = list.GP.num + 1 -- Found one, add it to our stock.
b.b = false -- No longer in subsection.
end
if mw.ustring.match(l, '==%s*.+%s*==<!--%s*.+%s*-->') ~= nil then -- This is meant to catch == See also == section.
b.a = false -- We're out of RfOGP, stop.
end
end
end
end
if frame then -- If a parameter was specified,
if frame.args[1] == 'GR' then -- outputs number of GR requests...
return list.GR.num
elseif frame.args[1] == 'GS' then -- ...GS...
return list.GS.num
elseif frame.args[1] == 'GRN' then -- ...GRN...
return list.GRN.num
elseif frame.args[1] == 'GP' then -- ...and the rest, accordingly.
return list.GP.num
end
else -- Else, returns a pipe-separated list.
local a = {} -- New table
for k, v in pairs(list) do
table.insert(a, list[k].num) -- Add all numbers to the table
end
return table.concat(a, '|')
end
end
function p.main() -- Main function
local num = mw.text.gsplit(p.list(), '|') -- p.list() returns a pipe-separated list (\d+|\d+|\d+|\d+); split it up.
local req = {}
local s = { -- "s" stands for `s`ection.
'Requests for global rename permissions',
'Requests for other global permissions',
'Requests for global sysop permissions',
'Requests for global rollback permissions'
}
local i = { -- Table for numbers.
t = { -- "t" stands for `t`rue.
0
},
f = { -- "f" stands for `f`alse.
0
},
i = 0 -- "i" stands for `i`ndex.
}
for n in num do -- Iterate "num".
i.i = i.i + 1 -- Add 1 to index before going.
if tonumber(n) > 0 then -- Outputs something is number of requests is not 0.
table.insert(req, '[[' .. title .. '#' .. s[i.i] .. '|' .. n .. ' Rf' .. perm[i.i] .. ']]')
table.insert(i.t, i.i) -- This is irrelevant; just ignore it.
else
table.insert(i.f, i.i) -- Idem.
end
end
if #req > 0 then -- If our total is not 0,
return ' • <b>' .. table.concat(req, '</b> • <b>') .. '</b>' -- ...adds requests up.
else
return '' -- No requests atm, return nothing.
end
end
function p.catch(l, list, k) -- This is meant to be a template for two cases: GR/GS/GRN and GP
local j -- Splitting cases
if list ~= nil
then j = 1
else
j = 2
end
if j == 1 then -- If case 1, everything this function needs were provided. Returns a value (which we don't have to care about) or nil.
return mw.ustring.match(l, '===%s*[Gg]lobal%s*' .. list[k].pat .. '%s*for%s*%[%[%s*[Uu][Ss][Ee][Rr]%s*:%s*..-%]%]%s*===')
else -- Returns <username>[|<username>]. Some people writes [[User:Foo]] instead of [[User:Foo|Foo]], hence the function.
return mw.ustring.match(l, '===%s*[^=]-for%s*%[%[%s*[Uu][Ss][Ee][Rr]%s*:%s*(..-)%]%][^=]-%s*===')
end
end
function p.status(str) -- Return value of |status= parameter, or the first word of the hidden comment <!--don't change this line-->.
return mw.ustring.lower(
mw.ustring.gsub(
mw.ustring.match(
mw.ustring.match(str, '%s*%|%s*status%s*=%s*(.*)'),
'([%w ]+)'
) or '',
'%s*',
''
)
)
end
function p.inc(e, a) -- Return a boolean value if "e" is an `e`lement (key/value) of table (`a`rray) "a".
local b = false
for k, v in pairs(a) do
if k == e or v == e then
b = true
end
end
return b
end
function p.split(str, sep) -- Splitting things up. "str" stands for `str`ing and "sep" stands for `sep`arator.
local t = {}
if sep == nil then
sep = '%s*([^|]+)%s*'
end
for str in string.gmatch(str, sep) do
table.insert(t, str)
end
return t
end
function p.getun(un, i) -- Outputs <username> from <username>[|<username>]. Generally this is irrelevant to our final result.
local id
if i ~= nil then
id = i
else
id = 1
end
return p.split(un)[id]:gsub('%s+', ' ')
end
function p.ins(a, e) -- Adds `e`lement "e" to `a`rray "a".
local i = #a
a[i+1] = e
return a
end
return p