aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_pubsub
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2017-04-15 01:21:55 +0100
committerEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2017-04-15 01:21:55 +0100
commit5af0698f71f9a9e9e381f09f3bbf8f561f72c991 (patch)
tree60d10502329cdfa165123f5cbbbfb2fc1316bf9d /plugins/mod_pubsub
parent18c92af84956c0d46b7bcf813f58dd7a8191758f (diff)
downloadprosody-5af0698f71f9a9e9e381f09f3bbf8f561f72c991.tar.gz
prosody-5af0698f71f9a9e9e381f09f3bbf8f561f72c991.zip
mod_pubsub: Add item persistence using mod_storage_*?s archive store.
Diffstat (limited to 'plugins/mod_pubsub')
-rw-r--r--plugins/mod_pubsub/mod_pubsub.lua7
-rw-r--r--plugins/mod_pubsub/pubsub.lib.lua73
2 files changed, 80 insertions, 0 deletions
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;