Comparison

plugins/mod_muc_mam.lua @ 10000:189b00a782bf

mod_muc_mam: Handle archive quotas Same as in mod_mam
author Kim Alvefur <zash@zash.se>
date Sun, 05 May 2019 14:52:34 +0200
parent 9882:18f025b3987d
child 10022:b56654f89cd5
comparison
equal deleted inserted replaced
9999:d2febb4befbc 10000:189b00a782bf
31 local time_now = os.time; 31 local time_now = os.time;
32 local m_min = math.min; 32 local m_min = math.min;
33 local timestamp, timestamp_parse, datestamp = import( "util.datetime", "datetime", "parse", "date"); 33 local timestamp, timestamp_parse, datestamp = import( "util.datetime", "datetime", "parse", "date");
34 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50); 34 local default_max_items, max_max_items = 20, module:get_option_number("max_archive_query_results", 50);
35 35
36 local cleanup_after = module:get_option_string("muc_log_expires_after", "1w");
37 local cleanup_interval = module:get_option_number("muc_log_cleanup_interval", 4 * 60 * 60);
38
36 local default_history_length = 20; 39 local default_history_length = 20;
37 local max_history_length = module:get_option_number("max_history_messages", math.huge); 40 local max_history_length = module:get_option_number("max_history_messages", math.huge);
38 41
39 local function get_historylength(room) 42 local function get_historylength(room)
40 return math.min(room._data.history_length or default_history_length, max_history_length); 43 return math.min(room._data.history_length or default_history_length, max_history_length);
47 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false); 50 local log_all_rooms = module:get_option_boolean("muc_log_all_rooms", false);
48 local log_by_default = module:get_option_boolean("muc_log_by_default", true); 51 local log_by_default = module:get_option_boolean("muc_log_by_default", true);
49 52
50 local archive_store = "muc_log"; 53 local archive_store = "muc_log";
51 local archive = module:open_store(archive_store, "archive"); 54 local archive = module:open_store(archive_store, "archive");
55
56 local archive_item_limit = module:get_option_number("storage_archive_item_limit", archive.caps and archive.caps.quota or 1000);
52 57
53 if archive.name == "null" or not archive.find then 58 if archive.name == "null" or not archive.find then
54 if not archive.find then 59 if not archive.find then
55 module:log("error", "Attempt to open archive storage returned a driver without archive API support"); 60 module:log("error", "Attempt to open archive storage returned a driver without archive API support");
56 module:log("error", "mod_%s does not support archiving", 61 module:log("error", "mod_%s does not support archiving",
62 return false; 67 return false;
63 end 68 end
64 69
65 local function archiving_enabled(room) 70 local function archiving_enabled(room)
66 if log_all_rooms then 71 if log_all_rooms then
72 module:log("debug", "Archiving all rooms");
67 return true; 73 return true;
68 end 74 end
69 local enabled = room._data.archiving; 75 local enabled = room._data.archiving;
70 if enabled == nil then 76 if enabled == nil then
77 module:log("debug", "Default is %s (for %s)", log_by_default, room.jid);
71 return log_by_default; 78 return log_by_default;
72 end 79 end
80 module:log("debug", "Logging in room %s is %s", room.jid, enabled);
73 return enabled; 81 return enabled;
74 end 82 end
75 83
76 if not log_all_rooms then 84 if not log_all_rooms then
77 module:hook("muc-config-form", function(event) 85 module:hook("muc-config-form", function(event)
355 if stanza.attr.type then 363 if stanza.attr.type then
356 with = with .. "<" .. stanza.attr.type 364 with = with .. "<" .. stanza.attr.type
357 end 365 end
358 366
359 -- And stash it 367 -- And stash it
360 local id = archive:append(room_node, nil, stored_stanza, time_now(), with); 368 local time = time_now();
369 local id, err = archive:append(room_node, nil, stored_stanza, time, with);
370
371 if not id and err == "quota-limit" then
372 if type(cleanup_after) == "number" then
373 module:log("debug", "Room '%s' over quota, cleaning archive", room_node);
374 local cleaned = archive:delete(room_node, {
375 ["end"] = (os.time() - cleanup_after);
376 });
377 if cleaned then
378 id, err = archive:append(room_node, nil, stored_stanza, time, with);
379 end
380 end
381 if not id and (archive.caps and archive.caps.truncate) then
382 module:log("debug", "User '%s' over quota, truncating archive", room_node);
383 local truncated = archive:delete(room_node, {
384 truncate = archive_item_limit - 1;
385 });
386 if truncated then
387 id, err = archive:append(room_node, nil, stored_stanza, time, with);
388 end
389 end
390 end
361 391
362 if id then 392 if id then
363 schedule_cleanup(room_node); 393 schedule_cleanup(room_node);
364 stanza:add_direct_child(st.stanza("stanza-id", { xmlns = xmlns_st_id, by = self.jid, id = id })); 394 stanza:add_direct_child(st.stanza("stanza-id", { xmlns = xmlns_st_id, by = self.jid, id = id }));
365 end 395 end
396 module:hook("muc-disco#info", function(event) 426 module:hook("muc-disco#info", function(event)
397 event.reply:tag("feature", {var=xmlns_mam}):up(); 427 event.reply:tag("feature", {var=xmlns_mam}):up();
398 end); 428 end);
399 429
400 -- Cleanup 430 -- Cleanup
401
402 local cleanup_after = module:get_option_string("muc_log_expires_after", "1w");
403 local cleanup_interval = module:get_option_number("muc_log_cleanup_interval", 4 * 60 * 60);
404 431
405 if cleanup_after ~= "never" then 432 if cleanup_after ~= "never" then
406 local cleanup_storage = module:open_store("muc_log_cleanup"); 433 local cleanup_storage = module:open_store("muc_log_cleanup");
407 local cleanup_map = module:open_store("muc_log_cleanup", "map"); 434 local cleanup_map = module:open_store("muc_log_cleanup", "map");
408 435