--- a/mod_mam/README.markdown Tue Jan 19 13:31:11 2016 +0100
+++ b/mod_mam/README.markdown Tue Jan 19 13:34:16 2016 +0100
@@ -40,6 +40,7 @@
------------------------------ ----------------------- ---------
max\_archive\_query\_results number `50`
default\_archive\_policy boolean or `"roster"` `false`
+ archive\_expires\_after string `"1w"`
Storage backend
---------------
@@ -67,6 +68,30 @@
blocked while processing the request and will not be able to do anything
else.
+Archive expiry
+--------------
+
+Messages in the archive will expire after some time, by default one
+week. This can be changed by setting `archive_expires_after`:
+
+``` {.lua}
+archive_expires_after = "1d" -- one day
+
+archive_expires_after = "1w" -- one week, the default
+
+archive_expires_after = "2m" -- two months
+
+archive_expires_after = "1y" -- one year
+
+archive_expires_after = 60 * 60 -- one hour
+
+archive_expires_after = "never" -- forever
+```
+
+The format is an integer number of seconds or a multiple of a period
+given by a suffix that can be one of `d` (day), `w` (week), `m` (month)
+or `y` (year). No multiplier means seconds.
+
Message matching policy
-----------------------
--- a/mod_mam/mod_mam.lua Tue Jan 19 13:31:11 2016 +0100
+++ b/mod_mam/mod_mam.lua Tue Jan 19 13:34:16 2016 +0100
@@ -49,6 +49,8 @@
return;
end
+local cleanup;
+
-- Handle prefs.
module:hook("iq/self/"..xmlns_mam..":prefs", function(event)
local origin, stanza = event.origin, event.stanza;
@@ -90,6 +92,8 @@
local query = stanza.tags[1];
local qid = query.attr.queryid;
+ if cleanup then cleanup[origin.username] = true; end
+
-- Search query parameters
local qwith, qstart, qend;
local form = query:get_child("x", "jabber:x:data");
@@ -253,6 +257,7 @@
-- And stash it
local ok, id = archive:append(store_user, nil, time_now(), with, stanza);
if ok then
+ if cleanup then cleanup[store_user] = true; end
module:fire_event("archive-message-added", { origin = origin, stanza = stanza, for_user = store_user, id = id });
end
else
@@ -264,6 +269,47 @@
return message_handler(event, true);
end
+local cleanup_after = module:get_option_string("archive_expires_after", "1w");
+local cleanup_interval = module:get_option_number("archive_expire_interval", 4 * 60 * 60);
+if cleanup_after ~= "never" then
+ local day = 86400;
+ local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day };
+ local n, m = cleanup_after:lower():match("(%d+)%s*([dmy]?)");
+ if not n then
+ module:log("error", "Could not parse archive_expires_after string %q", cleanup_after);
+ return false;
+ end
+
+ cleanup_after = tonumber(n) * ( multipliers[m] or 1 );
+
+ if not archive.delete then
+ module:log("error", "archive_expires_after set but mod_%s does not support deleting", archive._provided_by);
+ return false;
+ end
+
+ cleanup = {};
+
+ pcall(function ()
+ local um = require "core.usermanager";
+ for user in um.users(module.host) do
+ cleanup[user] = true;
+ end
+ end);
+
+ module:add_timer(10, function()
+ local user = next(cleanup);
+ if user then
+ module:log("debug", "Removing old messages for user %q", user);
+ local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; })
+ if not ok then
+ module:log("warn", "Could not expire archives for user %s: %s", user, err);
+ end
+ user[cleanup] = nil;
+ end
+ return 14400;
+ end);
+end
+
-- Stanzas sent by local clients
module:hook("pre-message/bare", c2s_message_handler, 2);
module:hook("pre-message/full", c2s_message_handler, 2);