Functions to provide the Proofread of the Month aspects of {{PotM}} and {{Collaboration}}.

Add work data to Module:PotM/data.


-- This is an module to implement functions to do with the Proofread of the Month

local p = {} --p stands for package

-- Find the index of the first month that's either this month or the nearest
-- month in the past.
-- This allow to preload months in [[Module:PotM/data]] for auto-changeover
-- on the first of the month.
function get_month_index(data)
	local now = os.date("!*t")

	-- skip any months in the future
	local max_date_k = nil
	local max_date = 0

	for k, month_data in pairs(data) do
		local today_date = now["year"] * 100 + now["month"]
		local month_data_date = month_data["year"] * 100 + month_data["month"]
		if month_data_date <= today_date and month_data_date > max_date then
			max_date = month_data_date
			max_date_k = k
		end
	end
	if max_date_k ~= nil then
		return max_date_k
	end
	-- this should never happen unless all the data is removed
	error("Couldn't find a month in the past or present to start from")
end

-- the name of the next month (e.g. "March" if it is February now)
function get_next_month() 
	-- get today
	local date = os.date("!*t")
	-- add a month for next month
	date["month"] = (date['month'] + 1) % 12
	-- return the formatted month name
	return os.date("%B", os.time(date))
end

-- get the current index in this month. if not given we assume it's the first one
-- for historical months, the 'current' parameter would be the index of the
-- last active work that month
function get_current_work_index_in_month(month_data)
	
	local work_index = month_data["current"]
	if work_index == nil then
		work_index = 1
	end
	
	return work_index
end

-- infer an "option" from month data
function get_option(month_data)
	if month_data['overflow'] then
		-- if overflowed...
		return "overflow"
	elseif get_current_work_index_in_month(month_data) > 1 then
		-- or we haven't overflowed to "little works", but we have gotten to a second work
		return "extra"
	end
	
	return nil
end

function get_base_params(work, month_data)
	
	local file = work["image"]
	if file == nil then
		file = "Featured article star - check.svg"
	end
	
	local filesize = work["imagesize"]
	if filesize == nil then
		filesize = 75
	end	

	local base_args = {
		POTMindex = work["index"],
		POTMtitle = work["display"],
		POTMauthor = work["author"],
		POTMyear   = work["year"],
		option = get_option(month_data),
		POTMfile = file,
		POTMfilesize = filesize,
	}

	if string.match(work["author"], "%[%[Author:") then
		base_args["override_author"] = work["author"]
	else
		base_args["POTMauthor"] = work["author"]
	end	
	
	return base_args
end

--[=[
Call {{potm/base}} with parameters dug out of [[Module:PotM/data]]
]=]
function p.potm(frame)
	local data = mw.loadData('Module:PotM/data')
	
	local month_index = get_month_index(data)
	local curr_month = data[month_index]
	local curr_work_index = get_current_work_index_in_month(curr_month)

	-- this is the active work
	local curr_work = curr_month["works"][curr_work_index]

	-- the previous work is either the previous work in THIS month, or the final work
	-- in the LAST month
	local last_work
	if curr_work_index > 1 then
		last_work = curr_month["works"][curr_work_index - 1]
	else
		local last_month = data[month_index + 1]
		local last_month_index = get_current_work_index_in_month(last_month)
		last_work = last_month["works"][last_month_index]
	end

	local base_args = get_base_params(curr_work, curr_month)
	base_args["lastindex"] = last_work["index"]
	base_args["lasttitle"] = last_work["display"]
	base_args["nextmonth"] = get_next_month()

	return frame:expandTemplate{ title = 'PotM/base', args = base_args }
end

-- get the most recent "limit" works
function get_recents(data, limit, first_month)

	local recents = {}
	local skip = 1 -- ignore the first one, that's the current work
	
	-- iterate months
	for k, month in pairs(data) do
		local broken = false
		if k >= first_month then
			
			-- don't read past the "current" work in a month
			local last_idx = get_current_work_index_in_month(month)
	
			for i=last_idx, 1, -1 do
				
				local work = month["works"][i]
	
				if skip == 0 then
					table.insert(recents, work)
				else
					skip = skip - 1
				end
				
				if (#recents == limit) then
					broken = true
					break
				end
			end
		end
		
		if broken then
			break
		end
	end
	
	return recents
end

-- format an index link
function index_link(index, display)
	return "[[Index:" .. index .. "|" .. display .. "]]"
end

-- format a list of recent works
function format_recents(data, limit, first_month)
	local recents = get_recents(data, limit, first_month)
	
	local formatted = {}
	
    for k, work in pairs(recents) do
        formatted[k] = index_link(work["index"], work["display"])
    end
    return table.concat(formatted, ", ")
end

--[=[
Call {{collaboration/POTM}} with parameters dug out of [[Module:PotM/data]]
]=]
function p.collaboration_potm(frame)
	local data = mw.loadData('Module:PotM/data')
	
	local month_index = get_month_index(data)
	local curr_month = data[month_index]
	local curr_work_index = get_current_work_index_in_month(curr_month)
	local curr_work = curr_month["works"][curr_work_index]
	
	local num_recents = 10
	local base_args = get_base_params(curr_work, curr_month)

	base_args["POTMrecent"] = format_recents(data, num_recents, month_index)

	if string.match(curr_work["author"], "%[%[") then
		base_args["override_author"] = curr_work["author"]
	else
		base_args["POTMauthor"] = curr_work["author"]
	end
	
	return frame:expandTemplate{ title = 'Collaboration/POTM', args = base_args }
end

return p