require('Module:No globals')
local yesno, makeMessageBox -- passed in from Module:Protected edit request
local makeToolbar = require('Module:Toolbar')._main
local getPagetype = require('Module:Pagetype')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
----------------------------------------------------------------------
-- Helper functions
----------------------------------------------------------------------
local function makeWikilink(page, display)
if display then
return mw.ustring.format('[[%s|%s]]', page, display)
else
return mw.ustring.format('[[%s]]', page)
end
end
----------------------------------------------------------------------
-- Title class
----------------------------------------------------------------------
-- This is basically the mw.title class with some extras thrown in.
local title = {}
title.__index = title
function title.getProtectionLevelText(protectionLevel)
-- Gets the text to use in anchors and urn links.
local levels = {unprotected = 'editunprotected', autoconfirmed = 'editsemiprotected', extendedconfirmed = 'editextendedprotected', templateeditor = 'edittemplateprotected', sysop = 'editprotected'}
return levels[protectionLevel]
end
function title.new(...)
local success, obj = pcall(mw.title.new, ...)
if not (success and obj) then return end
-- Add a protectionLevel property.
obj.protectionLevel = effectiveProtectionLevel(obj.exists and 'edit' or 'create', obj)
if obj.protectionLevel == '*' then
-- Make unprotected pages return "unprotected".
obj.protectionLevel = 'unprotected'
elseif obj.protectionLevel == 'user' then
-- If we just need to be registered, pretend we need to be autoconfirmed, since it's the closest thing we have.
obj.protectionLevel = 'autoconfirmed'
end
-- Add a pagetype property.
obj.pagetype = getPagetype{page = obj.prefixedText, defaultns = 'all'}
-- Add link-making methods.
function obj:makeUrlLink(query, display)
return mw.ustring.format('[%s %s]', self:fullUrl(query), display)
end
function obj:makeViewLink(display)
return self:makeUrlLink({redirect = 'no'}, display)
end
function obj:makeEditLink(display)
return self:makeUrlLink({action = 'संपादन'}, display)
end
function obj:makeHistoryLink(display)
return self:makeUrlLink({action = 'इतिहास'}, display)
end
function obj:makeLastEditLink(display)
return self:makeUrlLink({diff = 'cur', oldid = 'prev'}, display)
end
function obj:makeWhatLinksHereLink(display)
return makeWikilink('Special:WhatLinksHere/' .. self.prefixedText, display)
end
function obj:makeCompareLink(otherTitle, display)
display = display or 'फरक'
local comparePagesTitle = title.new('Special:ComparePages')
return comparePagesTitle:makeUrlLink({page1 = self.prefixedText, page2 = otherTitle.prefixedText}, display)
end
function obj:makeLogLink(logType, display)
local logTitle = title.new('Special:Log')
return logTitle:makeUrlLink({type = logType, page = self.prefixedText}, display)
end
function obj:urlEncode()
return mw.uri.encode(self.prefixedText, 'WIKI')
end
function obj:makeUrnLink(boxProtectionLevel)
-- Outputs a urn link. The protection level is taken from the template, rather than detected from page itself,
-- as the detection may be inaccurate for cascade-protected and title-blacklisted pages as of Nov 2013.
local protectionLinkText = title.getProtectionLevelText(boxProtectionLevel)
return mw.ustring.format('[urn:x-wp-%s:%s <span></span>]', protectionLinkText, self:urlEncode())
end
-- Get a subpage title object, but go through pcall rather than use the unprotected mw.title:subPageTitle.
function obj:getSubpageTitle(subpage)
return title.new(self.prefixedText .. '/' .. subpage)
end
return obj
end
----------------------------------------------------------------------
-- TitleTable class
----------------------------------------------------------------------
local titleTable = {}
titleTable.__index = titleTable
function titleTable.new(args)
-- Get numerical arguments and make title objects for each of them.
local nums = {}
for k, v in pairs(args) do
if type(k) == 'number' then
table.insert(nums, k)
end
end
table.sort(nums)
local titles = {}
for _, num in ipairs(nums) do
local title = title.new(args[num])
table.insert(titles, title)
end
-- Get the current title, and get the subject title if no titles were specified.
titles.currentTitle = mw.title.getCurrentTitle()
if #titles < 1 then
local subjectNs = titles.currentTitle.subjectNsText
if subjectNs ~= '' then
subjectNs = subjectNs .. ':'
end
table.insert(titles, title.new(subjectNs .. titles.currentTitle.text))
end
-- Set the metatable.
setmetatable(titles, titleTable)
return titles
end
function titleTable:memoize(memoField, func, ...)
if self[memoField] ~= nil then
return self[memoField]
else
self[memoField] = func(...)
return self[memoField]
end
end
function titleTable:titleIterator()
local i = 0
local n = #self
return function()
i = i + 1
if i <= n then
return self[i]
end
end
end
function titleTable:hasSameProperty(memoField, getPropertyFunc)
-- If the titles table has more than one title in it, check if they have the same property.
-- The property is found using the getPropertyFunc function, which takes a title object as its single argument.
local function hasSameProperty(getPropertyFunc)
local property
for i, obj in ipairs(self) do
if i == 1 then
property = getPropertyFunc(obj)
elseif getPropertyFunc(obj) ~= property then
return false
end
end
return true
end
return self:memoize(memoField, hasSameProperty, getPropertyFunc)
end
function titleTable:hasSameExistenceStatus()
-- Returns true if all the titles exist, or if they all don't exist. Returns false if there is a mixture of existence statuses.
return self:hasSameProperty('sameExistenceStatus', function (title) return title.exists end)
end
function titleTable:hasSameProtectionStatus()
-- Checks if all the titles have the same protection status (either for creation protection or for edit-protection - the two are not mixed).
local sameExistenceStatus = self:hasSameExistenceStatus()
if sameExistenceStatus then
return self:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end)
else
return sameExistenceStatus
end
end
function titleTable:hasSamePagetype()
-- Checks if all the titles have the same pagetype.
return self:hasSameProperty('samePagetype', function (title) return title.pagetype end)
end
function titleTable:propertyExists(memoField, getPropertyFunc)
-- Checks if a title with a certain property exists.
-- The property is found using the getPropertyFunc function, which takes a title object as its single argument
-- and should return a boolean value.
local function propertyExists(getPropertyFunc)
for titleObj in self:titleIterator() do
if getPropertyFunc(titleObj) then
return true
end
end
return false
end
return self:memoize(memoField, propertyExists, getPropertyFunc)
end
function titleTable:hasNonInterfacePage()
return self:propertyExists('nonInterfacePage', function (titleObj) return titleObj.namespace ~= 8 end)
end
function titleTable:hasTemplateOrModule()
return self:propertyExists('templateOrModule', function (titleObj) return titleObj.namespace == 10 or titleObj.namespace == 828 end)
end
function titleTable:hasNonTemplateOrModule()
return self:propertyExists('nontemplateormodule', function (titleobj) return titleobj.namespace ~= 10 and titleobj.namespace ~= 828 end)
end
function titleTable:hasOtherProtectionLevel(level)
for titleObj in self:titleIterator() do
if titleObj.protectionLevel ~= level then
return true
end
end
return false
end
function titleTable:getProtectionLevels()
local function getProtectionLevels()
local levels = {}
for titleObj in self:titleIterator() do
local level = titleObj.protectionLevel
levels[level] = true
end
return levels
end
return self:memoize('protectionLevels', getProtectionLevels)
end
----------------------------------------------------------------------
-- Blurb class definition
----------------------------------------------------------------------
local blurb = {}
blurb.__index = blurb
function blurb.new(titleTable, boxProtectionLevel)
local obj = {}
obj.titles = titleTable
obj.boxProtectionLevel = boxProtectionLevel
obj.linkCount = 0 -- Counter for the number of total items in the object's link lists.
setmetatable(obj, blurb)
return obj
end
-- Static methods --
function blurb.makeParaText(name, val)
local pipe = mw.text.nowiki('|')
local equals = mw.text.nowiki('=')
val = val and ("''" .. val .. "''") or ''
return mw.ustring.format('<code style="white-space: nowrap;">%s%s%s%s</code>', pipe, name, equals, val)
end
function blurb.makeTemplateLink(s)
return mw.ustring.format('%s[[Template:%s|%s]]%s', mw.text.nowiki('{{'), s, s, mw.text.nowiki('}}'))
end
function blurb:makeProtectionText()
local boxProtectionLevel = self.boxProtectionLevel
local levels = {['*'] = 'unprotected', autoconfirmed = 'semi-protected', extendedconfirmed = 'extended-confirmed-protected', templateeditor = 'template-protected', sysop = 'संपूर्ण संरक्षित'}
for level, protectionText in pairs(levels) do
if level == boxProtectionLevel then
return mw.ustring.format('[[सहाय्य:संरक्षण|%s]]', protectionText)
end
end
error('अनोळखी सुरक्षा स्तर ' .. boxProtectionLevel)
end
function blurb.getPagetypePlural(title)
local pagetype = title.pagetype
if pagetype == 'category' then
return 'वर्ग'
else
return pagetype .. 's'
end
end
-- Normal methods --
function blurb:makeLinkList(title)
local tbargs = {} -- The argument list to pass to Module:Toolbar
tbargs.style = 'font-size: smaller;'
tbargs.separator = 'comma'
-- Page links.
table.insert(tbargs, title:makeEditLink('संपादन'))
table.insert(tbargs, title:makeHistoryLink('इतिहास'))
table.insert(tbargs, title:makeLastEditLink('मागील'))
table.insert(tbargs, title:makeWhatLinksHereLink('दुवे'))
-- Sandbox links.
local sandboxTitle = title:getSubpageTitle('धूळपाटी')
if sandboxTitle and sandboxTitle.exists then
table.insert(tbargs, sandboxTitle:makeViewLink('धूळपाटी'))
table.insert(tbargs, sandboxTitle:makeEditLink('धूळपाटी संपादन'))
table.insert(tbargs, sandboxTitle:makeHistoryLink('धूळपाटी इतिहास'))
table.insert(tbargs, sandboxTitle:makeLastEditLink('धूळपाटी शेवटचे संपादन'))
table.insert(tbargs, title:makeCompareLink(sandboxTitle, 'धूळपाटी फरक'))
end
-- Test cases links.
local testcasesTitle = title:getSubpageTitle('चाचणी ')
if testcasesTitle and testcasesTitle.exists then
table.insert(tbargs, testcasesTitle:makeViewLink('चाचणी '))
end
-- Transclusion count link.
if title.namespace == 10 or title.namespace == 828 then -- Only add the transclusion count link for templates and modules.
local tclink = mw.uri.new{
host = 'tools.wmflabs.org',
path = '/templatecount/index.php',
query = {
lang = 'en',
name = title.text,
namespace = title.namespace,
},
fragment = 'bottom'
}
tclink = string.format('[%s transclusion count]', tostring(tclink))
table.insert(tbargs, tclink)
end
-- Protection log link.
if title.namespace ~= 8 then -- MediaWiki pages don't have protection log entries.
table.insert(tbargs, title:makeLogLink('सुरक्षित करा', 'सुरक्षा नोंदी'))
end
self.linkCount = self.linkCount + #tbargs -- Keep track of the number of total links created by the object.
return makeToolbar(tbargs)
end
function blurb:makeLinkLists()
local titles = self.titles
if #titles == 1 then
return self:makeLinkList(titles[1])
else
local ret = {}
table.insert(ret, '<ul>')
for i, titleObj in ipairs(titles) do
table.insert(ret, mw.ustring.format('<li>%s %s</li>', titleObj:makeViewLink(titleObj.prefixedText), self:makeLinkList(titleObj)))
end
table.insert(ret, '</ul>')
return table.concat(ret)
end
end
function blurb:makeIntro()
local titles = self.titles
local requested = 'अशी [[विकिपीडिया:संपादन विनंत्या|विनंती]] करण्यात येते कि '
local protectionText
if titles:hasNonInterfacePage() then
protectionText = ' ' .. self:makeProtectionText()
else
protectionText = '' -- Interface pages cannot be unprotected, so we don't need to explicitly say they are protected.
end
-- Deal with cases where we are passed multiple titles.
if #titles > 1 then
local pagetype
if titles:hasSamePagetype() then
pagetype = blurb.getPagetypePlural(titles[1])
else
pagetype = 'pages'
end
return mw.ustring.format("'''%s खालील पानांवर संपादने करावी%s %s''':", requested, protectionText, pagetype)
end
-- Deal with cases where we are passed only one title.
local title = titles[1]
local stringToFormat
if title.exists then
stringToFormat = '%s या %s पानावर, खालील %sवर आमच्या वतीने संपादने करावीत: %s '
else
stringToFormat = '%s %s हे %s वर %s तयार करावे.'
end
stringToFormat = "'''" .. stringToFormat .. "'''"
return mw.ustring.format(stringToFormat, requested, protectionText, title.pagetype, title:makeViewLink(title.prefixedText))
end
function blurb:makeBody()
local titles = self.titles
local protectionLevels = titles:getProtectionLevels()
local boxProtectionLevel = self.boxProtectionLevel
local hasNonInterfacePage = titles:hasNonInterfacePage()
local isPlural = false
if #titles > 1 then
isPlural = true
end
local descriptionText = "या साच्याखालीच, विनंतीचे '''संपूर्ण व नेमके वर्णन''' द्यावयास हवे , "
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
local editText = 'संपादन'
if isPlural then
editText = editText .. 's'
end
local descriptionCompleteText = mw.ustring.format('त्यानुसार, या विषयाशी अपरिचित असणारा संपादक विनंती केलेले काम त्वरीत करू शकेल.', editText)
descriptionText = descriptionText .. descriptionCompleteText
else
descriptionText = descriptionText .. 'म्हणजेच, कोणता मजकूर हटवायचा/वगळायचा आहे ते नेमके नमूद करा व बदली करावयाच्या मजकूराची अचूक व शब्दशः प्रत तेथे टाका. '
.. [["कृपया ''क्ष''" बदला हे '''स्वीकार्य नाही''' त्यास ताबडतोब नामंजूर केले जाईल; विनंती ही '''खालील प्रकारेच''' असावयास हवी "कृपया ''क्ष'' ला ''य'' ने बदला".]]
end
local smallText = ''
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
local templateFullText
if boxProtectionLevel == 'sysop' then
templateFullText = 'संपूर्ण संरक्षित'
elseif boxProtectionLevel == 'templateeditor' then
templateFullText = 'template-protected'
end
smallText = 'या ' .. templateFullText .. " पानाच्या संपादन विनंत्या, केवळ त्या पानांसाठीच करण्यात याव्यात, जी पाने '''विवादमुक्त''' आहेत किंवा ज्यात [[विकिपीडिया:एकवाक्यता|एकमत]] आहे."
.. " जर प्रस्तावित संपादन हे '''विवाद''' उत्पन्न करण्याची शक्यता असेल तर, हा साचा '''लावण्यापूर्वीच,''' सुरक्षित केलेल्या पानाच्या संबंधीत चर्चापानावर, त्याची चर्चा करा."
else
local userText
if boxProtectionLevel == 'extendedconfirmed' then
userText = '[[Wikipedia:User access levels#Extended confirmed users|extended confirmed]] user'
elseif boxProtectionLevel == 'autoconfirmed' then
userText = '[[Wikipedia:User access levels#Autoconfirmed|autoconfirmed]] user'
else
userText = 'user'
end
local answeredPara = blurb.makeParaText('answered', 'no')
local stringToFormat = 'हे संपादन कोणत्याही %s द्वारा केले जाऊ शकते. '
.. [[सदस्याचे इनपुटची वाट बघतांना, जेंव्हा विनंती स्वीकारण्यात येते,नाकारण्यात येते, किंवा तटस्थ ठेवण्यात येते, हा %s प्राचल "'''yes'''" करण्याची आठवण ठेवा.]]
.. "हे यासाठी कि, अक्रिय अथवा पूर्ण झालेल्या विनंत्यांनी, आवश्यकता नसतांना, संपादन विनंत्या वर्गात विनाकारणच भर पडते. "
.. 'प्रतिसाद म्हणून, आपण %s साचा वापरण्यास कदाचित ईच्छुक असाल.'
smallText = mw.ustring.format(stringToFormat, userText, answeredPara, blurb.makeTemplateLink('ESp'))
end
if not isPlural then
local title = titles[1]
if title.namespace == 10 or title.namespace == 828 then
local sandboxTitle = title:getSubpageTitle('sandbox')
if sandboxTitle and sandboxTitle.exists then
smallText = smallText ..' प्रथमतः संपादन विनंती सादर करण्याआधी'
.. sandboxTitle:makeViewLink(title.pagetype .. "'s sandbox")
local testcasesTitle = title:getSubpageTitle('testcases')
if testcasesTitle and testcasesTitle.exists then
smallText = smallText .. 'येथे बदल करण्याचा विचार करा व ' .. testcasesTitle:makeViewLink ('येथे त्याची चांगल्या तर्हेने चाचणी करा')
end
smallText = smallText .. 'मग आपली विनंती सादर करा.'
end
end
end
if hasNonInterfacePage then
smallText = smallText .. ' एखादे पान सुरक्षित करावयाचे अथवा सुरक्षारहित, यासाठी योग्य ती विनंती [[विकिपीडिया:पान सुरक्षितता विनंत्या|सुरक्षितता विनंती]] येथे करा.'
end
if boxProtectionLevel == 'sysop' or boxProtectionLevel == 'templateeditor' then
smallText = smallText .. ' जेंव्हा एखादी विनंती पूर्ण करण्यात येते किंवा नाकारण्यात येते, त्यानंतर कृपया ' .. blurb.makeParaText('answered', 'yes') .. ' हा प्राचल तो साचा अक्रिय करण्यास वापरा.'
end
return mw.ustring.format('%s\n<p style="font-size:smaller; line-height:1.3em;">\n%s\n</p>', descriptionText, smallText)
end
function blurb:export()
local intro = self:makeIntro()
local linkLists = self:makeLinkLists()
local body = self:makeBody()
-- Start long links lists on a new line.
local linkListSep = ' '
if self.linkCount > 5 then
linkListSep = '<br />'
end
return mw.ustring.format('%s%s%s\n\n%s', intro, linkListSep, linkLists, body)
end
----------------------------------------------------------------------
-- Subclass of Module:Protected edit request's box class for active boxes
----------------------------------------------------------------------
local box = {}
box.__index = box
function box.new(protectionType, args)
-- In the inheritance system used here, an object's metatable is its class, and a class's metatable is its superclass
local obj = getmetatable(box).new(protectionType, args)
setmetatable(obj, box)
local boxProtectionLevels = {semi = 'autoconfirmed', extended = 'extendedconfirmed', template = 'templateeditor', full = 'sysop'}
obj.boxProtectionLevel = boxProtectionLevels[protectionType]
obj.demo = yesno(args.demo)
-- Set dependent objects.
obj.titles = titleTable.new(args)
if not yesno(args.force) and obj.titles:hasSameProperty('sameProtectionStatus', function (title) return title.protectionLevel end) and obj.titles[1].protectionLevel ~= 'unprotected' then
obj.boxProtectionLevel = obj.titles[1].protectionLevel
end
obj.blurb = blurb.new(obj.titles, obj.boxProtectionLevel)
return obj
end
function box:setImage()
local titles = self.titles
local boxProtectionLevel = self.boxProtectionLevel
local padlock
if boxProtectionLevel == 'sysop' then
padlock = 'Padlock.svg'
elseif boxProtectionLevel == 'templateeditor' then
padlock = 'Padlock-pink.svg'
elseif boxProtectionLevel == 'autoconfirmed' then
padlock = 'Padlock-silver.svg'
elseif boxProtectionLevel == 'extendedconfirmed' then
padlock = 'Padlock-blue.svg'
else
padlock = 'Padlock-bronze-open.svg'
end
local stringToFormat = '[[File:%s|%dpx|alt=|link=]]'
local smallPadlock = mw.ustring.format(stringToFormat, padlock, 25)
local largePadlock = mw.ustring.format(stringToFormat, padlock, 60)
self:setArg('smallimage', smallPadlock)
self:setArg('image', largePadlock)
end
function box:buildUrnLinks()
local ret = {}
local boxProtectionLevel = self.boxProtectionLevel
for titleObj in self.titles:titleIterator() do
table.insert(ret, titleObj:makeUrnLink(boxProtectionLevel))
end
return mw.ustring.format('<span class="plainlinks" style="display:none">%s</span>', table.concat(ret))
end
function box:setBlurbText()
self:setArg('text', self.blurb:export() .. self:buildUrnLinks())
end
function box:exportRequestTmbox()
self:setImage()
self:setBlurbText()
self:setArg('class', 'editrequest')
self:setArg('id', title.getProtectionLevelText(self.boxProtectionLevel)) -- for anchor. yes, this leads to multiple elements with the same ID. we should probably fix this at some point
return makeMessageBox('tmbox', self.tmboxArgs)
end
function box:exportRequestCategories()
local cats = {}
local boxProtectionLevel = self.boxProtectionLevel
local function addCat(cat)
table.insert(cats, mw.ustring.format('[[Category:%s]]', cat))
end
local protectionCats = {
autoconfirmed = 'विकिपीडिया अर्ध-सुरक्षित संपादन विनंत्या',
extendedconfirmed = 'विकिपीडिया विस्तारीत-शाबित-सुरक्षित संपादन विनंत्या',
templateeditor = 'विकिपीडिया साच्याद्वारे-सुरक्षित संपादन विनंत्या',
sysop = 'विकिपीडिया संपूर्ण-सुरक्षित संपादन विनंत्या'
}
addCat(protectionCats[boxProtectionLevel])
if self.titles:hasOtherProtectionLevel(boxProtectionLevel) then
addCat('चुकीचा साचा वापरत असल्याची शक्यता असणाऱ्या विकिपीडिया संपादन विनंत्या')
end
return table.concat(cats)
end
function box:export()
if not self.titles.currentTitle.isTalkPage and not self.demo then
return '<span class="error">Error: Protected edit requests can only be made on the talk page.</span>[[Category:Non-talk pages requesting an edit to a protected page]]'
end
local ret = {}
table.insert(ret, self:exportRequestTmbox())
if not self.demo then
table.insert(ret, self:exportRequestCategories())
end
return table.concat(ret)
end
----------------------------------------------------------------------
-- Function exported to Module:Protected edit request
----------------------------------------------------------------------
return function(superclass, yn, mb)
yesno = yn
makeMessageBox = mb
return setmetatable(box, superclass)
end