changeset 3750:9002c8a2165f

mod_http_muc_log: Refactor calendarization of date list into a template filter BC This breaks any custom templates using the calendar data structure.
author Kim Alvefur <zash@zash.se>
date Sun, 17 Nov 2019 15:16:23 +0100
parents cb61f0e06de3
children cb9517827d76
files mod_http_muc_log/http_muc_log.html mod_http_muc_log/mod_http_muc_log.lua
diffstat 2 files changed, 56 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/mod_http_muc_log/http_muc_log.html	Sun Nov 17 15:13:35 2019 +0100
+++ b/mod_http_muc_log/http_muc_log.html	Sun Nov 17 15:16:23 2019 +0100
@@ -70,7 +70,7 @@
 <dt {item.lang&lang="{item.lang}"} class="name"><a href="{item.href}{hide_presence&?p=h}">{item.name}</a></dt>
 <dd {item.lang&lang="{item.lang}"} class="description">{item.description?}</dd>}
 </dl>
-{years#
+{dates|calendarize#
 <h2 id="{item.year}">{item.year}</h2>
 {item.months#
 <table id="{item.month}-{item.year}">
--- a/mod_http_muc_log/mod_http_muc_log.lua	Sun Nov 17 15:13:35 2019 +0100
+++ b/mod_http_muc_log/mod_http_muc_log.lua	Sun Nov 17 15:16:23 2019 +0100
@@ -6,7 +6,8 @@
 local url = require"socket.url";
 local os_time, os_date = os.time, os.date;
 local httplib = require "util.http";
-local render = require"util.interpolation".new("%b{}", require"util.stanza".xml_escape);
+local render_funcs = {};
+local render = require"util.interpolation".new("%b{}", require"util.stanza".xml_escape, render_funcs);
 
 local archive = module:open_store("muc_log", "archive");
 
@@ -147,58 +148,54 @@
 	return false;
 end
 
--- Produce the calendar view
-local function years_page(event, path)
-	local request, response = event.request, event.response;
-
-	local room = nodeprep(path:match("^(.*)/$"));
-	local is_open = open_room(room);
-	if is_open == nil then
-		return -- implicit 404
-	elseif is_open == false then
-		return 403;
+local function get_dates(room) --> { integer, ... }
+	local date_list = archive.dates and archive:dates(room);
+	if date_list then
+		for i = 1, #date_list do
+			date_list[i] = datetime.parse(date_list[i].."T00:00:00Z");
+		end
+		return date_list;
 	end
 
-	-- Collect each date that has messages
-	-- convert it to a year / month / day tree
-	local date_list = archive.dates and archive:dates(room);
-	local dates = mt.new();
-	if date_list then
-		for _, date in ipairs(date_list) do
-			local when = datetime.parse(date.."T00:00:00Z");
-			local t = os_date("!*t", when);
-			dates:set(t.year, t.month, t.day, when);
-		end
-	elseif lazy then
+	if lazy then
 		-- Lazy with many false positives
+		date_list = {};
 		local first_day = find_once(room, nil, 3);
 		local last_day = find_once(room, { reverse = true }, 3);
 		if first_day and last_day then
 			first_day = date_floor(first_day);
 			last_day = date_floor(last_day);
 			for when = first_day, last_day, 86400 do
-				local t = os_date("!*t", when);
-				dates:set(t.year, t.month, t.day, when);
+				table.insert(date_list, when);
 			end
 		else
 			return; -- 404
 		end
-	else
-		-- Collect date the hard way
-		module:log("debug", "Find all dates with messages");
-		local next_day;
-		repeat
-			local when = find_once(room, { start = next_day; }, 3);
-			if not when then break; end
-			local t = os_date("!*t", when);
-			dates:set(t.year, t.month, t.day, when );
-			next_day = date_floor(when) + 86400;
-		until not next_day;
+		return date_list;
 	end
 
-	local years = {};
+	-- Collect date the hard way
+	module:log("debug", "Find all dates with messages");
+	date_list = {};
+	local next_day;
+	repeat
+		local when = find_once(room, { start = next_day; }, 3);
+		if not when then break; end
+		table.insert(date_list, when);
+		next_day = date_floor(when) + 86400;
+	until not next_day;
+	return date_list;
+end
 
+function render_funcs.calendarize(date_list)
+	-- convert array of timestamps to a year / month / day tree
+	local dates = mt.new();
+	for _, when in ipairs(date_list) do
+		local t = os_date("!*t", when);
+		dates:set(t.year, t.month, t.day, when);
+	end
 	-- Wrangle Y/m/d tree into year / month / week / day tree for calendar view
+	local years = {};
 	for current_year, months_t in pairs(dates.data) do
 		local t = { year = current_year, month = 1, day = 1 };
 		local months = { };
@@ -235,6 +232,25 @@
 		table.sort(months, sort_m);
 	end
 	table.sort(years, sort_Y);
+	return years;
+end
+
+-- Produce the calendar view
+local function years_page(event, path)
+	local request, response = event.request, event.response;
+
+	local room = nodeprep(path:match("^(.*)/$"));
+	local is_open = open_room(room);
+	if is_open == nil then
+		return -- implicit 404
+	elseif is_open == false then
+		return 403;
+	end
+
+	local date_list = get_dates(room);
+	if not date_list then
+		return; -- 404
+	end
 
 	-- Phew, all wrangled, all that's left is rendering it with the template
 
@@ -245,7 +261,7 @@
 		jid_node = jid_split(get_room(room).jid);
 		hide_presence = hide_presence(request);
 		presence_available = presence_logged;
-		years = years;
+		dates = date_list;
 		links = {
 			{ href = "../", rel = "up", text = "Room list" },
 			{ href = "latest", rel = "last", text = "Latest" },
@@ -385,6 +401,7 @@
 		lang = get_room(room).get_language and get_room(room):get_language();
 		lines = logs;
 		links = links;
+		dates = {}; -- COMPAT util.interpolation {nil|func#...} bug
 	});
 end
 
@@ -414,6 +431,7 @@
 		hide_presence = hide_presence(request);
 		presence_available = presence_logged;
 		rooms = room_list;
+		dates = {}; -- COMPAT util.interpolation {nil|func#...} bug
 	});
 end