Module:Sanctions: Difference between revisions

Content deleted Content added
additional note
Close added "p" tags
 
(34 intermediate revisions by 10 users not shown)
Line 1:
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
 
local rawData = mw.loadData('Module:Sanctions/data')
local data = rawData.sanctions
Line 5 ⟶ 7:
 
local messageBox = require('Module:Message box')
 
-- Functions
 
local function tableContainsValue(needle, haystack)
Line 32 ⟶ 36:
end
 
-- Topic class
local function getTopicData(frame, topicAlias)
if not topicAlias then
return false
end
 
local topicTopic = _getTopicData(topicAlias){}
Topic.__index = Topic
if topic then
 
return topic
function Topic.new(topicCode, args)
local obj = {}
obj._args = args
obj._topicData = _getTopicData(topicCode)
return setmetatable(obj, Topic)
end
 
function Topic:get(arg)
return self._topicData[arg]
end
 
function Topic:exists()
return ((self._topicData ~= nil) and (self._topicData ~= false))
end
 
function Topic:hasGlobalRestriction(type)
return self._topicData.restrictions[type]
end
 
function Topic:hasLocalRestriction(type)
local localRestriction = self._args[type]
if localRestriction then
if mw.ustring.find(type, '^restriction') ~= nil then
return true
else
return yesno(localRestriction)
end
else
return false
end
end
 
function Topic:hasRestriction(type)
return self:hasGlobalRestriction(type) or self:hasLocalRestriction(type)
end
 
function Topic:hasRestrictions(arr)
for _, v in ipairs(arr) do
if self:hasRestriction(v) then
return true
end
end
return false
end
 
function Topic:hasAnyRevertRestrictions()
return self:hasRestrictions({'1rr', 'consensusrequired', 'brd'})
end
 
function Topic:hasAnyRestrictions()
return self:hasAnyRevertRestrictions() or self:hasRestrictions({'restriction1'})
end
 
function Topic:getCustomRestrictions()
local customRestrictions = {}
local ri = 1
local checkArr = self._topicData.restrictions
local breakNext = false
while true do
if checkArr['restriction'..ri] then
table.insert(customRestrictions, checkArr['restriction'..ri])
ri = ri + 1
else
if breakNext then
break
else
ri = 1
checkArr = self._args
breakNext = true
end
end
end
return customRestrictions
end
 
-- End classes
 
-- This function builds a talk notice
Line 49 ⟶ 125:
--
-- @param frame
-- @param topicData data for the giventopic topic from the /dataclass pageinstance
-- @param args arguments passed to wrapper template
-- @returns String representation of notice
local function buildTalkNotice(frame, topicDatatopic, args)
local type = args['type'] or args[2] or 'mini'
local restrictions = topicData.restrictions
local type = args['type'] or args[2] or 'standard'
local out = mw.html.create('')
local hasRestrictions = topic:hasAnyRestrictions()
local hasRevertRestrictions = topic:hasAnyRevertRestrictions()
if hasRestrictions then
type = 'long' -- force long displaywhere custom restrictions are applicable
 
if type == 'long' then
out
:tag('span')
:css('font-size', '120%')
:wikitext("'''WARNING: ACTIVE COMMUNITY SANCTIONS'''")
:done()
end
 
if type == 'long' then
out
:tag('p')
:wikitext("The article [[:{{SUBJECTPAGENAME}}]], along with other pages relating to "..topicData.topic:get('scope')..", is currently subject to '''[[WP:AC/DS|discretionary sanctions]]''' authoriseddesignated by the community (see:as [["..a topicData['wikilink'] .."]])." .. ((args['1rr'] or args['consensusrequired'] or args['brd']Wikipedia:Contentious ortopics|contentious args['restriction1'topic]]) 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("<strong>The use of the [[WPWikipedia:AC/DSContentious topics|discretionarycontentious sanctionstopics procedure]] has been [[".. topicData['wikilink'] .."|authorised]] by the community for pages related to ".. topicData[topic:get('scope']) ..", including this page.</strong>" .. (type == 'mini' and ' PleaseEditors consultwho repeatedly or seriously fail to adhere to the [[Wikipedia:Arbitration_Committee/Discretionary_sanctions#AwarenessFive_pillars|awarenesspurpose criteriaof Wikipedia]], andany expected [[Wikipedia:Etiquette|standards of behaviour]], or any [[Wikipedia:List_of_policies|normal editorial process]] may editbe carefullysanctioned.' or ''))
end
 
if not (type == 'mini') then
local hasList = false
local hasRevertRestrictions = false
local restrictionList = mw.html.create('ul')
 
-- 1RR
if restrictions['1rr'] or args['1rr'] then
if topic:hasRestriction('1rr') then
hasList = true
hasRevertRestrictions = true
 
restrictionList
:tag('li')
:wikitext("'''Limit of one revert in 24 hours:''' This article is under [[Wikipedia:Edit warring#Other revert rules|WP:1RR]] (one [[Wikipedia:Reverting|revert]] per editor per article ''per 24-hour period'') [[Category:Wikipedia pages subject to a one-revert restriction]]")
end
 
-- Text for boilerplate/predefined restrictions
if args['consensusrequired'] then
if topic:hasRestriction('consensusrequired') then
hasList = true
hasRevertRestrictions = true
 
restrictionList
:tag('li')
:wikitext("'''Consensus required:''' All editors must obtain [[WP:Consensus|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. [[Category:Wikipedia pages subject to a consensus required restriction]]")
end
 
if args[topic:hasRestriction('brd']) then
hasList = true
hasRevertRestrictions = true
 
restrictionList
:tag('li')
:wikitext("'''24-hr [[Wikipedia:BOLD, revert, discuss cycle|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 [[Wikipedia:BOLD, revert, discuss cycle#WP:BRR|are preferable]] to wholesale reverts. [[Category:Wikipedia pages subject to an enforced BRD restriction]]")
end
 
local customRestrictions = topic:getCustomRestrictions()
local ri = 1
for _, v in ipairs(customRestrictions) do
while true do
restrictionList
if args['restriction'..ri] then
restrictionList:tag('li')
:tagwikitext('li'v)
:wikitext(args['restriction'..ri])
ri = ri + 1
hasList = true
else
break
end
end
 
if hasListhasRestrictions then
out:node(restrictionList)
end
Line 125 ⟶ 186:
out
:tag('p')
:wikitext("Provided the [[Wikipedia:Arbitration_Committee/Discretionary_sanctions#Awareness|awareness criteria]] are met, discretionary sanctions may be used against editorsEditors who repeatedly or seriously fail to adhere to the [[Wikipedia:Five_pillars|purpose of Wikipedia]], any expected [[Wikipedia:Etiquette|standards of behaviour]], or any [[Wikipedia:List_of_policies|normal editorial process]] may be sanctioned.")
-- Further info box
if hasRestrictions then
if type == 'long' and (restrictions['ds'] or restrictions['1rr'] or args['1rr']) then
local furtherInfo = mw.html.create('')
 
Line 138 ⟶ 199:
 
local enforcementProcedures = mw.html.create('ul')
 
if hasRevertRestrictions or args['restriction1'] then
enforcementProcedures
:tag('li')
:wikitext("Violations of any restrictions (excluding 1RR violations) and other conduct issues should be reported to the [[Wikipedia:Administrators' noticeboard/Incidents|administrators' incidents noticeboard]]. Violations of the 1RR restriction should be reported to the [[WP:ANEW|administrators' edit warring noticeboard]].")
: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 [[Wikipedia:Administrators' noticeboard/Incidents|administrators' incidents noticeboard]].")
:done()
end
 
enforcementProcedures
:tag('li')
:wikitext("Violations of any restrictions " .. (hasRevertRestrictions and "(excluding 1RR/reverting violations) " or "") .. "and other conduct issues should be reported to the [[Wikipedia:Administrators' noticeboard/Incidents|administrators' incidents noticeboard]]." .. (hasRevertRestrictions and " Violations of revert restrictions should be reported to the [[Wikipedia:Administrators' noticeboard/Edit warring|administrators' edit warring noticeboard]]." or ""))
:wikitext("An editor must be [[Wikipedia:Arbitration_Committee/Discretionary_sanctions#Awareness|aware]] before they can be sanctioned.")
:done()
:tag('li')
:wikitext("Editors who violate any listed restrictions may be blocked by any uninvolved administrator, even on a first offense.")
:done()
:tag('li')
:wikitext("An editor must be [[Wikipedia:Contentious topics#Awareness of contentious topics|aware]] before they can be sanctioned.")
:allDone()
furtherInfo:node(enforcementProcedures)
Line 163 ⟶ 215:
furtherInfo
:tag('p')
:wikitext("With respect to theany WP:1RRreverting restrictionrestrictions:")
:done()
:tag('ul')
Line 182 ⟶ 234:
end
 
local collapsed = frame:expandTemplate{ title = 'collapse', args = { -- TODO not use template
tostring(furtherInfo),
(hasRevertRestrictions and '<span style="color:red">' or '')..'Remedy instructions and exemptions'..(hasRevertRestrictions and '</span>' or ''),
['bg'] = '#EEE8AA'
}}
Line 196 ⟶ 248:
 
local box = messageBox.main( 'tmbox', {
type = 'noticecontent',
image = type == 'long' and '[[File:Commons-emblem-issue.svg|50px]]' or '[[ImageFile:Commons-emblem-hand-orange.svg|40px]]',
text = frame:preprocess(tostring(out))
})
Line 207 ⟶ 259:
--
-- @param frame
-- @param topicData data for the giventopic topic from the /dataclass pageinstance
-- @returns String representation of notice
local function buildAlert(frame, topicDatatopic, sig)
local hasRestrictions = topic:hasAnyRestrictions()
local restrictionIntro
local restrictionList
if hasRestrictions then
restrictionIntro = mw.html.create('p')
restrictionIntro:wikitext("Additionally, the following restriction(s) apply to this topic area:")
restrictionList = mw.html.create('ul')
if topic:hasRestriction('1rr') then
restrictionList
:tag('li')
:wikitext("All articles in this topic area are under [[Wikipedia:Edit warring#Other revert rules|WP:1RR]] (a limit of one [[Wikipedia:Reverting|revert]] per editor per article per 24-hour period). When in doubt, assume an edit is related and so is a revert. Clear vandalism of whatever origin may be reverted without restriction. Reverts of edits made by anonymous IP editors that are not vandalism are exempt from 1RR but are subject to the usual rules on edit warring. Editors who otherwise violate this 1RR restriction may be blocked without warning by any uninvolved administrator, even on a first offence.")
end
local customRestrictions = topic:getCustomRestrictions()
for _, v in ipairs(customRestrictions) do
restrictionList
:tag('li')
:wikitext(v)
end
end
local out = mw.html.create('table')
:addClass('messageboxgs-alert')
:cssText("border: 1px solid #AAA; background-color: #E5F8FF; padding: 0.5em; width: 100%; margin-bottom: 1em")
 
out
Line 221 ⟶ 297:
:done()
:tag('td')
:tag('p')
: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.''")
: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()
:done()
: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 [[Wikipedia:General sanctions|sanctions]] - such as [[Wikipedia:Editing restrictions#Types of restrictions|editing restrictions]], [[Wikipedia:Banning policy#Types of bans|bans]], or [[WP:Blocking policy|blocks]] - on editors who do not strictly follow [[Wikipedia:List of policies|Wikipedia's policies]], or the [[Wikipedia:Arbitration_Committee/Discretionary_sanctions#Page_restrictions|page-specific restrictions]], when making edits related to the topic.")
:newlinetag('p')
:wikitext("You have shown interest in ".. topic:get('scope') ..". Due to past disruption in this topic area, the community has authorised uninvolved administrators to impose [[Wikipedia:Contentious topics|contentious topics restrictions]]—such as [[Wikipedia:Editing restrictions#Types of restrictions|editing restrictions]], [[Wikipedia:Banning policy#Types of bans|bans]], or [[WP:Blocking policy|blocks]]—on editors who do not strictly follow [[Wikipedia:List of policies|Wikipedia's policies]], expected [[Wikipedia:Etiquette|standards of behaviour]], or the [[Wikipedia:Contentious topics#Standard set|page-specific restrictions]], when making edits related to the topic.")
:wikitext("For additional information, please see the [[".. topicData.wikilink .."|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.")
:done()
:node(restrictionIntro)
:node(restrictionList)
:tag('p')
:wikitext("For additional information, please see the [[".. topic:get('wikilink') .."|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 ''))
:done()
 
return frame:preprocess(tostring(out))
Line 231 ⟶ 313:
 
-- Builds an edit notice
local function buildEditNotice(frame, topicDatatopic, args)
local restrictions = topicData.restrictions
local enHeader = mw.html.create('')
local restrictionMsgs = {}
local nRestriction = restrictions['1rr'] and 1 or 0
local expiry = args['expiry'] or 'indefinite'
local cRestrictions = {}
local redirect = args['redirect'] or ''
if topic:hasRestriction('1rr') then
table.insert(restrictionMsgs, "Editors must not make more than one [[Help:Reverting|revert]] per 24 hours (subject to [[Wikipedia:Edit warring#Exemptions|exceptions]])")
end
if topic:hasRestriction('consensusrequired') then
table.insert(restrictionMsgs, "Editors must not reinstate any challenged edits (via reversion) without first obtaining [[Wikipedia:Consensus|consensus]] on the talk page of this article")
end
 
local customRestrictions = topic:getCustomRestrictions()
local ri = 1
for _, v in ipairs(customRestrictions) do
while true do
table.insert(restrictionMsgs, v)
if args['restriction'..ri] then
table.insert(cRestrictions, args['restriction'..ri])
ri = ri + 1
nRestriction = nRestriction + 1
else
break
end
end
 
if nRestriction#restrictionMsgs == 0 then
return frame:preprocess(syntaxHelp())
elseif nRestriction == 1 then
enHeader
:wikitext("Editors to this page ")
 
if restrictions['1rr'] or args['1rr'] then
enHeader
:wikitext("are restricted to making no more than one [[Help:Reverting|revert]] per twenty-four (24) hours (subject to exceptions below)")
else
enHeader
:wikitext(args['restriction1'])
end
else
local list = mw.html.create('ul')
enHeader
for _,v in ipairs(restrictionMsgs) do
:wikitext("Editors to this page:")
list
:tag('li')
if restrictions['1rr'] or args['1rr'] then
:wikitext(v)
enHeader
:newlinedone()
:wikitext("* are restricted to making no more than one [[Help:Reverting|revert]] per twenty-four (24) hours (subject to exceptions below)")
end
 
for _,v in ipairs(cRestrictions) do
enHeader
:newline()
:wikitext("* " .. v)
end
enHeader:wikitext(tostring(list))
end
 
Line 281 ⟶ 348:
enText
:tag('p')
:wikitext("<strong>Breaching the restriction on this page may result in a block or other sanctions.</strong> In addition, please note that because this topic area has been disrupted in the past, the community has [["..topic:get('wikilink').."|authorised]] administrators to take [[Wikipedia:Contentious topics|appropriate steps]] to ensure the smooth running of all pages related to "..topic:get('scope')..". Conduct which does not adhere to our policies and [[Wikipedia:Etiquette|standards of behaviour]] may be met with sanctions. Please edit carefully.")
:wikitext("This is due to [["..topicData.wikilink.."|active community sanctions]] on all pages relating to "..topicData.scope..". <strong>If you breach the restriction on this page, you may be blocked or otherwise sanctioned" .. (restrictions['1rr'] and " <u>without warning</u>" or "") .. ".</strong> Please edit carefully.")
:done()
:tag('p')
:wikitext("In addition, please note that discretionary sanctions are in force across this topic area, and can be used against individual editors who repeatedly or seriously fail to adhere to the [[Wikipedia:Five pillars|purpose of Wikipedia]], any expected [[Wikipedia:Etiquette|standards of behaviour]], or any [[Wikipedia:List of policies|Wikipedia policy and editorial norm]].")
:done()
:tag('p')
:css("font-size", "85%")
:wikitext("Before you make any more edits to pages in this topic area, please familiarise yourself with the [[Wikipedia:General sanctions|general sanctions system]] and the [["..topicData.wikilink.."|restrictions in this topic area]]." .. (restrictions['1rr'] and " Clear vandalism of whatever origin may be reverted without restriction. Reverts of edits made by anonymous IP editors that are not vandalism are exempt from 1RR but are subject to the usual rules on edit warring." or "") .. (restrictions['500/30'] and " Edits by unregistered users and editors with less than 500 edits or 30 days tenure may be reverted without regarding the one revert rule." or ""))
 
local editnotice = frame:expandTemplate{ title = 'editnotice', args = {
expiry = "indefinite"tostring(expiry),
headerstyle = "font-size: 120%;",
style = "background: ivory;",
image = "Commons-emblem-issue.svg",
imagesize = "50px",
redirect = tostring(redirect),
header = tostring(enHeader),
text = tostring(enText)
Line 319 ⟶ 380:
})
 
local topic = getTopicDataTopic.new(frame, args['topic'] or args[1], args)
 
if not topic:exists() 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('<span class="error">No relevant sanctions authorised for this topic.</span>')
end
Line 341 ⟶ 399:
})
 
local topic = getTopicDataTopic.new(frame, args['topic'] or args[1], args)
if not topic:exists() then
return frame:preprocess(syntaxHelp())
elseif not topic.restrictions or not topic.restrictions[:hasRestriction('ds']) then
return frame:preprocess('<span class="error">This topic area is not designated as a contentious topic. Alert is not required.</span>')
-- error: DS not authorised, alert not needed
return frame:preprocess('<span class="error">Discretionary sanctions are not authorised for this topic area. Alert is not required.</span>')
end
return buildAlert(frame, topic, args['sig'])
end
 
Line 358 ⟶ 415:
wrappers = {
'Template:Gs/editnotice',
'Template:Gs/editnotice/sandbox',
}
})
 
local topic = getTopicDataTopic.new(frame, args['topic'] or args[1], args)
if not topic:exists() then
return frame:preprocess(syntaxHelp())
elseif not topic.restrictions or :hasAnyRestrictions(not topic.restrictions['1rr'] and not args['restriction1']) then
return frame:preprocess('<span class="error">Page sanctions are not authorised for this topic area. Edit notice is not required.</span>[[Category:Pages with sanctions errors]]')
-- error: no custom restrictions authorised, alert not needed
return frame:preprocess('<span class="error">Page sanctions are not authorised for this topic area. Edit notice is not required.</span>')
end
 
Line 385 ⟶ 441:
:css('font-size', '9pt')
:css('background', 'transparent')
:css('color', 'inherit')
 
-- Headers
Line 410 ⟶ 467:
tbl:tag('tr')
:tag('td')
:wikitext(frame:preprocess("{{tlx"..(args['subst'] and "s" or "").."|{{#ifeq:{{BASEPAGENAME}}|Gs|{{PAGENAME}}|{{BASEPAGENAME}}}}|<nowiki>topic=</nowiki><b>"..(sanction.palias or v).."</b>}}"))
:done()
:tag('td')
Line 437 ⟶ 494:
else
return "" -- ?
end
end
 
-- Returns true if the given topic name is a valid topic area
function p.checkIfValidTopic(topicName)
local topic = Topic.new(topicName, nil)
if topic:exists() then
return true
else
return false
end
end