Software /
code /
prosody
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) |