From 15f20672973752454f3475b0ba04cf1e8381bdf6 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:34:33 +0200 Subject: mod_storage_internal: Separate driver from keyval implementation --- plugins/mod_storage_internal.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index ade4f0a6..dd8cf61f 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -3,19 +3,23 @@ local datamanager = require "core.storagemanager".olddm; local host = module.host; local driver = {}; -local driver_mt = { __index = driver }; function driver:open(store, typ) - if typ and typ ~= "keyval" then + local mt = self[typ or "keyval"] + if not mt then return nil, "unsupported-store"; end - return setmetatable({ store = store, type = typ }, driver_mt); + return setmetatable({ store = store, type = typ }, mt); end -function driver:get(user) + +local keyval = { }; +driver.keyval = { __index = keyval }; + +function keyval:get(user) return datamanager.load(user, host, self.store); end -function driver:set(user, data) +function keyval:set(user, data) return datamanager.store(user, host, self.store, data); end @@ -23,7 +27,7 @@ function driver:stores(username) return datamanager.stores(username, host); end -function driver:users() +function keyval:users() return datamanager.users(host, self.store, self.type); end -- cgit v1.2.3 From 7b14467d602d8998281214f16777c8306d69d46a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:38:46 +0200 Subject: mod_storage_internal: Reorder methods --- plugins/mod_storage_internal.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index dd8cf61f..557a329e 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -12,6 +12,14 @@ function driver:open(store, typ) return setmetatable({ store = store, type = typ }, mt); end +function driver:stores(username) + return datamanager.stores(username, host); +end + +function driver:purge(user) + return datamanager.purge(user, host); +end + local keyval = { }; driver.keyval = { __index = keyval }; @@ -23,16 +31,8 @@ function keyval:set(user, data) return datamanager.store(user, host, self.store, data); end -function driver:stores(username) - return datamanager.stores(username, host); -end - function keyval:users() return datamanager.users(host, self.store, self.type); end -function driver:purge(user) - return datamanager.purge(user, host); -end - module:provides("storage", driver); -- cgit v1.2.3 From 91c38521ad0476190e33427692dd38dfb05c4619 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:39:41 +0200 Subject: mod_storage_internal: Ignore unused 'self' argument [luacheck] --- plugins/mod_storage_internal.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 557a329e..294d823c 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -12,11 +12,11 @@ function driver:open(store, typ) return setmetatable({ store = store, type = typ }, mt); end -function driver:stores(username) +function driver:stores(username) -- luacheck: ignore 212/self return datamanager.stores(username, host); end -function driver:purge(user) +function driver:purge(user) -- luacheck: ignore 212/self return datamanager.purge(user, host); end -- cgit v1.2.3 From 0e7993732b3552f05f93e6c8410e07a82ef91bfa Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:47:06 +0200 Subject: mod_storage_internal: Add basic archive store implementation --- plugins/mod_storage_internal.lua | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index 294d823c..a5401f70 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -1,4 +1,9 @@ local datamanager = require "core.storagemanager".olddm; +local array = require "util.array"; +local datetime = require "util.datetime"; +local st = require "util.stanza"; +local now = require "util.time".now; +local id = require "util.id".medium; local host = module.host; @@ -35,4 +40,84 @@ function keyval:users() return datamanager.users(host, self.store, self.type); end +local archive = {}; +driver.archive = { __index = archive }; + +function archive:append(username, key, value, when, with) + key = key or id(); + when = when or now(); + if not st.is_stanza(value) then + return nil, "unsupported-datatype"; + end + value = st.preserialize(st.clone(value)); + value.key = key; + value.when = when; + value.with = with; + value.attr.stamp = datetime.datetime(when); + value.attr.stamp_legacy = datetime.legacy(when); + local ok, err = datamanager.list_append(username, host, self.store, value); + if not ok then return ok, err; end + return key; +end + +function archive:find(username, query) + local items, err = datamanager.list_load(username, host, self.store); + if not items then return items, err; end + local count = #items; + local i = 0; + if query then + items = array(items); + if query.with then + items:filter(function (item) + return item.with == query.with; + end); + end + if query.start then + items:filter(function (item) + return item.when >= query.start; + end); + end + if query["end"] then + items:filter(function (item) + return item.when <= query["end"]; + end); + end + count = #items; + if query.reverse then + items:reverse(); + if query.before then + for j = 1, count do + if (items[j].key or tostring(j)) == query.before then + i = j; + break; + end + end + end + elseif query.after then + for j = 1, count do + if (items[j].key or tostring(j)) == query.after then + i = j; + break; + end + end + end + if query.limit and #items - i > query.limit then + items[i+query.limit+1] = nil; + end + end + return function () + i = i + 1; + local item = items[i]; + if not item then return; end + local key = item.key or tostring(i); + local when = item.when or datetime.parse(item.attr.stamp); + local with = item.with; + item.key, item.when, item.with = nil, nil, nil; + item.attr.stamp = nil; + item.attr.stamp_legacy = nil; + item = st.deserialize(item); + return key, item, when, with; + end, count; +end + module:provides("storage", driver); -- cgit v1.2.3 From 2c3869f5be7a1a842438c207a60389f80eb75289 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:48:50 +0200 Subject: mod_storage_internal: Add support for removing archived items --- plugins/mod_storage_internal.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index a5401f70..c1e460eb 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -120,4 +120,23 @@ function archive:find(username, query) end, count; end +function archive:delete(username, query) + if not query or next(query) == nil then + return datamanager.list_store(username, host, self.store, nil); + end + for k in pairs(query) do + if k ~= "end" then return nil, "unsupported-query-field"; end + end + local items, err = datamanager.list_load(username, host, self.store); + if not items then return items, err; end + items = array(items); + items:filter(function (item) + return item.when > query["end"]; + end); + local count = #items; + local ok, err = datamanager.list_store(username, host, self.store, items); + if not ok then return ok, err; end + return count; +end + module:provides("storage", driver); -- cgit v1.2.3 From 8943b3423f70df83b3b941fd5242c7bd97898d90 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:49:51 +0200 Subject: mod_storage_internal: Add the dates method --- plugins/mod_storage_internal.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index c1e460eb..09760838 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -120,6 +120,12 @@ function archive:find(username, query) end, count; end +function archive:dates(username) + local items, err = datamanager.list_load(username, host, self.store); + if not items then return items, err; end + return array(items):pluck("when"):map(datetime.date):unique(); +end + function archive:delete(username, query) if not query or next(query) == nil then return datamanager.list_store(username, host, self.store, nil); -- cgit v1.2.3 From d2b589c2aa0df1e0c372f4f94049e20ef478c609 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 17:50:19 +0200 Subject: mod_offline: Switch to using archive store via the storagemanager API --- plugins/mod_offline.lua | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_offline.lua b/plugins/mod_offline.lua index 08ab8490..fe4df573 100644 --- a/plugins/mod_offline.lua +++ b/plugins/mod_offline.lua @@ -7,29 +7,24 @@ -- -local datamanager = require "util.datamanager"; -local st = require "util.stanza"; local datetime = require "util.datetime"; -local ipairs = ipairs; local jid_split = require "util.jid".split; +local offline_messages = module:open_store("offline", "archive"); + module:add_feature("msgoffline"); module:hook("message/offline/handle", function(event) local origin, stanza = event.origin, event.stanza; local to = stanza.attr.to; - local node, host; + local node; if to then - node, host = jid_split(to) + node = jid_split(to) else - node, host = origin.username, origin.host; + node = origin.username; end - stanza.attr.stamp, stanza.attr.stamp_legacy = datetime.datetime(), datetime.legacy(); - local result = datamanager.list_append(node, host, "offline", st.preserialize(stanza)); - stanza.attr.stamp, stanza.attr.stamp_legacy = nil, nil; - - return result; + return offline_messages:append(node, nil, stanza); end, -1); module:hook("message/offline/broadcast", function(event) @@ -37,15 +32,12 @@ module:hook("message/offline/broadcast", function(event) local node, host = origin.username, origin.host; - local data = datamanager.list_load(node, host, "offline"); + local data = offline_messages:find(node); if not data then return true; end - for _, stanza in ipairs(data) do - stanza = st.deserialize(stanza); - stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = host, stamp = stanza.attr.stamp}):up(); -- XEP-0203 - stanza:tag("x", {xmlns = "jabber:x:delay", from = host, stamp = stanza.attr.stamp_legacy}):up(); -- XEP-0091 (deprecated) - stanza.attr.stamp, stanza.attr.stamp_legacy = nil, nil; + for _, stanza, when in data do + stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = host, stamp = datetime.datetime(when)}):up(); -- XEP-0203 origin.send(stanza); end - datamanager.list_store(node, host, "offline", nil); + offline_messages:delete(node); return true; end, -1); -- cgit v1.2.3 From 79bc05914a516cf0d005b6adff8b264be907eaa0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 31 Mar 2017 18:52:53 +0200 Subject: MUC: Only create rooms in a locked state when they are created by someone joining (fixes timed deletion of all rooms on startup) --- plugins/muc/mod_muc.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 90b01cc7..8c223cb2 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -86,12 +86,12 @@ local function room_save(room, forced) if forced then persistent_rooms_storage:set(nil, persistent_rooms); end end -function create_room(jid) +function create_room(jid, locked) local room = muc_new_room(jid); room.route_stanza = room_route_stanza; room.save = room_save; rooms[jid] = room; - if lock_rooms then + if locked then room.locked = true; if lock_room_timeout and lock_room_timeout > 0 then module:add_timer(lock_room_timeout, function () @@ -166,7 +166,7 @@ function stanza_handler(event) if not(restrict_room_creation) or is_admin(stanza.attr.from) or (restrict_room_creation == "local" and select(2, jid_split(stanza.attr.from)) == module.host:gsub("^[^%.]+%.", "")) then - room = create_room(bare); + room = create_room(bare, lock_rooms); end end if room then -- cgit v1.2.3