Mô đun:Status

-- This module implements

-- Initialise necessary modules
local Object = require('Module:Classic')
local CountVotes = require('Module:CountVotes')._main
local yesno = require('Module:Yesno')

-- Lazily initialise modules and objects we don't always need
local lang

-- Set constants
local CONFIG_MODULE = 'Module:Status/config'
local LINE_FEED = '&010;'

--------------------------------------------------------------------------------
-- Helper class
--------------------------------------------------------------------------------

local Helper = Object:extend()

function Helper:validateDate(dateString)
lang = lang or mw.language.getContentLanguage()
local success, result = pcall(lang.formatDate, lang, 'U', dateString)
if success then
result = tonumber(result)
if result then
return true
end
end
error(string.format('ngày tháng không hợp lệ: %s', tostring(dateString)))
end

function Helper:isUnixTime(dateString)
local success, result = pcall(os.date, '!%Y-%m-%dT%TZ', dateString)
if success then
return true
end
return false
end

function Helper:formatDate(dateString, format)
lang = lang or mw.language.getContentLanguage()
if Helper:isUnixTime(dateString) then
if format == 'U' then
return dateString
end
return lang:formatDate(format, os.date('!%Y-%m-%dT%TZ', dateString))
end
if Helper:validateDate(dateString) then
return lang:formatDate(format, dateString)
end
end

function Helper:substParams(msg, params)
return msg:gsub('${(%u+)}', params)
end

function Helper:dayToSecond(dayNumber)
return tonumber(dayNumber) 24 3600
end

function Helper:breakLines(title)
return title:gsub('%. ', '. ' .. LINE_FEED) -- Phải dùng bản mẫu trung gian để escape
end

function Helper:countdown(duration)
return string.format(
'%s ngày %s giờ %s phút %s giây',
duration.days or 0,
duration.hours or 0,
duration.minutes or 0,
duration.seconds or 0
)
end

function Helper:votesNumberTitle(positiveVotesNumber, negativeVotesNumber)
return string.format(
' ' .. LINE_FEED .. 'Số phiếu thuận là %s. '
.. LINE_FEED .. 'Số phiếu chống là %s.',
positiveVotesNumber,
negativeVotesNumber
)
end

--------------------------------------------------------------------------------
-- Status class
--------------------------------------------------------------------------------

local Status = Object:extend()

function Status:new(...)
local args, cfg = unpack({...})

-- Set cfg
self.cfg = cfg

-- Set startTime
if args[1] then args.start = args[1] end -- Tương thích ngược phiên bản cũ
if args.start and mw.text.trim(args.start) ~= then
self.startTime = tonumber(Helper:formatDate(args.start, 'U'))
else
error('phải có tham số start và start không được rỗng')
end

-- Set maxTime
self.maxTime = self:_getMaxTime(...)
end

function Status:_getMaxTime(...)
local args, cfg, title = unpack({...})
if args[2] then args.max = args[2] end -- Tương thích ngược phiên bản cũ
if title then
return self.startTime + Helper:dayToSecond(tonumber(args.max)
or (cfg.rootTitles[title.rootText] or {}).max or cfg.DEFAULT_MAX)
end
return self.startTime + Helper:dayToSecond(tonumber(args.max) or cfg.DEFAULT_MAX)
end

function Status:_getMinTime(...)
local _, cfg, title = unpack({...})
return self.startTime + Helper:dayToSecond((cfg.rootTitles[title.rootText] or {}).min or cfg.DEFAULT_MIN)
end

function Status:_getConsiderExtensionTime(...)
local _, cfg, title = unpack({...})
return self.startTime + Helper:dayToSecond((cfg.rootTitles[title.rootText] or {}).considerExtension
or cfg.DEFAULT_CONSIDER_EXTENSION)
end

function Status:_getExtendedTime(...)
local _, cfg, title = unpack({...})
return self.startTime + Helper:dayToSecond((cfg.rootTitles[title.rootText] or {}).extended
or cfg.DEFAULT_EXTENDED)
end

function Status:_getInfo()
local statusName, titleIndex
local now = os.time()

if now self.extendedTime and self.extend then
statusName, titleIndex = 'INVALID', 3
else
statusName, titleIndex = 'INVALID', 1
end

return statusName, titleIndex
end

--------------------------------------------------------------------------------
-- StatusWithMinTimeAndExtendedTime class extends Status class
--------------------------------------------------------------------------------

local StatusWithMinTimeAndExtendedTime = Status:extend()

function StatusWithMinTimeAndExtendedTime:new(...)
StatusWithMinTimeAndExtendedTime.super.new(self, ...)
local args, cfg, title = unpack({...})

-- Set minTime
self.minTime = self:_getMinTime(...)

-- Set considerExtensionTime
self.considerExtensionTime = self:_getConsiderExtensionTime(...)

-- Set extendedTime
self.extendedTime = self:_getExtendedTime(...)

-- Set positiveVotesNumber & negativeVotesNumber
self.positiveVotesNumber, self.negativeVotesNumber = CountVotes(title)

-- Set checkSuccessConclusionFunc
self.checkSuccessConclusionFunc = (cfg.rootTitles[title.rootText] or {}).checkSuccessConclusionFunc

-- Set checkValidExtensionFunc
self.checkValidExtensionFunc = (cfg.rootTitles[title.rootText] or {}).checkValidExtensionFunc

-- Set extend
self.extend = yesno(args.extend) or false
end

function StatusWithMinTimeAndExtendedTime:_getInfo()
local statusName, titleIndex
local now = os.time()

statusName, titleIndex = 'VALID', 1

if now self.extendedTime and self.extend then
statusName, titleIndex = 'INVALID', 3
else
statusName, titleIndex = 'INVALID', 2
end

return statusName, titleIndex
end

--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------

local p = {}

function p._exportClasses()
-- This is used for testing purposes.
return {
Status = Status,
StatusWithMinTime = StatusWithMinTime,
StatusWithExtendedTime = StatusWithExtendedTime,
StatusWithMinTimeAndExtendedTime = StatusWithMinTimeAndExtendedTime,
}
end

function p._main(args, cfg)
args = args or {}
cfg = cfg or require(CONFIG_MODULE)

local statusObj = {}

if args.id then
if mw.text.trim(args.id) ~= then
local title = {}
if tonumber(args.id) then
title = mw.title.new(tonumber(args.id))
else
title = mw.title.new(args.id)
end
local group = (cfg.rootTitles[title.rootText] or {}).group

if group == 1 then
statusObj = StatusWithMinTime(args, cfg, title)
elseif group == 2 then
statusObj = StatusWithExtendedTime(args, cfg, title)
elseif group == 3 then
statusObj = StatusWithMinTimeAndExtendedTime(args, cfg, title)
else
error('khu vực không được hỗ trợ')
end
else
error('id không được rỗng')
end
else
statusObj = Status(args, cfg)
end

return statusObj:getValues()
end

function p.main(frame)
local args = frame:getParent().args
local cfg = require(CONFIG_MODULE)
return frame:expandTemplate{title = 'Status/core', args = p._main(args, cfg)}
end

return p