Mercurial > prosody-modules
comparison mod_http_muc_log/mod_http_muc_log.lua @ 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 | 971417eedfee |
comparison
equal
deleted
inserted
replaced
3749:cb61f0e06de3 | 3750:9002c8a2165f |
---|---|
4 local nodeprep = require"util.encodings".stringprep.nodeprep; | 4 local nodeprep = require"util.encodings".stringprep.nodeprep; |
5 local it = require"util.iterators"; | 5 local it = require"util.iterators"; |
6 local url = require"socket.url"; | 6 local url = require"socket.url"; |
7 local os_time, os_date = os.time, os.date; | 7 local os_time, os_date = os.time, os.date; |
8 local httplib = require "util.http"; | 8 local httplib = require "util.http"; |
9 local render = require"util.interpolation".new("%b{}", require"util.stanza".xml_escape); | 9 local render_funcs = {}; |
10 local render = require"util.interpolation".new("%b{}", require"util.stanza".xml_escape, render_funcs); | |
10 | 11 |
11 local archive = module:open_store("muc_log", "archive"); | 12 local archive = module:open_store("muc_log", "archive"); |
12 | 13 |
13 -- Support both old and new MUC code | 14 -- Support both old and new MUC code |
14 local mod_muc = module:depends"muc"; | 15 local mod_muc = module:depends"muc"; |
145 end | 146 end |
146 end | 147 end |
147 return false; | 148 return false; |
148 end | 149 end |
149 | 150 |
150 -- Produce the calendar view | 151 local function get_dates(room) --> { integer, ... } |
151 local function years_page(event, path) | |
152 local request, response = event.request, event.response; | |
153 | |
154 local room = nodeprep(path:match("^(.*)/$")); | |
155 local is_open = open_room(room); | |
156 if is_open == nil then | |
157 return -- implicit 404 | |
158 elseif is_open == false then | |
159 return 403; | |
160 end | |
161 | |
162 -- Collect each date that has messages | |
163 -- convert it to a year / month / day tree | |
164 local date_list = archive.dates and archive:dates(room); | 152 local date_list = archive.dates and archive:dates(room); |
165 local dates = mt.new(); | |
166 if date_list then | 153 if date_list then |
167 for _, date in ipairs(date_list) do | 154 for i = 1, #date_list do |
168 local when = datetime.parse(date.."T00:00:00Z"); | 155 date_list[i] = datetime.parse(date_list[i].."T00:00:00Z"); |
169 local t = os_date("!*t", when); | 156 end |
170 dates:set(t.year, t.month, t.day, when); | 157 return date_list; |
171 end | 158 end |
172 elseif lazy then | 159 |
160 if lazy then | |
173 -- Lazy with many false positives | 161 -- Lazy with many false positives |
162 date_list = {}; | |
174 local first_day = find_once(room, nil, 3); | 163 local first_day = find_once(room, nil, 3); |
175 local last_day = find_once(room, { reverse = true }, 3); | 164 local last_day = find_once(room, { reverse = true }, 3); |
176 if first_day and last_day then | 165 if first_day and last_day then |
177 first_day = date_floor(first_day); | 166 first_day = date_floor(first_day); |
178 last_day = date_floor(last_day); | 167 last_day = date_floor(last_day); |
179 for when = first_day, last_day, 86400 do | 168 for when = first_day, last_day, 86400 do |
180 local t = os_date("!*t", when); | 169 table.insert(date_list, when); |
181 dates:set(t.year, t.month, t.day, when); | |
182 end | 170 end |
183 else | 171 else |
184 return; -- 404 | 172 return; -- 404 |
185 end | 173 end |
186 else | 174 return date_list; |
187 -- Collect date the hard way | 175 end |
188 module:log("debug", "Find all dates with messages"); | 176 |
189 local next_day; | 177 -- Collect date the hard way |
190 repeat | 178 module:log("debug", "Find all dates with messages"); |
191 local when = find_once(room, { start = next_day; }, 3); | 179 date_list = {}; |
192 if not when then break; end | 180 local next_day; |
193 local t = os_date("!*t", when); | 181 repeat |
194 dates:set(t.year, t.month, t.day, when ); | 182 local when = find_once(room, { start = next_day; }, 3); |
195 next_day = date_floor(when) + 86400; | 183 if not when then break; end |
196 until not next_day; | 184 table.insert(date_list, when); |
197 end | 185 next_day = date_floor(when) + 86400; |
198 | 186 until not next_day; |
187 return date_list; | |
188 end | |
189 | |
190 function render_funcs.calendarize(date_list) | |
191 -- convert array of timestamps to a year / month / day tree | |
192 local dates = mt.new(); | |
193 for _, when in ipairs(date_list) do | |
194 local t = os_date("!*t", when); | |
195 dates:set(t.year, t.month, t.day, when); | |
196 end | |
197 -- Wrangle Y/m/d tree into year / month / week / day tree for calendar view | |
199 local years = {}; | 198 local years = {}; |
200 | |
201 -- Wrangle Y/m/d tree into year / month / week / day tree for calendar view | |
202 for current_year, months_t in pairs(dates.data) do | 199 for current_year, months_t in pairs(dates.data) do |
203 local t = { year = current_year, month = 1, day = 1 }; | 200 local t = { year = current_year, month = 1, day = 1 }; |
204 local months = { }; | 201 local months = { }; |
205 local year = { year = current_year, months = months }; | 202 local year = { year = current_year, months = months }; |
206 years[#years+1] = year; | 203 years[#years+1] = year; |
233 end | 230 end |
234 end | 231 end |
235 table.sort(months, sort_m); | 232 table.sort(months, sort_m); |
236 end | 233 end |
237 table.sort(years, sort_Y); | 234 table.sort(years, sort_Y); |
235 return years; | |
236 end | |
237 | |
238 -- Produce the calendar view | |
239 local function years_page(event, path) | |
240 local request, response = event.request, event.response; | |
241 | |
242 local room = nodeprep(path:match("^(.*)/$")); | |
243 local is_open = open_room(room); | |
244 if is_open == nil then | |
245 return -- implicit 404 | |
246 elseif is_open == false then | |
247 return 403; | |
248 end | |
249 | |
250 local date_list = get_dates(room); | |
251 if not date_list then | |
252 return; -- 404 | |
253 end | |
238 | 254 |
239 -- Phew, all wrangled, all that's left is rendering it with the template | 255 -- Phew, all wrangled, all that's left is rendering it with the template |
240 | 256 |
241 response.headers.content_type = "text/html; charset=utf-8"; | 257 response.headers.content_type = "text/html; charset=utf-8"; |
242 return render(template, { | 258 return render(template, { |
243 room = get_room(room)._data; | 259 room = get_room(room)._data; |
244 jid = get_room(room).jid; | 260 jid = get_room(room).jid; |
245 jid_node = jid_split(get_room(room).jid); | 261 jid_node = jid_split(get_room(room).jid); |
246 hide_presence = hide_presence(request); | 262 hide_presence = hide_presence(request); |
247 presence_available = presence_logged; | 263 presence_available = presence_logged; |
248 years = years; | 264 dates = date_list; |
249 links = { | 265 links = { |
250 { href = "../", rel = "up", text = "Room list" }, | 266 { href = "../", rel = "up", text = "Room list" }, |
251 { href = "latest", rel = "last", text = "Latest" }, | 267 { href = "latest", rel = "last", text = "Latest" }, |
252 }; | 268 }; |
253 }); | 269 }); |
383 hide_presence = hide_presence(request); | 399 hide_presence = hide_presence(request); |
384 presence_available = presence_logged; | 400 presence_available = presence_logged; |
385 lang = get_room(room).get_language and get_room(room):get_language(); | 401 lang = get_room(room).get_language and get_room(room):get_language(); |
386 lines = logs; | 402 lines = logs; |
387 links = links; | 403 links = links; |
404 dates = {}; -- COMPAT util.interpolation {nil|func#...} bug | |
388 }); | 405 }); |
389 end | 406 end |
390 | 407 |
391 local function list_rooms(event) | 408 local function list_rooms(event) |
392 local request, response = event.request, event.response; | 409 local request, response = event.request, event.response; |
412 title = module:get_option_string("name", "Prosody Chatrooms"); | 429 title = module:get_option_string("name", "Prosody Chatrooms"); |
413 jid = module.host; | 430 jid = module.host; |
414 hide_presence = hide_presence(request); | 431 hide_presence = hide_presence(request); |
415 presence_available = presence_logged; | 432 presence_available = presence_logged; |
416 rooms = room_list; | 433 rooms = room_list; |
434 dates = {}; -- COMPAT util.interpolation {nil|func#...} bug | |
417 }); | 435 }); |
418 end | 436 end |
419 | 437 |
420 module:provides("http", { | 438 module:provides("http", { |
421 route = { | 439 route = { |