মডিউল:Rfx/খেলাঘর
অবয়ব
এটি মডিউল:Rfx-এর জন্য মডিউল খেলাঘর পাতা (পার্থক্য)। |
----------------------------------------------------------------------
-- Module:Rfx --
-- This is a library for retrieving information about requests --
-- for adminship and requests for bureaucratship on the English --
-- Wikipedia. Please see the module documentation for instructions. --
----------------------------------------------------------------------
local libraryUtil = require('libraryUtil')
local date_names = require('মডিউল:উদ্ধৃতি/রূপরেখা').date_names
local lang = mw.getContentLanguage()
local enlang = mw.language.new('en')
local textSplit = mw.text.split
local umatch = mw.ustring.match
local newTitle = mw.title.new
local rfx = {}
--------------------------------------
-- Helper functions --
--------------------------------------
local function getTitleObject(title)
local success, titleObject = pcall(newTitle, title)
if success and titleObject then
return titleObject
else
return nil
end
end
local function parseVoteBoundaries(section)
-- Returns an array containing the raw wikitext of RfX votes in a given section.
section = section:match('^.-\n#(.*)$') -- Strip non-votes from the start.
if not section then
return {}
end
section = section:match('^(.-)\n[^#]') or section -- Discard subsequent numbered lists.
local comments = textSplit(section, '\n#')
local votes = {}
for i, comment in ipairs(comments) do
if comment:find('^[^#*;:].*%S') then
votes[#votes + 1] = comment
end
end
return votes
end
local function parseVote(vote)
-- parses a username from an RfX vote.
local userStart, userMatch = vote:match('^(.*)%[%[[%s_]*:?[%s_]*[uU][sS][eE][rR][%s_]*:[%s_]*(.-)[%s_]*%]%].-$')
local talkStart, talkMatch = vote:match('^(.*)%[%[[%s_]*:?[%s_]*[uU][sS][eE][rR][%s_]+[tT][aA][lL][kK][%s_]*:[%s_]*(.-)[%s_]*%]%].-$')
local contribStart, contribMatch = vote:match('^(.*)%[%[[%s_]*:?[%s_]*[sS][pP][eE][cC][iI][aA][lL][%s_]*:[%s_]*[cC][oO][nN][tT][rR][iI][bB][uU][tT][iI][oO][nN][sS]/[%s_]*(.-)[%s_]*%]%].-$')
local username
if userStart and talkStart then
if #userStart > #talkStart then
username = userMatch
else
username = talkMatch
end
elseif userStart then
username = userMatch
elseif talkStart then
username = talkMatch
elseif contribStart then
username = contribMatch
else
return string.format( "'''Error parsing signature''': ''%s''", vote )
end
username = username:match('^[^|/#]*')
return username
end
local function parseVoters(votes)
local voters = {}
for i, vote in ipairs(votes) do
voters[#voters + 1] = parseVote(vote)
end
return voters
end
local function dupesExist(...)
local exists = {}
local tables = {...}
for i, usernames in ipairs(tables) do
for j, username in ipairs(usernames) do
username = lang:ucfirst(username)
if exists[username] then
return true
else
exists[username] = true
end
end
end
return false
end
------------------------------------------
-- Define the constructor function --
------------------------------------------
function rfx.new(title)
local obj = {}
local data = {}
local checkSelf = libraryUtil.makeCheckSelfFunction( 'Module:Rfx', 'rfx', obj, 'rfx object' )
-- Get the title object and check to see whether we are a subpage of WP:RFA or WP:RFB.
title = getTitleObject(title)
if not title then
return nil
end
function data:getTitleObject()
checkSelf(self, 'getTitleObject')
return title
end
if title.namespace == 4 then
local rootText = title.rootText
if rootText == 'প্রশাসক হওয়ার আবেদন' then
data.type = 'rfa'
elseif rootText == 'Requests for bureaucratship' then
data.type = 'rfb'
else
return nil
end
else
return nil
end
-- Get the page content and divide it into sections.
local pageText = title:getContent()
if not pageText then
return nil
end
local introText, supportText, opposeText, neutralText = umatch(
pageText,
'^.-\n===[^=\n][^\n]-===(.-)'
.. '\n====%s*মনোনয়ন%s*====.-'
.. '\n====%s*সমর্থন%s*====(.-)'
.. '\n====%s*বিরোধিতা%s*====(.-)'
.. '\n====%s*নিরপেক্ষ%s*===(.-)$'
)
if not introText then
introText, supportText, opposeText, neutralText = umatch(
pageText,
"^(.-\n'''[^\n]-%(%d+/%d+/%d+%)[^\n]-''')\n.-"
.. "\n'''Support'''(.-)\n'''Oppose'''(.-)\n'''Neutral'''(.-)"
)
end
-- Get vote counts.
local supportVotes, opposeVotes, neutralVotes
if supportText and opposeText and neutralText then
supportVotes = parseVoteBoundaries(supportText)
opposeVotes = parseVoteBoundaries(opposeText)
neutralVotes = parseVoteBoundaries(neutralText)
end
local supports, opposes, neutrals
if supportVotes and opposeVotes and neutralVotes then
supports = #supportVotes
data.supports = supports
opposes = #opposeVotes
data.opposes = opposes
neutrals = #neutralVotes
data.neutrals = neutrals
end
-- Voter methods and dupe check.
function data:getSupportUsers()
checkSelf(self, 'getSupportUsers')
if supportVotes then
return parseVoters(supportVotes)
else
return nil
end
end
function data:getOpposeUsers()
checkSelf(self, 'getOpposeUsers')
if opposeVotes then
return parseVoters(opposeVotes)
else
return nil
end
end
function data:getNeutralUsers()
checkSelf(self, 'getNeutralUsers')
if neutralVotes then
return parseVoters(neutralVotes)
else
return nil
end
end
function data:dupesExist()
checkSelf(self, 'dupesExist')
local supportUsers = self:getSupportUsers()
local opposeUsers = self:getOpposeUsers()
local neutralUsers = self:getNeutralUsers()
if not (supportUsers and opposeUsers and neutralUsers) then
return nil
end
return dupesExist(supportUsers, opposeUsers, neutralUsers)
end
if supports and opposes then
local total = supports + opposes
if total <= 0 then
data.percent = 0
else
data.percent = math.floor((supports / total * 100) + 0.5)
end
end
if introText then
local hours, minutes, days, bnMonth, year = umatch(introText, '([০১২৩৪৫৬৭৮৯][০১২৩৪৫৬৭৮৯]):([০১২৩৪৫৬৭৮৯][০১২৩৪৫৬৭৮৯]) ([০১২৩৪৫৬৭৮৯]+) (.-) ([০১২৩৪৫৬৭৮৯]+) %(ইউটিসি%)')
local monthNumber = date_names['local']['long'][bnMonth]
data.endTime = lang:parseFormattedNumber(year) .. '-' .. monthNumber .. '-' .. lang:parseFormattedNumber(days) .. ' ' .. lang:parseFormattedNumber(hours) .. ':' .. lang:parseFormattedNumber(minutes)
data.user = umatch(introText, '===%s*%[%[[_%s]*ব্যবহারকারী:.-|[_%s]*(.-)[_%s]*%]%][_%s]*===') or umatch(introText, '===%s*([^\n]-)%s*===')
end
-- Methods for seconds left and time left.
function data:getSecondsLeft()
checkSelf(self, 'getSecondsLeft')
local endTime = self.endTime
if not endTime then
return nil
end
local now = tonumber(enlang:formatDate("U"))
local success, endTimeU = pcall(enlang.formatDate, enlang, 'U', endTime, true)
if not success then
return nil
end
endTimeU = tonumber(endTimeU)
if not endTimeU then
return nil
end
local secondsLeft = endTimeU - now
if secondsLeft <= 0 then
return 0
else
return secondsLeft
end
end
function data:getTimeLeft()
checkSelf(self, 'getTimeLeft')
local secondsLeft = self:getSecondsLeft()
if not secondsLeft then
return nil
end
return mw.ustring.gsub(lang:formatDuration(secondsLeft, {'days', 'hours'}), ' and', ',')
end
function data:getStatus()
-- Gets the current status of the RfX. Returns either "successful", "unsuccessful",
-- "discussion", "open", or "pending closure". Returns nil if the status could not be found.
checkSelf( self, 'getStatus' )
local rfxType = data.type
if rfxType == 'rfa' then
if umatch(
pageText,
'%[%[[%s_]*বিষয়শ্রেণী[%s_]*:[%s_]*উইকিপিডিয়া প্রশাসক হওয়ার সফল আবেদন(.-)[%s_]*%]%]'
) then
return 'সফল'
elseif umatch(
pageText,
'%[%[[%s_]*বিষয়শ্রেণী[%s_]*:[%s_]*উইকিপিডিয়া প্রশাসক হওয়ার ব্যর্থ আবেদন(.-)[%s_]*%]%]'
) then
return 'ব্যর্থ'
end
elseif rfxType == 'rfb' then
if umatch(
pageText,
'%[%[[%s_]*[cC][aA][tT][eE][gG][oO][rR][yY][%s_]*:[%s_]*[sS]uccessful requests for bureaucratship(.-)[%s_]*%]%]'
) then
return 'successful'
elseif umatch(
pageText,
'%[%[[%s_]*[cC][aA][tT][eE][gG][oO][rR][yY][%s_]*:[%s_]*[uU]nsuccessful requests for bureaucratship(.-)[%s_]*%]%]'
) then
return 'unsuccessful'
end
end
local secondsLeft = self:getSecondsLeft()
if secondsLeft and secondsLeft > 0 then
return 'খোলা'
elseif secondsLeft and secondsLeft <= 0 then
return ' বন্ধের জন্য অপেক্ষমান'
else
return nil
end
end
-- Specify which fields are read-only, and prepare the metatable.
local readOnlyFields = {
getTitleObject = true,
['type'] = true,
getSupportUsers = true,
getOpposeUsers = true,
getNeutralUsers = true,
supports = true,
opposes = true,
neutrals = true,
endTime = true,
percent = true,
user = true,
dupesExist = true,
getSecondsLeft = true,
getTimeLeft = true,
getReport = false,
getStatus = true
}
local function pairsfunc( t, k )
local v
repeat
k = next( readOnlyFields, k )
if k == nil then
return nil
end
v = t[k]
until v ~= nil
return k, v
end
return setmetatable( obj, {
__pairs = function ( t )
return pairsfunc, t, nil
end,
__index = data,
__newindex = function( t, key, value )
if readOnlyFields[ key ] then
error( 'index "' .. key .. '" is read-only', 2 )
else
rawset( t, key, value )
end
end,
__tostring = function( t )
return t:getTitleObject().prefixedText
end
} )
end
return rfx