Mercurial > prosody-modules
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 |
| parents | 3246d53ce0c3 |
| children | 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); |
