Comparison

plugins/mod_pep.lua @ 2327:5839f303addf

mod_pep: Support item retrieval use cases
author Paul Aurich <paul@darkrain42.org>
date Sat, 05 Dec 2009 10:26:43 -0800
parent 2326:814eaba0c777
child 2384:7bec10f26082
child 2923:b7049746bd29
comparison
equal deleted inserted replaced
2326:814eaba0c777 2327:5839f303addf
35 end 35 end
36 36
37 module:add_identity("pubsub", "pep", "Prosody"); 37 module:add_identity("pubsub", "pep", "Prosody");
38 module:add_feature("http://jabber.org/protocol/pubsub#publish"); 38 module:add_feature("http://jabber.org/protocol/pubsub#publish");
39 39
40 local function publish(session, node, item) 40 local function subscription_presence(user_bare, recipient)
41 local recipient_bare = jid_bare(recipient);
42 if (recipient_bare == user_bare) then return true end
43 local item = load_roster(jid_split(user_bare))[recipient_bare];
44 return item and (item.subscription == 'from' or item.subscription == 'both');
45 end
46
47 local function publish(session, node, id, item)
41 item.attr.xmlns = nil; 48 item.attr.xmlns = nil;
42 local disable = #item.tags ~= 1 or #item.tags[1] == 0; 49 local disable = #item.tags ~= 1 or #item.tags[1] == 0;
43 if #item.tags == 0 then item.name = "retract"; end 50 if #item.tags == 0 then item.name = "retract"; end
44 local bare = session.username..'@'..session.host; 51 local bare = session.username..'@'..session.host;
45 local stanza = st.message({from=bare, type='headline'}) 52 local stanza = st.message({from=bare, type='headline'})
56 user_data[node] = nil; 63 user_data[node] = nil;
57 if not next(user_data) then data[bare] = nil; end 64 if not next(user_data) then data[bare] = nil; end
58 end 65 end
59 else 66 else
60 if not user_data then user_data = {}; data[bare] = user_data; end 67 if not user_data then user_data = {}; data[bare] = user_data; end
61 user_data[node] = stanza; 68 user_data[node] = {id or "1", item};
62 end 69 end
63 70
64 -- broadcast 71 -- broadcast
65 for recipient, notify in pairs(recipients[bare] or NULL) do 72 for recipient, notify in pairs(recipients[bare] or NULL) do
66 if notify[node] then 73 if notify[node] then
67 stanza.attr.to = recipient; 74 stanza.attr.to = recipient;
68 core_post_stanza(session, stanza); 75 core_post_stanza(session, stanza);
72 local function publish_all(user, recipient, session) 79 local function publish_all(user, recipient, session)
73 local d = data[user]; 80 local d = data[user];
74 local notify = recipients[user] and recipients[user][recipient]; 81 local notify = recipients[user] and recipients[user][recipient];
75 if d and notify then 82 if d and notify then
76 for node in pairs(notify) do 83 for node in pairs(notify) do
77 local message = d[node]; 84 if d[node] then
78 if message then 85 local id, item = unpack(d[node]);
79 message.attr.to = recipient; 86 session.send(st.message({from=user, to=recipient, type='headline'})
80 session.send(message); 87 :tag('event', {xmlns='http://jabber.org/protocol/pubsub#event'})
88 :tag('items', {node=node})
89 :add_child(item)
90 :up()
91 :up());
81 end 92 end
82 end 93 end
83 end 94 end
84 end 95 end
85 96
104 end 115 end
105 116
106 module:hook("presence/bare", function(event) 117 module:hook("presence/bare", function(event)
107 -- inbound presence to bare JID recieved 118 -- inbound presence to bare JID recieved
108 local origin, stanza = event.origin, event.stanza; 119 local origin, stanza = event.origin, event.stanza;
109
110 local user = stanza.attr.to or (origin.username..'@'..origin.host); 120 local user = stanza.attr.to or (origin.username..'@'..origin.host);
111 local bare = jid_bare(stanza.attr.from); 121
112 local item = load_roster(jid_split(user))[bare]; 122 if not stanza.attr.to or subscription_presence(user, stanza.attr.from) then
113 if not stanza.attr.to or (item and (item.subscription == 'from' or item.subscription == 'both')) then
114 local recipient = stanza.attr.from; 123 local recipient = stanza.attr.from;
115 local current = recipients[user] and recipients[user][recipient]; 124 local current = recipients[user] and recipients[user][recipient];
116 local hash = get_caps_hash_from_presence(stanza, current); 125 local hash = get_caps_hash_from_presence(stanza, current);
117 if current == hash then return; end 126 if current == hash then return; end
118 if not hash then 127 if not hash then
133 end 142 end
134 end, 10); 143 end, 10);
135 144
136 module:hook("iq/bare/http://jabber.org/protocol/pubsub:pubsub", function(event) 145 module:hook("iq/bare/http://jabber.org/protocol/pubsub:pubsub", function(event)
137 local session, stanza = event.origin, event.stanza; 146 local session, stanza = event.origin, event.stanza;
147 local payload = stanza.tags[1];
148
138 if stanza.attr.type == 'set' and (not stanza.attr.to or jid_bare(stanza.attr.from) == stanza.attr.to) then 149 if stanza.attr.type == 'set' and (not stanza.attr.to or jid_bare(stanza.attr.from) == stanza.attr.to) then
139 local payload = stanza.tags[1]; 150 payload = payload.tags[1];
140 if payload.name == 'pubsub' then -- <pubsub xmlns='http://jabber.org/protocol/pubsub'> 151 if payload and (payload.name == 'publish' or payload.name == 'retract') and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'>
152 local node = payload.attr.node;
141 payload = payload.tags[1]; 153 payload = payload.tags[1];
142 if payload and (payload.name == 'publish' or payload.name == 'retract') and payload.attr.node then -- <publish node='http://jabber.org/protocol/tune'> 154 if payload and payload.name == "item" then -- <item>
143 local node = payload.attr.node; 155 local id = payload.attr.id;
144 payload = payload.tags[1]; 156 session.send(st.reply(stanza));
145 if payload and payload.name == "item" then -- <item> 157 publish(session, node, id, st.clone(payload));
146 session.send(st.reply(stanza)); 158 return true;
147 publish(session, node, st.clone(payload)); 159 end
160 end
161 elseif stanza.attr.type == 'get' then
162 local user = stanza.attr.to and jid_bare(stanza.attr.to) or session.username..'@'..session.host;
163 if subscription_presence(user, stanza.attr.from) then
164 local user_data = data[user];
165 local node, requested_id;
166 payload = payload.tags[1];
167 if payload and payload.name == 'items' then
168 node = payload.attr.node;
169 local item = payload.tags[1];
170 if item and item.name == "item" then
171 requested_id = item.attr.id;
172 end
173 end
174 if node and user_data and user_data[node] then -- Send the last item
175 local id, item = unpack(user_data[node]);
176 if not requested_id or id == requested_id then
177 local stanza = st.reply(stanza)
178 :tag('pubsub', {xmlns='http://jabber.org/protocol/pubsub'})
179 :tag('items', {node=node})
180 :add_child(item)
181 :up()
182 :up();
183 session.send(stanza);
148 return true; 184 return true;
149 end 185 else -- requested item doesn't exist
150 end 186 local stanza = st.reply(stanza)
187 :tag('pubsub', {xmlns='http://jabber.org/protocol/pubsub'})
188 :tag('items', {node=node})
189 :up();
190 session.send(stanza);
191 return true;
192 end
193 elseif node then -- node doesn't exist
194 session.send(st.error_reply(stanza, 'cancel', 'item-not-found'));
195 return true;
196 else --invalid request
197 session.send(st.error_reply(stanza, 'modify', 'bad-request'));
198 return true;
199 end
200 else --no presence subscription
201 session.send(st.error_reply(stanza, 'auth', 'not-authorized')
202 :tag('presence-subscription-required', {xmlns='http://jabber.org/protocol/pubsub#errors'}));
203 return true;
151 end 204 end
152 end 205 end
153 end); 206 end);
154 207
155 local function calculate_hash(disco_info) 208 local function calculate_hash(disco_info)