+-- Prosody IM
+-- Copyright (C) 2008-2009 Matthew Wild
+-- Copyright (C) 2008-2009 Waqas Hussain
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
local jid_bare = require "util.jid".bare;
local jid_split = require "util.jid".split;
local recipients = {};
local hash_map = {};
-module:add_identity("pubsub", "pep");
+module.save = function()
+ return { data = data, recipients = recipients, hash_map = hash_map };
+end
+module.restore = function(state)
+ data = state.data or {};
+ recipients = state.recipients or {};
+ hash_map = state.hash_map or {};
+end
+
+module:add_identity("pubsub", "pep", "Prosody");
module:add_feature("http://jabber.org/protocol/pubsub#publish");
local function publish(session, node, item)
+ item.attr.xmlns = nil;
local disable = #item.tags ~= 1 or #item.tags[1].tags == 0;
+ if #item.tags == 0 then item.name = "retract"; end
local bare = session.username..'@'..session.host;
local stanza = st.message({from=bare, type='headline'})
:tag('event', {xmlns='http://jabber.org/protocol/pubsub#event'})
-- store for the future
local user_data = data[bare];
if disable then
- if user_data then user_data[node] = nil; end
- if not next(user_data) then data[bare] = nil; end
+ if user_data then
+ user_data[node] = nil;
+ if not next(user_data) then data[bare] = nil; end
+ end
else
if not user_data then user_data = {}; data[bare] = user_data; end
user_data[node] = stanza;
end
end
end
+local function publish_all(user, recipient, session)
+ local d = data[user];
+ local notify = recipients[user] and recipients[user][recipient];
+ if d and notify then
+ for node in pairs(notify) do
+ local message = d[node];
+ if message then
+ message.attr.to = recipient;
+ session.send(message);
+ end
+ end
+ end
+end
local function get_caps_hash_from_presence(stanza, current)
local t = stanza.attr.type;
if recipients[user] then recipients[user][recipient] = nil; end
else
recipients[user] = recipients[user] or {};
- recipients[user][recipient] = hash;
- origin.send(
- st.stanza("iq", {from=stanza.attr.to, to=stanza.attr.from, id="disco", type="get"})
- :query("http://jabber.org/protocol/disco#info")
- );
+ if hash_map[hash] then
+ recipients[user][recipient] = hash_map[hash];
+ publish_all(user, recipient, origin);
+ else
+ recipients[user][recipient] = hash;
+ origin.send(
+ st.stanza("iq", {from=stanza.attr.to, to=stanza.attr.from, id="disco", type="get"})
+ :query("http://jabber.org/protocol/disco#info")
+ );
+ end
end
end
end, 10);
local payload = stanza.tags[1];
if payload.name == 'pubsub' then -- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
payload = payload.tags[1];
- if payload and payload.name == 'publish' and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'>
+ if payload and (payload.name == 'publish' or payload.name == 'retract') and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'>
local node = payload.attr.node;
payload = payload.tags[1];
- if payload then -- <item>
- publish(session, node, payload);
+ if payload and payload.name == "item" then -- <item>
+ session.send(st.reply(stanza));
+ publish(session, node, st.clone(payload));
return true;
end
end
local notify = {};
for _, feature in pairs(disco.tags) do
if feature.name == "feature" and feature.attr.var then
- local nfeature = feature.attr.var:match("^(.*)+notify$");
+ local nfeature = feature.attr.var:match("^(.*)%+notify$");
if nfeature then notify[nfeature] = true; end
end
end
hash_map[ver] = notify; -- update hash map
recipients[user][contact] = notify; -- set recipient's data to calculated data
-- send messages to recipient
- local d = data[user];
- if d then
- for node, message in pairs(notify) do
- if d[node] then
- message.attr.to = stanza.attr.from;
- session.send(message);
- end
- end
- end
+ publish_all(user, contact, session);
end
end
end);