پودمان:Protection banner: تفاوت میان نسخه‌ها

۲٬۸۰۹ بایت اضافه‌شده ،  ‏۲۵ فوریهٔ ۲۰۲۳
جز
۱ نسخه واردشده
en.wikipedia>ProcrastinatingReader
(add catonly param which hides both the banner and padlock if set to yes. all testcases pass. tested in sandbox.)
جز (۱ نسخه واردشده)
 
(۲ نسخهٔ میانی ویرایش شده توسط ۲ کاربر نشان داده نشد)
خط ۱: خط ۱:
-- This module implements {{pp-meta}} and its daughter templates such as
-- This module implements {{pp-meta}} and its daughter templates such as
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.
-- {{pp-dispute}}, {{pp-vandalism}} and {{pp-sock}}.
-- بخش‌هایی از این پودمان برای فارسی‌سازی بهتر تغییریافته است. لطفاً هنگام به‌روزرسانی دقت کنید.


-- Initialise necessary modules.
-- Initialise necessary modules.
require('Module:No globals')
require('Module:No globals')
local converter = require("Module:Numeral converter").convert
local makeFileLink = require('Module:File link')._main
local makeFileLink = require('Module:File link')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
local effectiveProtectionLevel = require('Module:Effective protection level')._main
خط ۱۸: خط ۲۰:
-- Helper functions
-- Helper functions
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- چون ممکنه نام ماه میلادی رو به فارسی کاربران بنویسند من این تابع رو تعریف کردم که به انگلیسی برگرداند تا خطای تاریخ نامعتبر ندهد.
local function replacePersianGreMonthName(frame)
getArgs = require('Module:Arguments').getArgs
local args = getArgs(frame)
local greMonth = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'}
local perGreMonth = {'ژانویه', 'فوریه', 'مارس', 'آوریل', 'مه', 'ژوئن', 'ژوئیه', 'اوت', 'سپتامبر', 'اکتبر', 'نوامبر', 'دسامبر'}
for k, v in ipairs(perGreMonth) do
args[1] = mw.ustring.gsub(args[1], v, greMonth[k])
end
return converter("en", args[1])
end
-- از آنجا که تاریخ‌ها به صورت انگلیسی به پودمان داده می‌شوند، از mw.getLanguage('en') استفاده شده‌است
-- و خروجی formatDate() از آبجکت زبان مربوطه با فرمت xi انگلیسی است.
-- برای تبدیل نام انگلیسی ماه‌های فارسی به نوشتهٔ فارسی از این تابع استفاده می‌شود.
local function replacePersianMonthName(str)
local engMonth = {'Farvardin', 'Ordibehesht', 'Khordad', 'Tir', 'Mordad', 'Shahrivar', 'Mehr', 'Aban', 'Azar', 'Dey', 'Bahman', 'Esfand'}
local faMonth = {'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'}
for k, v in ipairs(engMonth) do
str = mw.ustring.gsub(str, v, faMonth[k])
end
return str
end


local function makeCategoryLink(cat, sort)
local function makeCategoryLink(cat, sort)
if cat then
if cat then
return string.format(
return mw.ustring.format(
'[[%s:%s|%s]]',
'[[%s:%s|%s]]',
mw.site.namespaces[14].name,
mw.site.namespaces[14].name,
خط ۳۳: خط ۵۹:
local function validateDate(dateString, dateType)
local function validateDate(dateString, dateType)
if not lang then
if not lang then
lang = mw.language.getContentLanguage()
-- در خط زیر جای mw.language.getContentLanguage() از mw.getLanguage('en') استفاده کردم.
lang = mw.getLanguage('en')
end
end
local success, result = pcall(lang.formatDate, lang, 'U', dateString)
local success, result = pcall(lang.formatDate, lang, 'U', converter('en', dateString))
if success then
if success then
result = tonumber(result)
result = tonumber(result)
خط ۴۲: خط ۶۹:
end
end
end
end
error(string.format(
error(mw.ustring.format(
'invalid %s: %s',
'%s نامعتبر: %s',
dateType,
dateType,
tostring(dateString)
tostring(dateString)
خط ۵۰: خط ۷۷:


local function makeFullUrl(page, query, display)
local function makeFullUrl(page, query, display)
return string.format(
return mw.ustring.format(
'[%s %s]',
'[%s %s]',
tostring(mw.uri.fullUrl(page, query)),
tostring(mw.uri.fullUrl(page, query)),
خط ۱۱۲: خط ۱۳۹:
obj.action = args.action
obj.action = args.action
else
else
error(string.format(
error(mw.ustring.format(
'invalid action: %s',
'اقدام نامعتبر: %s',
tostring(args.action)
tostring(args.action)
), 3)
), 3)
خط ۱۳۱: خط ۱۵۸:
obj.expiry = 'indef'
obj.expiry = 'indef'
elseif effectiveExpiry ~= 'unknown' then
elseif effectiveExpiry ~= 'unknown' then
obj.expiry = validateDate(effectiveExpiry, 'expiry date')
obj.expiry = validateDate(effectiveExpiry, 'تاریخ انقضا')
end
end


خط ۱۳۸: خط ۱۶۵:
obj.reason = mw.ustring.lower(args[1])
obj.reason = mw.ustring.lower(args[1])
if obj.reason:find('|') then
if obj.reason:find('|') then
error('reasons cannot contain the pipe character ("|")', 3)
error('دلایل نمی‌تواند شامل نویسه خط عمودی («|») باشد', 3)
end
end
end
end
خط ۱۴۴: خط ۱۷۱:
-- Set protection date
-- Set protection date
if args.date then
if args.date then
obj.protectionDate = validateDate(args.date, 'protection date')
obj.protectionDate = validateDate(args.date, 'تاریخ حفاظت')
end
end
خط ۱۶۹: خط ۱۹۶:
end
end
return setmetatable(obj, Protection)
return setmetatable(obj, Protection)
end
function Protection:isUserScript()
-- Whether the page is a user JavaScript or CSS page.
local title = self.title
return title.namespace == 2 and (
title.contentModel == 'javascript' or title.contentModel == 'css'
)
end
end


خط ۱۸۲: خط ۲۰۱:
return self.level ~= '*'
return self.level ~= '*'
end
end
function Protection:shouldShowLock()
-- Whether we should output a banner/padlock
return self:isProtected() and not self:isUserScript()
end
-- Whether this page needs a protection category.
Protection.shouldHaveProtectionCategory = Protection.shouldShowLock


function Protection:isTemporary()
function Protection:isTemporary()
خط ۱۹۶: خط ۲۰۷:


function Protection:makeProtectionCategory()
function Protection:makeProtectionCategory()
if not self:shouldHaveProtectionCategory() then
local cfg = self._cfg
local title = self.title
-- Exit if the page is not protected.
if not self:isProtected() then
return ''
return ''
end
end
local cfg = self._cfg
local title = self.title
-- Get the expiry key fragment.
-- Get the expiry key fragment.
خط ۲۱۶: خط ۲۲۸:
namespaceFragment = 'talk'
namespaceFragment = 'talk'
end
end
 
-- Define the order that key fragments are tested in. This is done with an
-- Define the order that key fragments are tested in. This is done with an
-- array of tables containing the value to be tested, along with its
-- array of tables containing the value to be tested, along with its
خط ۳۲۴: خط ۳۳۶:
function Protection:isIncorrect()
function Protection:isIncorrect()
local expiry = self.expiry
local expiry = self.expiry
return not self:shouldHaveProtectionCategory()
return not self:isProtected()
or type(expiry) == 'number' and expiry < os.time()
or type(expiry) == 'number' and expiry < os.time()
end
end
خط ۳۳۹: خط ۳۵۱:
function Protection:makeCategoryLinks()
function Protection:makeCategoryLinks()
local msg = self._cfg.msg
local msg = self._cfg.msg
local ret = {self:makeProtectionCategory()}
local ret = { self:makeProtectionCategory() }
if self:isIncorrect() then
if self:isIncorrect() then
ret[#ret + 1] = makeCategoryLink(
ret[#ret + 1] = makeCategoryLink(
خط ۳۸۲: خط ۳۹۴:
function Blurb:_formatDate(num)
function Blurb:_formatDate(num)
-- Formats a Unix timestamp into dd Month, YYYY format.
-- Formats a Unix timestamp into dd Month, YYYY format.
lang = lang or mw.language.getContentLanguage()
-- در خط زیر جای mw.language.getContentLanguage() از mw.getLanguage('en') استفاده کردم.
lang = lang or mw.getLanguage('en')
local success, date = pcall(
local success, date = pcall(
lang.formatDate,
lang.formatDate,
lang,
lang,
self._cfg.msg['expiry-date-format'] or 'j F Y',
self._cfg.msg['expiry-date-format'] or 'xij xiF xiY', -- The 'xi' prefix is the prefix for displaying Iranian time
'@' .. tostring(num)
'@' .. replacePersianGreMonthName{converter('en', tostring(num))}
)
)
if success then
if success then
خط ۴۴۳: خط ۴۵۶:
-- We need the move log link.
-- We need the move log link.
return makeFullUrl(
return makeFullUrl(
'Special:Log',
'ویژه:سیاهه‌ها',
{type = 'move', page = pagename},
{type = 'move', page = pagename},
self:_getExpandedMessage('current-version-move-display')
self:_getExpandedMessage('current-version-move-display')
خط ۵۱۵: خط ۵۲۸:
msg = explanations[action].default.default
msg = explanations[action].default.default
else
else
error(string.format(
error(mw.ustring.format(
'could not find explanation blurb for action "%s", level "%s" and talk key "%s"',
'نمی‌توان explanation blurb را برای عمل «%s»، سطح «%s» و کلید بحث «%s» پیدا کرد',
action,
action,
level,
level,
خط ۵۴۲: خط ۵۵۵:
function Blurb:_makeIntroBlurbParameter()
function Blurb:_makeIntroBlurbParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-blurb-expiry')
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('intro-blurb-expiry')))
else
else
return self:_getExpandedMessage('intro-blurb-noexpiry')
return self:_getExpandedMessage('intro-blurb-noexpiry')
خط ۵۵۰: خط ۵۶۳:
function Blurb:_makeIntroFragmentParameter()
function Blurb:_makeIntroFragmentParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('intro-fragment-expiry')
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('intro-fragment-expiry')))
else
else
return self:_getExpandedMessage('intro-fragment-noexpiry')
return self:_getExpandedMessage('intro-fragment-noexpiry')
خط ۵۶۰: خط ۵۷۳:
return pagetypes[self._protectionObj.title.namespace]
return pagetypes[self._protectionObj.title.namespace]
or pagetypes.default
or pagetypes.default
or error('no default pagetype defined', 8)
or error('هیچ نوع صفحه پیش‌فرضی تعریف نشده‌است', 8)
end
end


خط ۵۷۵: خط ۵۸۸:
msg = protectionBlurbs.edit.default
msg = protectionBlurbs.edit.default
else
else
error('no protection blurb defined for protectionBlurbs.edit.default', 8)
error('هیچ blurb حفاظتی برای protectionBlurbs.edit.default تعریف نشده‌است', 8)
end
end
return self:_substituteParameters(msg)
return self:_substituteParameters(msg)
خط ۶۰۱: خط ۶۱۴:
msg = protectionLevels.edit.default
msg = protectionLevels.edit.default
else
else
error('no protection level defined for protectionLevels.edit.default', 8)
error('هیچ سطح حفاظتی برای protectionLevels.edit.default تعریف نشده‌است', 8)
end
end
return self:_substituteParameters(msg)
return self:_substituteParameters(msg)
خط ۶۱۱: خط ۶۲۴:
-- We need the pending changes log.
-- We need the pending changes log.
return makeFullUrl(
return makeFullUrl(
'Special:Log',
'ویژه:سیاهه‌ها',
{type = 'stable', page = pagename},
{type = 'stable', page = pagename},
self:_getExpandedMessage('pc-log-display')
self:_getExpandedMessage('pc-log-display')
خط ۶۱۸: خط ۶۳۱:
-- We need the protection log.
-- We need the protection log.
return makeFullUrl(
return makeFullUrl(
'Special:Log',
'ویژه:سیاهه‌ها',
{type = 'protect', page = pagename},
{type = 'protect', page = pagename},
self:_getExpandedMessage('protection-log-display')
self:_getExpandedMessage('protection-log-display')
خط ۶۲۶: خط ۶۳۹:


function Blurb:_makeTalkPageParameter()
function Blurb:_makeTalkPageParameter()
return string.format(
return mw.ustring.format(
'[[%s:%s#%s|%s]]',
'[[%s:%s#%s|%s]]',
mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
mw.site.namespaces[self._protectionObj.title.namespace].talk.name,
خط ۶۳۷: خط ۶۵۰:
function Blurb:_makeTooltipBlurbParameter()
function Blurb:_makeTooltipBlurbParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-blurb-expiry')
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-blurb-expiry')))
else
else
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
return self:_getExpandedMessage('tooltip-blurb-noexpiry')
خط ۶۴۵: خط ۶۵۸:
function Blurb:_makeTooltipFragmentParameter()
function Blurb:_makeTooltipFragmentParameter()
if self._protectionObj:isTemporary() then
if self._protectionObj:isTemporary() then
return self:_getExpandedMessage('tooltip-fragment-expiry')
return converter('fa', replacePersianMonthName(self:_getExpandedMessage('tooltip-fragment-expiry')))
else
else
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
return self:_getExpandedMessage('tooltip-fragment-noexpiry')
خط ۶۵۲: خط ۶۶۵:


function Blurb:_makeVandalTemplateParameter()
function Blurb:_makeVandalTemplateParameter()
return mw.getCurrentFrame():expandTemplate{
return require('Module:Vandal-m')._main{
title="vandal-m",
self._args.user or self._protectionObj.title.baseText
args={self._args.user or self._protectionObj.title.baseText}
}
}
end
end
خط ۶۶۳: خط ۶۷۵:
-- Validate input.
-- Validate input.
if not key or not Blurb.bannerTextFields[key] then
if not key or not Blurb.bannerTextFields[key] then
error(string.format(
error(mw.ustring.format(
'"%s" is not a valid banner config field',
'«%s» زمینه پیکربندی بنر معتبری نیست',
tostring(key)
tostring(key)
), 2)
), 2)
خط ۶۷۶: خط ۶۸۸:
msg = msg(self._protectionObj, self._args)
msg = msg(self._protectionObj, self._args)
if type(msg) ~= 'string' then
if type(msg) ~= 'string' then
error(string.format(
error(mw.ustring.format(
'bad output from banner config function with key "%s"'
'خروجی نامناسب از تابع پیکربندی بنر همراه کلید "%s"'
.. ' (expected string, got %s)',
.. ' (رشته انتظار می‌رود، %s داده شده‌است)',
tostring(key),
tostring(key),
type(msg)
type(msg)
خط ۷۷۱: خط ۷۸۳:
-- Renders the banner.
-- Renders the banner.
makeMessageBox = makeMessageBox or require('Module:Message box').main
makeMessageBox = makeMessageBox or require('Module:Message box').main
local reasonText = self._reasonText or error('no reason text set', 2)
local reasonText = self._reasonText or error('هیچ متن دلیلی تعیین نشده‌است', 2)
local explanationText = self._explanationText
local explanationText = self._explanationText
local mbargs = {
local mbargs = {
خط ۷۷۷: خط ۷۸۹:
type = 'protection',
type = 'protection',
image = self:renderImage(),
image = self:renderImage(),
text = string.format(
text = mw.ustring.format(
"'''%s'''%s",
"'''%s'''%s",
reasonText,
reasonText,
خط ۸۳۴: خط ۸۴۶:
function p._main(args, cfg, title)
function p._main(args, cfg, title)
args = args or {}
args = args or {}
-- local args
if args['کوچک'] then args.small = args['کوچک'] end
if args['عمل'] then args.action = args['عمل'] end
if args['تاریخ'] then args.date = args['تاریخ'] end
if args['کاربر'] then args.user = args['کاربر'] end
if args['بخش'] then args.section = args['بخش'] end
if args['رده'] then args.category = args['رده'] end
if args['فقط رده'] then args.catonly = args['فقط رده'] end
cfg = cfg or require(CONFIG_MODULE)
cfg = cfg or require(CONFIG_MODULE)


خط ۸۴۳: خط ۸۶۵:
-- protection from some other action, then don't bother displaying anything
-- protection from some other action, then don't bother displaying anything
-- for the other action (except categories).
-- for the other action (except categories).
if not yesno(args.catonly) and (protectionObj.action == 'edit' or
if protectionObj.action == 'edit' or
args.demolevel or
args.demolevel or
not getReachableNodes(
not getReachableNodes(
cfg.hierarchy,
cfg.hierarchy,
protectionObj.level
protectionObj.level
)[effectiveProtectionLevel('edit', protectionObj.title)])
)[effectiveProtectionLevel('edit', protectionObj.title)]
then
then
-- Initialise the blurb object
-- Initialise the blurb object
خط ۸۵۴: خط ۸۷۶:
-- Render the banner
-- Render the banner
if protectionObj:shouldShowLock() then
if protectionObj:isProtected() then
ret[#ret + 1] = tostring(
ret[#ret + 1] = tostring(
(yesno(args.small) and Padlock or Banner)
(yesno(args.small) and Padlock or Banner)
خط ۸۷۵: خط ۸۹۷:
-- Find default args, if any.
-- Find default args, if any.
local parent = frame.getParent and frame:getParent()
local parent = frame.getParent and frame:getParent()
local defaultArgs = parent and cfg.wrappers[parent:getTitle():gsub('/sandbox$', '')]
local defaultArgs = parent and cfg.wrappers[mw.ustring.gsub(parent:getTitle(), '/تمرین$', '')]


-- Find user args, and use the parent frame if we are being called from a
-- Find user args, and use the parent frame if we are being called from a