local makePurgeLink = require('Module:Purge')._mainlocal lang = mw.language.getContentLanguagelocal CONFIG_MODULE = 'Module:Progress box/config'
--------------------------------------------------------------------------------- Message mixin-- -- This function is mixed into all of the other classes-------------------------------------------------------------------------------
local function message(self, key, ...) local msg = self._cfg[key] if not msg then error(string.format("no message found with key '%s'", tostring(key)), 2) end if select('#', ...) > 0 then return mw.message.newRawMessage(msg, ...):plain else return msg endend
--------------------------------------------------------------------------------- Category class-------------------------------------------------------------------------------
local Category = Category.__index = CategoryCategory.message = message
function Category.new(data) local self = setmetatable(Category) self._cfg = data.cfg self._whatToCount = data.whatToCount self:setCategory(data.category) return selfend
function Category:setCategory(category) self._category = categoryend
function Category:getCategory return self._categoryend
function Category:makeCategoryLink(display) local cat = self:getCategory display = display or cat return string.format('%s', cat, display)end
function Category:getCount if not self._count then local counts = mw.site.stats.pagesInCategory(self:getCategory, '*') self._count = counts[self._whatToCount or 'pages'] if not self._count then error("the count type must be one of 'pages', 'subcats', 'files' or 'all'") end end return self._countend
function Category:getFormattedCount return lang:formatNum(self:getCount)end
function Category:exists return mw.title.makeTitle(14, self:getCategory).existsend
--------------------------------------------------------------------------------- DatedCategory class-- Inherits from Category-------------------------------------------------------------------------------
local DatedCategory = DatedCategory.__index = DatedCategorysetmetatable(DatedCategory, Category)
function DatedCategory.new(data) local self = setmetatable(Category.new(data),) self._date = data.date self._dateFormat = data.dateFormat or self:message('date-format') self._formattedDate = self:formatDate(self._date) do local category = self:message('dated-category-format', data.baseCategory, self._formattedDate, data.from or self:message('dated-category-format-from'), data.suffix or ) category = category:match('^%s*(.-)%s*$') -- trim whitespace self:setCategory(category) end return selfend
function DatedCategory:formatDate(date) return lang:formatDate(self._dateFormat, date)end
function DatedCategory:getDate return self._dateend
function DatedCategory:getFormattedDate return self._formattedDateend
--------------------------------------------------------------------------------- ProgressBox class-------------------------------------------------------------------------------
local ProgressBox = ProgressBox.__index = ProgressBoxProgressBox.message = message
function ProgressBox.new(args, cfg, title) local self = setmetatable(ProgressBox)
-- Argument defaults args = args or self._cfg = cfg or mw.loadData(CONFIG_MODULE) self._title = title or mw.title.getCurrentTitle
-- Set data if not args.float or (args.float and (args.float
)) then self._float_class = 'maint-cat-progress-left' elseif args.float
'none' then -- 'none' is actually 'center'ed self._float_class = 'maint-cat-progress-center' end self._header = args[1] self._frame = mw.getCurrentFrame
-- Make the base category object if not args[1] then error('no base category specified', 3) end self._baseCategoryObj = Category.new
-- Make datedCategory objects self._datedCategories = do local cfg = self._cfg local baseCategory = args[2] or self._baseCategoryObj:getCategory local whatToCount = args.count local from = args.from or self:message('dated-category-format-from') local suffix = args.suffix local currentDate = lang:formatDate('Y-m') local date = self:findEarliestCategoryDate local dateFormat = self:message('date-format') while date <= currentDate do local datedCategoryObj = DatedCategory.new if datedCategoryObj:getCount > 0 then table.insert(self._datedCategories, datedCategoryObj) end date = ProgressBox.incrementDate(date) end end
-- Make all-article category object do local allCategory if args[3] then allCategory = args[3] else allCategory = self:message('all-articles-category-format', self._baseCategoryObj:getCategory ) allCategory = self._frame:preprocess(allCategory) end self._allCategoryObj = Category.new end
return selfend
-- Increments a date in the format YYYY-MMfunction ProgressBox.incrementDate(date) local year, month = date:match('^(%d%d%d%d)%-(%d%d)$') year = tonumber(year) month = tonumber(month) if not year or not month then error(string.format("error parsing date '%s'", tostring(date)), 2) end month = month + 1 if month > 12 then month = 1 year = year + 1 end return string.format('%04d-%02d', year, month)end
function ProgressBox:findEarliestCategoryDate return self:message('start-date')end
function ProgressBox:isCollapsed return self._title.namespace ~= 10 -- is not in template namespaceend
function ProgressBox:makeTotalLabel local display = self:message('all-articles-label') if self._allCategoryObj:exists then return self._allCategoryObj:makeCategoryLink(display) else return display endend
function ProgressBox:getTotalCount local count = 0 for i, obj in ipairs(self._datedCategories) do count = count + obj:getCount end count = count + self._baseCategoryObj:getCount return countend
function ProgressBox:getFormattedTotalCount return lang:formatNum(self:getTotalCount)end
function ProgressBox:__tostring data = data or local root = mw.html.create('div') -- Base classes and styles root :addClass('maint-cat-progress') :addClass(self._float_class)
-- Header row root:tag('div') :addClass('maint-cat-progress-header') :wikitext(self._header)
-- Refresh row root:tag('div') :addClass('maint-cat-progress-refresh') :wikitext(makePurgeLink)
-- Subtotals local subtotalTable = mw.html.create('table') subtotalTable :addClass('maint-cat-progress-subtotals mw-collapsible') :addClass(self:isCollapsed and 'mw-collapsed' or nil) :tag('caption') :wikitext(self:message('subtotal-heading')) for i, datedCategoryObj in ipairs(self._datedCategories) do subtotalTable :tag('tr') :tag('td') :wikitext(datedCategoryObj:makeCategoryLink(datedCategoryObj:getFormattedDate )) :done :tag('td') :wikitext(datedCategoryObj:getFormattedCount) end
-- Undated articles subtotalTable :tag('tr') :tag('td') :wikitext(self._baseCategoryObj:makeCategoryLink(self:message('undated-articles-label') )) :done :tag('td') :wikitext(self._baseCategoryObj:getFormattedCount) :allDone
-- Total root :node(subtotalTable) :tag('div') :addClass('maint-cat-progress-total-row') :tag('div') :addClass('maint-cat-progress-total-label') :wikitext(self:makeTotalLabel) :done :tag('div') :addClass('maint-cat-progress-total') :wikitext(self:getFormattedTotalCount)
return mw.getCurrentFrame:extensionTag .. tostring(root)end
--------------------------------------------------------------------------------- Exports-------------------------------------------------------------------------------
local p =
function p._exportClasses return end
function p._main(args, cfg, title) return tostring(ProgressBox.new(args, cfg, title))end
function p.main(frame) local args = require('Module:Arguments').getArgs(frame,) return p._main(args)end
return p