Module:Sanctions/sandbox2

local getArgs = require('Module:Arguments').getArgs

local yesno = require('Module:Yesno')

local rawData = mw.loadData('Module:Sanctions/data')

local data = rawData.sanctions

local aliasMap = rawData.aliases

local messageBox = require('Module:Message box')

local function tableContainsValue(needle, haystack)

for _, v in pairs(haystack) do

if v == needle then

return true

end

end

return false

end

local function _getTopicData(topicAlias)

if data[topicAlias] then

return data[topicAlias]

elseif aliasMap[topicAlias] then

return data[aliasMap[topicAlias]]

else

return false

end

end

-- Returns an invalid topic error, with a table of acceptable topics

local function syntaxHelp()

return [[{{para|topic}} not specified. Available options:

{{Gs/topics/table}}

]]

end

local function getTopicData(frame, topicAlias)

if not topicAlias then

return false

end

local topic = _getTopicData(topicAlias)

if topic then

return topic

else

return false

end

end

-- This function builds a talk notice

-- TODO: split this up

--

-- @param frame

-- @param topicData data for the given topic from the /data page

-- @param args arguments passed to wrapper template

-- @returns String representation of notice

local function buildTalkNotice(frame, topicData, args)

local restrictions = topicData.restrictions

local type = args['type'] or args[2] or 'standard'

local hasRestrictions = false

local hasRevertRestrictions = false

local out = mw.html.create('')

-- Set (and force) a long display if there are applicable restrictions

if restrictions['1rr'] or args['1rr'] or args['consensusrequired'] or args['brd'] then

hasRestrictions = true

hasRevertRestrictions = true

end

if args['restriction1'] then

hasRestrictions = true

end

if hasRestrictions then

out

:tag('span')

:css('font-size', '120%')

:wikitext("WARNING: ACTIVE COMMUNITY SANCTIONS")

end

if hasRestrictions then

out

:tag('p')

:wikitext("The article :{{SUBJECTPAGENAME}}, along with other pages relating to "..topicData.scope..", is currently subject to discretionary sanctions authorised by the community (see: ".. topicData['wikilink'] ..")." .. ((args['1rr'] or args['consensusrequired'] or args['brd'] or args['restriction1']) and ' An administrator has applied the following restrictions to this article:' or ) .. (restrictions['1rr'] and ' The current restrictions are:' or ))

else

out

:tag('p')

:wikitext("The use of discretionary sanctions has been authorised by the community for pages related to ".. topicData['scope'] ..", including this page." .. (type == 'mini' and ' Please consult the awareness criteria and edit carefully.' or ''))

end

if not (type == 'mini') then

local restrictionList = mw.html.create('ul')

-- General notice for revert restrictions

if hasRevertRestrictions then

restrictionList

:tag('li')

:wikitext("Limit of one revert in 24 hours: This article is under WP:1RR (one revert per editor per article per 24-hour period)")

end

-- Text for boilerplate/predefined restrictions

if args['consensusrequired'] then

restrictionList

:tag('li')

:wikitext("Consensus required: All editors must obtain consensus on the talk page of this article before reinstating any edits that have been challenged (via reversion). This includes making edits similar to the ones that have been challenged. If in doubt, do not make the edit.")

end

if args['brd'] then

restrictionList

:tag('li')

:wikitext("24-hr BRD cycle: If a change you make to this article is reverted, you may not reinstate that change unless you discuss the issue on the talk page and wait 24 hours (from the time of the original edit). Partial reverts/reinstatements that reasonably address objections of other editors are preferable to wholesale reverts.")

end

local ri = 1

while true do

if args['restriction'..ri] then

restrictionList

:tag('li')

:wikitext(args['restriction'..ri])

ri = ri + 1

else

break

end

end

if hasRestrictions then

out:node(restrictionList)

end

out

:tag('p')

:wikitext("Provided the awareness criteria are met, discretionary sanctions may be used against editors who repeatedly or seriously fail to adhere to the purpose of Wikipedia, any expected standards of behaviour, or any normal editorial process.")

-- Further info box

if hasRestrictions then

local furtherInfo = mw.html.create('')

-- Enforcement procedures

furtherInfo

:tag('p')

:wikitext('Enforcement procedures:')

:done()

local enforcementProcedures = mw.html.create('ul')

if hasRevertRestrictions or args['restriction1'] then

enforcementProcedures

:tag('li')

:wikitext("Violations of any restrictions " .. (hasRevertRestrictions and "(excluding 1RR/reverting violations) " or "") .. "and other conduct issues should be reported to the administrators' incidents noticeboard." .. (hasRevertRestrictions and " Violations of revert restrictions should be reported to the administrators' edit warring noticeboard." or ""))

:done()

:tag('li')

:wikitext("Editors who violate any listed restrictions may be blocked by any uninvolved administrator, even on a first offense.")

:done()

else

enforcementProcedures

:tag('li')

:wikitext("Problems should be reported to the administrators' incidents noticeboard.")

:done()

end

enforcementProcedures

:tag('li')

:wikitext("An editor must be aware before they can be sanctioned.")

:allDone()

furtherInfo:node(enforcementProcedures)

if hasRevertRestrictions then

furtherInfo

:tag('p')

:wikitext("With respect to any reverting restrictions:")

:done()

:tag('ul')

:tag('li')

:wikitext("Edits made solely to enforce any clearly established consensus are exempt from all edit-warring restrictions. In order to be considered \"clearly established\" the consensus must be proven by prior talk-page discussion.")

:done()

:tag('li')

:wikitext("Edits made which remove or otherwise change any material placed by clearly established consensus, without first obtaining consensus to do so, may be treated in the same manner as clear vandalism.")

:done()

:tag('li')

:wikitext("Clear vandalism of any origin may be reverted without restriction.")

:done()

:tag('li')

:wikitext("Reverts of edits made by anonymous (IP) editors that are not vandalism are exempt from the 1RR but are subject to the usual rules on edit warring. If you are in doubt, contact an administrator for assistance.")

:allDone()

:tag('p')

:wikitext("If you are unsure if your edit is appropriate, discuss it here on this talk page first. Remember: When in doubt, don't revert!")

end

local collapsed = frame:expandTemplate{ title = 'collapse', args = {

tostring(furtherInfo),

'Remedy instructions and exemptions',

['bg'] = '#EEE8AA'

}}

out

:newline()

:node(collapsed)

end

-- End further info box

end

local box = messageBox.main( 'tmbox', {

type = 'notice',

image = type == 'long' and '50px' or '40px',

text = frame:preprocess(tostring(out))

})

return box

end

-- Builds an alert notice

--

-- @param frame

-- @param topicData data for the given topic from the /data page

-- @returns String representation of notice

local function buildAlert(frame, topicData, sig)

local out = mw.html.create('table')

:addClass('messagebox')

:cssText("border: 1px solid #AAA; background: #E5F8FF; padding: 0.5em; width: 100%;")

out

:tag('tr')

:tag('td')

:cssText("vertical-align:middle; padding-left:1px; padding-right:0.5em;")

:wikitext("50px")

:done()

:tag('td')

:wikitext("This is a standard message to notify contributors about an administrative ruling in effect. It does not imply that there are any issues with your contributions to date.")

:newline()

:wikitext("You have shown interest in ".. topicData.scope ..". Due to past disruption in this topic area, the community has enacted a more stringent set of rules. Any administrator may impose sanctions - such as editing restrictions, bans, or blocks - on editors who do not strictly follow Wikipedia's policies, or the page-specific restrictions, when making edits related to the topic.")

:newline()

:wikitext("For additional information, please see the guidance on these sanctions. If you have any questions, or any doubts regarding what edits are appropriate, you are welcome to discuss them with me or any other editor." .. (sig and ' '..sig or ''))

return frame:preprocess(tostring(out))

end

-- Builds an edit notice

local function buildEditNotice(frame, topicData, args)

local restrictions = topicData.restrictions

local enHeader = mw.html.create('')

local restrictionMsgs = {}

if restrictions['1rr'] or args['1rr'] then

table.insert(restrictionMsgs, "Editors must not make more than one revert per twenty-four (24) hours (subject to exceptions)")

end

if args['consensusrequired'] then

table.insert(restrictionMsgs, "Editors must not reinstate any challenged edits (via reversion) without first obtaining consensus on the talk page of this article")

end

local ri = 1

while true do

if args['restriction'..ri] then

table.insert(restrictionMsgs, args['restriction'..ri])

ri = ri + 1

else

break

end

end

if #restrictionMsgs == 0 then

return frame:preprocess(syntaxHelp())

else

local list = mw.html.create('ul')

for _,v in ipairs(restrictionMsgs) do

list

:tag('li')

:wikitext(v)

:done()

end

enHeader:wikitext(tostring(list))

end

local enText = mw.html.create('')

enText

:tag('p')

:wikitext("Breaching the restriction on this page may result in a block or other sanctions. Please note that because this topic area has been disrupted in the past, the community has authorised administrators to take appropriate steps to ensure the smooth running of all pages related to "..topicData.scope..". Conduct which does not adhere to our policies and standards of behaviour may be met with sanctions. Please edit carefully.")

:done()

local editnotice = frame:expandTemplate{ title = 'editnotice', args = {

expiry = "indefinite",

headerstyle = "font-size: 120%;",

style = "background: ivory;",

image = "Commons-emblem-issue.svg",

imagesize = "50px",

header = tostring(enHeader),

text = tostring(enText)

}}

return editnotice

end

--/////////--

-- EXPORTS

--/////////--

local p = {}

-- Returns a talk notice

-- For documentation, see Template:Gs/talk notice

function p.talknotice(frame)

local args = getArgs(frame, {

wrappers = {

'Template:Gs/talk notice',

'Template:Gs/talk notice/sandbox'

}

})

local topic = getTopicData(frame, args['topic'] or args[1])

if not topic then

return frame:preprocess(syntaxHelp())

elseif not topic.restrictions or (not topic.restrictions['ds'] and not topic.restrictions['1rr']) then

-- error: no relevant sanctions authorised

return frame:preprocess('No relevant sanctions authorised for this topic.')

end

return buildTalkNotice(frame, topic, args)

end

-- Returns an alert

-- For documentation, see Template:Gs/alert

function p.alert(frame)

local args = getArgs(frame, {

wrappers = {

'Template:Gs/alert',

'Template:Gs/alert/sandbox',

}

})

local topic = getTopicData(frame, args['topic'] or args[1])

if not topic then

return frame:preprocess(syntaxHelp())

elseif not topic.restrictions or not topic.restrictions['ds'] then

-- error: DS not authorised, alert not needed

return frame:preprocess('Discretionary sanctions are not authorised for this topic area. Alert is not required.')

end

return buildAlert(frame, topic, args['sig'])

end

-- Returns an edit notice

-- For documentation, see Template:Gs/editnotice

function p.editnotice(frame)

local args = getArgs(frame, {

wrappers = {

'Template:Gs/editnotice',

'Template:Gs/editnotice/sandbox',

'User:ProcrastinatingReader/sandbox/ds'

}

})

local topic = getTopicData(frame, args['topic'] or args[1])

if not topic then

return frame:preprocess(syntaxHelp())

elseif not topic.restrictions or (not topic.restrictions['1rr'] and not args['1rr'] and not args['consensusrequired'] and not args['restriction1']) then

-- error: no custom restrictions authorised, alert not needed

return frame:preprocess('Page sanctions are not authorised for this topic area. Edit notice is not required.Category:Pages with sanctions errors')

end

return buildEditNotice(frame, topic, args)

end

function p.table(frame)

local args = getArgs(frame, {

wrappers = {

'Template:Gs/topics/table',

'Template:Gs/topics/table/sandbox',

}

})

local tbl = mw.html.create('table')

:addClass('wikitable')

:css('font-size', '9pt')

:css('background', 'transparent')

-- Headers

tbl:tag('tr')

:tag('th')

:wikitext("Topic code")

:done()

:tag('th')

:wikitext("Area of conflict")

:done()

:tag('th')

:wikitext("Decision linked to")

:allDone()

-- sort alphabetically

local sortedTable = {}

for n in pairs(data) do

table.insert(sortedTable, n)

end

table.sort(sortedTable)

for _,v in ipairs(sortedTable) do

local sanction = data[v]

local title = mw.title.new(sanction.wikilink).redirectTarget -- probably unnecessarily expensive; just add to config

tbl:tag('tr')

:tag('td')

:wikitext(frame:preprocess("{{tlx"..(args['subst'] and "s" or "").."|{{#ifeq:{{BASEPAGENAME}}|Gs|{{PAGENAME}}|{{BASEPAGENAME}}}}|topic="..(sanction.palias or v).."}}"))

:done()

:tag('td')

:wikitext(sanction.scope)

:done()

:tag('td')

:wikitext(""..title.fullText.."")

:allDone()

end

return tostring(tbl)

end

function p.topicsHelper(frame)

local args = getArgs(frame, {

wrappers = {

'Template:Gs/topics',

'Template:Gs/topics/sandbox'

}

})

if args['sanctions scope'] and data[args['sanctions scope']] then

return _getTopicData(args['sanctions scope']).scope

elseif args['sanctions link'] and data[args['sanctions link']] then

return mw.title.new(_getTopicData(args['sanctions link']).wikilink).redirectTarget

else

return "" -- ?

end

end

return p