Module:Votings-global/sandbox
Appearance
From Meta, a Wikimedia project coordination wiki
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 ]
The above documentation is transcluded from Module:Votings-global/doc. (edit | history)
Editors can experiment in this module’s sandbox (edit | diff) and testcases (create) pages.
Please add categories to the /doc subpage. Subpages of this module.
Editors can experiment in this module’s sandbox (edit | diff) and testcases (create) pages.
Please add categories to the /doc subpage. Subpages of this module.
-- 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