Comparison

mod_mam/mod_mam.lua @ 2016:279885fd9728

mod_mam: Add support for trimming old archived messages
author Kim Alvefur <zash@zash.se>
date Tue, 19 Jan 2016 13:34:16 +0100
parent 2001:3246d53ce0c3
child 2017:d44ac0756c46
comparison
equal deleted inserted replaced
2015:7f90692bbd23 2016:279885fd9728
46 module:log("debug", "Attempt to open archive storage returned a valid driver but it does not seem to implement the storage API"); 46 module:log("debug", "Attempt to open archive storage returned a valid driver but it does not seem to implement the storage API");
47 module:log("error", "mod_%s does not support archiving", archive._provided_by or archive.name and "storage_"..archive.name.."(?)" or "<unknown>"); 47 module:log("error", "mod_%s does not support archiving", archive._provided_by or archive.name and "storage_"..archive.name.."(?)" or "<unknown>");
48 module:log("info", "See https://prosody.im/doc/storage and https://prosody.im/doc/archiving for more information"); 48 module:log("info", "See https://prosody.im/doc/storage and https://prosody.im/doc/archiving for more information");
49 return; 49 return;
50 end 50 end
51
52 local cleanup;
51 53
52 -- Handle prefs. 54 -- Handle prefs.
53 module:hook("iq/self/"..xmlns_mam..":prefs", function(event) 55 module:hook("iq/self/"..xmlns_mam..":prefs", function(event)
54 local origin, stanza = event.origin, event.stanza; 56 local origin, stanza = event.origin, event.stanza;
55 local user = origin.username; 57 local user = origin.username;
88 module:hook("iq-set/self/"..xmlns_mam..":query", function(event) 90 module:hook("iq-set/self/"..xmlns_mam..":query", function(event)
89 local origin, stanza = event.origin, event.stanza; 91 local origin, stanza = event.origin, event.stanza;
90 local query = stanza.tags[1]; 92 local query = stanza.tags[1];
91 local qid = query.attr.queryid; 93 local qid = query.attr.queryid;
92 94
95 if cleanup then cleanup[origin.username] = true; end
96
93 -- Search query parameters 97 -- Search query parameters
94 local qwith, qstart, qend; 98 local qwith, qstart, qend;
95 local form = query:get_child("x", "jabber:x:data"); 99 local form = query:get_child("x", "jabber:x:data");
96 if form then 100 if form then
97 local err; 101 local err;
251 module:log("debug", "Archiving stanza: %s", stanza:top_tag()); 255 module:log("debug", "Archiving stanza: %s", stanza:top_tag());
252 256
253 -- And stash it 257 -- And stash it
254 local ok, id = archive:append(store_user, nil, time_now(), with, stanza); 258 local ok, id = archive:append(store_user, nil, time_now(), with, stanza);
255 if ok then 259 if ok then
260 if cleanup then cleanup[store_user] = true; end
256 module:fire_event("archive-message-added", { origin = origin, stanza = stanza, for_user = store_user, id = id }); 261 module:fire_event("archive-message-added", { origin = origin, stanza = stanza, for_user = store_user, id = id });
257 end 262 end
258 else 263 else
259 module:log("debug", "Not archiving stanza: %s (prefs)", stanza:top_tag()); 264 module:log("debug", "Not archiving stanza: %s (prefs)", stanza:top_tag());
260 end 265 end
261 end 266 end
262 267
263 local function c2s_message_handler(event) 268 local function c2s_message_handler(event)
264 return message_handler(event, true); 269 return message_handler(event, true);
270 end
271
272 local cleanup_after = module:get_option_string("archive_expires_after", "1w");
273 local cleanup_interval = module:get_option_number("archive_expire_interval", 4 * 60 * 60);
274 if cleanup_after ~= "never" then
275 local day = 86400;
276 local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day };
277 local n, m = cleanup_after:lower():match("(%d+)%s*([dmy]?)");
278 if not n then
279 module:log("error", "Could not parse archive_expires_after string %q", cleanup_after);
280 return false;
281 end
282
283 cleanup_after = tonumber(n) * ( multipliers[m] or 1 );
284
285 if not archive.delete then
286 module:log("error", "archive_expires_after set but mod_%s does not support deleting", archive._provided_by);
287 return false;
288 end
289
290 cleanup = {};
291
292 pcall(function ()
293 local um = require "core.usermanager";
294 for user in um.users(module.host) do
295 cleanup[user] = true;
296 end
297 end);
298
299 module:add_timer(10, function()
300 local user = next(cleanup);
301 if user then
302 module:log("debug", "Removing old messages for user %q", user);
303 local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; })
304 if not ok then
305 module:log("warn", "Could not expire archives for user %s: %s", user, err);
306 end
307 user[cleanup] = nil;
308 end
309 return 14400;
310 end);
265 end 311 end
266 312
267 -- Stanzas sent by local clients 313 -- Stanzas sent by local clients
268 module:hook("pre-message/bare", c2s_message_handler, 2); 314 module:hook("pre-message/bare", c2s_message_handler, 2);
269 module:hook("pre-message/full", c2s_message_handler, 2); 315 module:hook("pre-message/full", c2s_message_handler, 2);