From a3dcce859a4270ae04b92881f03bb25bb766b70c Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 15 Apr 2017 01:21:55 +0100 Subject: =?UTF-8?q?mod=5Fpubsub:=20Add=20item=20persistence=20using=20mod?= =?UTF-8?q?=5Fstorage=5F*=E2=80=99s=20archive=20store.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/mod_pubsub/mod_pubsub.lua | 7 ++++ plugins/mod_pubsub/pubsub.lib.lua | 73 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua index ae6cfce2..8bbebcf9 100644 --- a/plugins/mod_pubsub/mod_pubsub.lua +++ b/plugins/mod_pubsub/mod_pubsub.lua @@ -21,6 +21,8 @@ module:depends("disco"); module:add_identity("pubsub", "service", pubsub_disco_name); module:add_feature("http://jabber.org/protocol/pubsub"); +local archive = module:open_store("pubsub", "archive"); + function handle_pubsub_iq(event) local origin, stanza = event.origin, event.stanza; local pubsub_tag = stanza.tags[1]; @@ -36,6 +38,10 @@ function handle_pubsub_iq(event) end end +local function simple_itemstore(config, node) + return lib_pubsub.simple_itemstore(archive, config, node, expose_publisher); +end + function simple_broadcast(kind, node, jids, item, actor) if item then item = st.clone(item); @@ -224,6 +230,7 @@ function module.load() autocreate_on_publish = autocreate_on_publish; autocreate_on_subscribe = autocreate_on_subscribe; + itemstore = simple_itemstore; broadcaster = simple_broadcast; get_affiliation = get_affiliation; diff --git a/plugins/mod_pubsub/pubsub.lib.lua b/plugins/mod_pubsub/pubsub.lib.lua index fd1f59d1..45c6933f 100644 --- a/plugins/mod_pubsub/pubsub.lib.lua +++ b/plugins/mod_pubsub/pubsub.lib.lua @@ -1,4 +1,5 @@ local t_unpack = table.unpack or unpack; -- luacheck: ignore 113 +local time_now = os.time; local st = require "util.stanza"; local uuid_generate = require "util.uuid".generate; @@ -316,4 +317,76 @@ function handlers.get_default(origin, stanza, default, service) return true; end +local function create_encapsulating_item(id, payload, publisher, expose_publisher) + local item = st.stanza("item", { id = id }, xmlns_pubsub); + item:add_child(payload); + if expose_publisher then + item.attr.publisher = publisher; + end + return item; +end + +local function simple_itemstore(archive, config, node, expose_publisher) + module:log("debug", "Creation of itemstore for node %s with config %s", node, config); + local get_set = {}; + function get_set:items() + local store = self.store; + local data, err = archive:find(node); + if not data then + module:log("error", "Unable to get items: %s", err); + return true; + end + module:log("debug", "Listed items %s from store %s", data, store); + return function() + local id, payload, when, publisher = data(); + if id == nil then + return; + end + local item = create_encapsulating_item(id, payload, publisher, expose_publisher); + return id, item; + end; + end + function get_set:get(key) + local store = self.store; + local data, err = archive:find(node, { + key = key; + }); + if not data then + module:log("error", "Unable to get item: %s", err); + return nil, err; + end + -- Workaround for buggy SQL drivers which require iterating until we get a nil. + local id, payload, when, publisher; + for a, b, c, d in data() do + id, payload, when, publisher = a, b, c, d; + end + module:log("debug", "Get item %s (published at %s by %s) from store %s", id, when, publisher, store); + if id == nil then + return nil; + end + return create_encapsulating_item(id, payload, publisher, expose_publisher); + end + function get_set:set(key, value) + local store = self.store; + module:log("debug", "Set item %s to %s for %s in store %s", key, value, node, store); + local data, err; + if value ~= nil then + local publisher = value.attr.publisher; + local payload = value.tags[1]; + data, err = archive:append(node, key, payload, time_now(), publisher); + else + data, err = archive:delete(node, { + key = key; + }); + end + if not data then + module:log("error", "Unable to set item: %s", err); + return nil, err; + end + return true; + end + return setmetatable(get_set, archive); +end +_M.simple_itemstore = simple_itemstore; + return _M; -- cgit v1.2.3