Module:Speedy Explained

local getArgs = require("Module:Arguments").getArgslocal pageType = require("Module:Pagetype")local mbox = require("Module:Message box")local yesno = require("Module:Yesno")local button = require('Module:Clickable button 2')local preview = require('Module:If preview')local p = local config = mw.loadData('Module:Speedy/config')local timeAgo = require('Module:Time ago')------------------------------------------------------------------------------ message function from ----------------------------------------------------------------------------local fillStringWithArgslocal function message(cfgKey, valArray, expectType) ---- Gets a message from the cfg table and formats it if appropriate. -- The function raises an error if the value from the cfg table is not -- of the type expectType. The default type for expectType is 'string'. -- If the table valArray is present, strings such as $1, $2 etc. in the -- message are substituted with values from the table keys [1], [2] etc. -- For example, if the message "foo-message" had the value 'Foo $2 bar $1.', -- message('foo-message',) would return "Foo qux bar baz." -- local msg = config.messages[cfgKey] expectType = expectType or 'string' if type(msg) ~= expectType then error('message: type error in message cfg.' .. cfgKey .. ' (' .. expectType .. ' expected, got ' .. type(msg) .. ')', 2) end if not valArray then return msg end return fillStringWithArgs(msg, valArray)end

function fillStringWithArgs(text, valArray) if not valArray then return text end

local function getVal(match) match = tonumber(match) return valArray[match] or end

return mw.ustring.gsub(text, '$([1-9][0-9]*)', getVal) .. end

local function detectParameters(text) return text and mw.ustring.find(text, '$([1-9][0-9]*)') and true or falseend

local function makeUnorderedList(array) local ul = mw.html.create('ul') for k,v in pairs(array) do local li = ul:tag('li') li:wikitext(v) li:done end ul:allDone return tostring(ul)end

local function makeWikiList(array) local out = for k,v in pairs(array) do out = out .. '* ' .. v .. '\n' end return outend

------------------------------------------------------------------------------ Argument processing (from)----------------------------------------------------------------------------

local function makeInvokeFunc(funcName) return function (frame) local args = getArgs(frame,) return p[funcName](args) endend

------------------------------------------------------------------------------ Miscellaneous functions related to speedy deletion----------------------------------------------------------------------------

local function getDeletionEntry(code) return config.deletionCodes[code]end

local function yn(input, default) local res = yesno(input, nil) if (res

nil) then return default else return res endend

local function processDeletionArgs(iparams) local args = local entry = nil local replaceParams = false local params = local paramNo = 2 local skipped = true local function cleanupLeftover(v) if entry then table.insert(args.deletionReasons, '

' .. fillStringWithArgs(entry.description, params) .. '. ' .. (entry.more and ' ' .. entry.more .. ' ' or ) .. '' .. message('deleteIntroCriteriaLink',) .. '.') table.insert(args.deletionReasonsNotice, fillStringWithArgs(entry.description, params) .. ' (CSD ' .. entry.code .. '). ' .. (entry.additionalMessage and fillStringWithArgs(entry.additionalMessage, params) or )) table.insert(args.entries, entry) else if (v ~= ) then table.insert(args.deletionReasons, v) table.insert(args.deletionReasonsNotice, v) end table.insert(args.entries,) end params = paramNo = 2 args.customHeader = entry and ((entry.notice or 2) >= args.highestMessage) and entry.customHeader or args.customHeader args.customIntro = entry and ((entry.notice or 2) >= args.highestMessage) and entry.customIntro or args.customIntroDeleted args.customIntroDeleted = entry and ((entry.notice or 2) >= args.highestMessage) and entry.customIntroDeleted or args.customIntroDeleted args.customCloser = entry and ((entry.notice or 2) >= args.highestMessage) and entry.customCloser or args.customCloser args.numberOfEntries = args.numberOfEntries + 1 args.hideButton = entry and (args.hideButton and (entry.notice or 2)

0) or false args.highestMessage = entry and ((entry.notice or 2) >= args.highestMessage) and entry.notice or args.highestMessage args.drv = entry and (args.drv or entry.drv) or args.drv args.willProvide = entry and entry.willProvide or args.willProvide args.hide = entry and (entry.hide or args.hide) or args.hide args.blank = entry and (entry.blank or args.blank) or args.blank end for k,v in ipairs(iparams) do if type(k)

type(1) then skipped = false if (replaceParams) then local pName = fillStringWithArgs(entry and entry.inputFormat[paramNo - 1] or '$2',) paramNo = paramNo + 1 table.insert(params, pName) else entry = getDeletionEntry(v) or nil replaceParams = entry and detectParameters(entry.description) or false end if not replaceParams then cleanupLeftover(v) end end end if replaceParams then cleanupLeftover() end if skipped then args.hideButton = false end args.help = yn(iparams.help, true) args.nocat = yn(iparams.nocat, false) args.bot = yn(iparams.bot, false) args.noHeader = yn(iparams.noheader, false) args.additionalNote = iparams.additionalnote args.pageName = iparams.page args.notice = yn(iparams.notice, false) args.date = iparams.date or mw.getCurrentFrame:preprocess('') return argsend

local isSubstituted = mw.isSubsting;

------------------------------------------------------------------------------ Entry point----------------------------------------------------------------------------

p.main = makeInvokeFunc('_main')function p._main(params) -- get page local args = processDeletionArgs(params) local out = if args.notice then -- we are handling a note for the talk page, not a note for deletion if not args.pageName then return preview._warning end if not args.noHeader then out = out .. (args.customHeader and '

' .. fillStringWithArgs(args.customHeader,) .. '

' or "

" .. message("noticeHeader",) .. "

") .. '\n' end local messageType = args.highestMessage

1 and 'welcome' or 'notice' out = out .. (message('level' .. args.highestMessage .. 'icon')

and or '40px ') if mw.title.new(args.pageName).exists then -- if the page exists then show the "page may be deleted" message. if args.customIntro then out = out .. fillStringWithArgs(args.customIntro,) .. '\n\n' elseif args.numberOfEntries

1 then out = out .. message(messageType .. 'Message',) .. '\n\n' elseif args.numberOfEntries > 1 then out = out .. message(messageType .. 'MessageMultiple',) .. '\n' else out = out .. message(messageType .. 'MessageMultiple',) .. '\n\n' end if args.customCloser then out = out .. args.customCloser else -- this ifexist checks if the page has possibly been deleted or moved -- ifexist is expensive so it may return false from time to time, even if the page exists -- fortunately this is handled in the message by saying "appears" rather than "has been" out = out .. '' end else -- if the page does not exist then show the "page has been deleted" message if args.customIntroDeleted then out = out .. fillStringWithArgs(args.customIntroDeleted,) .. '\n\n' elseif args.numberOfEntries

1 then out = out .. message(messageType .. 'MessageDeleted',) .. '\n\n' elseif args.numberOfEntries > 1 then out = out .. message(messageType .. 'MessageDeletedMultiple',) .. '\n\n' else out = out .. message(messageType .. 'MessageDeletedMultiple',) .. '\n\n' end if args.customCloser then out = out .. args.customCloser else out = out .. message('deletedAfterMessage') if not args.hideButton then out = out .. message('closingWarning',) .. ' ' end if args.willProvide then out = out .. message('undeleteSuggestion',) end end end return mw.getCurrentFrame:preprocess(out) else -- we are handling a deletion template message if isSubstituted then -- if substituted then just prefill parameters -- simpler than the unsubst module because this just autofills the parameters then returns the text needed for the specific deletion template local out = '' return out else local titleOfPage = mw.title.getCurrentTitle local pt = pageType._main local introPrefixToUse = args.bot and 'bot' or 'delete' local mainNotice = mw.html.create('div') mainNotice:wikitext('\n') local intro = mw.html.create('span') intro:css if args.numberOfEntries

1 then intro:wikitext(message(introPrefixToUse .. 'Intro',)) elseif args.numberOfEntries > 1 then intro:wikitext(message(introPrefixToUse .. 'IntroMultiple',)) else intro:wikitext(message(introPrefixToUse .. 'IntroMultiple',)) end intro:allDone mainNotice:wikitext(tostring(intro)) if args.additionalNote then mainNotice:wikitext('\n\n' .. message('additionalNote',)) end if args.hideButton then mainNotice:wikitext('\n\n' .. message("removeNoticeNoButton",)):allDone else mainNotice:wikitext('\n\n' .. message("removeNotice",) ):done local contestButton = mw.html.create('div') contestButton:css if args.numberOfEntries

1 then contestButton:wikitext(button.main):done else contestButton:wikitext(button.main):done end mainNotice:wikitext('\n\n' .. tostring(contestButton)) mainNotice:wikitext('\n\n' .. message("deleteCloser",)):done if (args.help) then local templateCall = '<nowiki>{{subst:db|page=' .. titleOfPage.fullText for k,v in pairs(params) do templateCall = templateCall .. '|' .. k .. '=' .. v end templateCall = templateCall .. '|notice=yes}} ~~' .. '~~</nowiki>' mainNotice:wikitext('\n\n' .. message('deleteNoticeTemplate',)) end local hangOn = mw.html.create('span') if titleOfPage.talkPageTitle.exists then hangOn:addClass('sysop-show') hangOn:wikitext(message("hangOnAdmin",) ):done else hangOn:wikitext(message('hangOn',)):done end mainNotice:wikitext('\n\n' .. tostring(hangOn)) end if args.numberOfEntries

1 then if args.entries[1].notes then mainNotice:wikitext(args.entries[1].notes):done end end local deleteReasonSummary = if args.numberOfEntries > 1 then deleteReasonSummary = 'Multiple criteria: ' local isFirst = true for k,v in pairs(args.entries) do deleteReasonSummary = v.code and deleteReasonSummary .. (isFirst and or ', ') .. '' .. v.code .. '' or isFirst = false end elseif args.numberOfEntries

1 then deleteReasonSummary = args.entries[1].code and deleteReasonSummary .. '' .. args.entries[1].code .. '' or end if deleteReasonSummary

then deleteReasonSummary = 'Speedy' end local adminMessage = mw.html.create('span') adminMessage:addClass('sysop-show') adminMessage:wikitext(message(args.bot and 'checkBot' or 'check', ) ):done mainNotice:wikitext('\n\n' .. tostring(adminMessage)) local lastEditUser = mw.getCurrentFrame:callParserFunction('REVISIONUSER', titleOfPage.fullText) local editDate = mw.getCurrentFrame:callParserFunction('#time', 'H:i, j F Y', mw.getCurrentFrame:callParserFunction('REVISIONTIMESTAMP', titleOfPage.fullText)) mainNotice:wikitext(' ' .. message('lastEdited',)) mainNotice:wikitext('\n') mainNotice:allDone out = out .. tostring(mainNotice) -- categorize out = out .. '' for k,v in pairs(args.entries) do local categorizeTime = mw.getCurrentFrame:preprocess('') local currentTime = mw.getCurrentFrame:preprocess('') if currentTime + 0 >= categorizeTime + 0 then for l,w in pairs(v and v.categories or) do out = out .. '' end end end local deletionBoxArgs = local deletionBox = mbox.main('mbox', deletionBoxArgs) local blankedBox = local hiddenBox = local blanked = local hidden = if args.blank then blanked = blanked .. message('blanked') if mw.getCurrentFrame:preprocess('') + 0 >= 35 then blanked = blanked .. ' ' .. message('pleaseBlank') .. '' end local blankedBoxArgs = blankedBox = mbox.main('mbox', blankedBoxArgs) end if args.hide then hidden = hidden .. message('hidden') local hiddenBoxArgs = hiddenBox = mbox.main('mbox', hiddenBoxArgs) end if args.hide and not args.nocat then hiddenBox = hiddenBox .. '

' end return deletionBox .. blankedBox .. hiddenBox end endend

p.makeTable = makeInvokeFunc('_makeTable')function p._makeTable(args) local usedCodes = local tb = mw.html.create("table") tb:addClass('wikitable') local th = tb:tag('tr') th:tag('th'):wikitext('Code'):done th:tag('th'):wikitext('Aliases'):done th:tag('th'):wikitext('Criterion'):done th:tag('th'):wikitext('Name'):done th:tag('th'):wikitext('Description'):done for k,v in pairs(config.deletionReasonsSorting) do local entry = getDeletionEntry(v) if entry then if not usedCodes[v] then local tr = tb:tag('tr') tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess('<nowiki>' .. v .. '</nowiki>')):done local aliasStr = for _,alias in pairs(entry.aliases) do aliasStr = aliasStr .. '<nowiki>' .. alias .. '</nowiki>' usedCodes[alias] = true end tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess(aliasStr)) tr:tag('td'):wikitext('' .. entry.code .. ''):done tr:tag('td'):wikitext(entry.name):done tr:tag('td'):wikitext(entry.description):done usedCodes[v] = true end end end for k,entry in pairs(config.deletionCodes) do if not usedCodes[k] then local tr = tb:tag('tr') tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess('<nowiki>' .. k .. '</nowiki>')):done local aliasStr = for _,alias in pairs(entry.aliases) do aliasStr = aliasStr .. '<nowiki>' .. alias .. '</nowiki>' usedCodes[alias] = true end tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess(aliasStr)) tr:tag('td'):wikitext('' .. entry.code .. ''):done tr:tag('td'):wikitext(entry.name):done tr:tag('td'):wikitext(entry.description):done usedCodes[k] = true end end return tostring(tb) .. end

p.makeTableWithExamples = makeInvokeFunc('_makeTableWithExamples')function p._makeTableWithExamples(args) local usedCodes = local tb = mw.html.create("table") tb:addClass('wikitable') local th = tb:tag('tr') th:tag('th'):css:wikitext('Codes'):done --th:tag('th'):wikitext('Criterion'):done th:tag('th'):css:wikitext('Deletion message'):done th:tag('th'):css:wikitext('Deletion notice'):done for k,v in pairs(config.deletionReasonsSorting) do local entry = getDeletionEntry(v) if entry then if not usedCodes[v] then local tr = tb:tag('tr') local aliasStr = for _,alias in pairs(entry.aliases) do aliasStr = aliasStr .. '
<nowiki>{{db|' .. alias .. '}}</nowiki>' usedCodes[alias] = true end tr:tag('td'):css:wikitext(mw.getCurrentFrame:preprocess('<nowiki>{{db|' .. v .. '}}</nowiki>' .. aliasStr)):done --tr:tag('td'):wikitext('' .. entry.code .. ''):done tr:tag('td'):wikitext('

' .. mw.getCurrentFrame:preprocess('' .. '

')):done tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess('

' .. '' .. '

')):done usedCodes[v] = true end end end for v,entry in pairs(config.deletionCodes) do if not usedCodes[v] then local tr = tb:tag('tr') local aliasStr = for _,alias in pairs(entry.aliases) do aliasStr = aliasStr .. '
<nowiki>{{db|' .. alias .. '}}</nowiki>' usedCodes[alias] = true end tr:tag('td'):css:wikitext(mw.getCurrentFrame:preprocess('<nowiki>{{db|' .. v .. '}}</nowiki>\n' .. aliasStr)):done --tr:tag('td'):wikitext('' .. entry.code .. ''):done tr:tag('td'):wikitext('

' .. mw.getCurrentFrame:preprocess('' .. '

')):done tr:tag('td'):wikitext(mw.getCurrentFrame:preprocess('

' .. '' .. '

')):done usedCodes[v] = true end end return tostring(tb) .. end

return p