Software / code / prosody
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 |