Software /
code /
prosody
Comparison
util/pubsub.lua @ 6054:7a5ddbaf758d
Merge 0.9->0.10
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 02 Apr 2014 17:41:38 +0100 |
parent | 5972:f365d3c8fd2c |
child | 5973:905b4fd863b4 |
child | 6435:689cb04ff9fd |
comparison
equal
deleted
inserted
replaced
6053:2f93a04564b2 | 6054:7a5ddbaf758d |
---|---|
1 local events = require "util.events"; | 1 local events = require "util.events"; |
2 local t_remove = table.remove; | |
2 | 3 |
3 module("pubsub", package.seeall); | 4 module("pubsub", package.seeall); |
4 | 5 |
5 local service = {}; | 6 local service = {}; |
6 local service_mt = { __index = service }; | 7 local service_mt = { __index = service }; |
16 return setmetatable({ | 17 return setmetatable({ |
17 config = setmetatable(config, { __index = default_config }); | 18 config = setmetatable(config, { __index = default_config }); |
18 affiliations = {}; | 19 affiliations = {}; |
19 subscriptions = {}; | 20 subscriptions = {}; |
20 nodes = {}; | 21 nodes = {}; |
22 data = {}; | |
21 events = events.new(); | 23 events = events.new(); |
22 }, service_mt); | 24 }, service_mt); |
23 end | 25 end |
24 | 26 |
25 function service:jids_equal(jid1, jid2) | 27 function service:jids_equal(jid1, jid2) |
27 return normalize(jid1) == normalize(jid2); | 29 return normalize(jid1) == normalize(jid2); |
28 end | 30 end |
29 | 31 |
30 function service:may(node, actor, action) | 32 function service:may(node, actor, action) |
31 if actor == true then return true; end | 33 if actor == true then return true; end |
32 | 34 |
33 local node_obj = self.nodes[node]; | 35 local node_obj = self.nodes[node]; |
34 local node_aff = node_obj and node_obj.affiliations[actor]; | 36 local node_aff = node_obj and node_obj.affiliations[actor]; |
35 local service_aff = self.affiliations[actor] | 37 local service_aff = self.affiliations[actor] |
36 or self.config.get_affiliation(actor, node, action) | 38 or self.config.get_affiliation(actor, node, action) |
37 or "none"; | 39 or "none"; |
38 | 40 |
39 -- Check if node allows/forbids it | 41 -- Check if node allows/forbids it |
40 local node_capabilities = node_obj and node_obj.capabilities; | 42 local node_capabilities = node_obj and node_obj.capabilities; |
41 if node_capabilities then | 43 if node_capabilities then |
42 local caps = node_capabilities[node_aff or service_aff]; | 44 local caps = node_capabilities[node_aff or service_aff]; |
43 if caps then | 45 if caps then |
45 if can ~= nil then | 47 if can ~= nil then |
46 return can; | 48 return can; |
47 end | 49 end |
48 end | 50 end |
49 end | 51 end |
50 | 52 |
51 -- Check service-wide capabilities instead | 53 -- Check service-wide capabilities instead |
52 local service_capabilities = self.config.capabilities; | 54 local service_capabilities = self.config.capabilities; |
53 local caps = service_capabilities[node_aff or service_aff]; | 55 local caps = service_capabilities[node_aff or service_aff]; |
54 if caps then | 56 if caps then |
55 local can = caps[action]; | 57 local can = caps[action]; |
56 if can ~= nil then | 58 if can ~= nil then |
57 return can; | 59 return can; |
58 end | 60 end |
59 end | 61 end |
60 | 62 |
61 return false; | 63 return false; |
62 end | 64 end |
63 | 65 |
64 function service:set_affiliation(node, actor, jid, affiliation) | 66 function service:set_affiliation(node, actor, jid, affiliation) |
65 -- Access checking | 67 -- Access checking |
209 end | 211 end |
210 -- | 212 -- |
211 if self.nodes[node] then | 213 if self.nodes[node] then |
212 return false, "conflict"; | 214 return false, "conflict"; |
213 end | 215 end |
214 | 216 |
217 self.data[node] = {}; | |
215 self.nodes[node] = { | 218 self.nodes[node] = { |
216 name = node; | 219 name = node; |
217 subscribers = {}; | 220 subscribers = {}; |
218 config = {}; | 221 config = {}; |
219 data = {}; | |
220 affiliations = {}; | 222 affiliations = {}; |
221 }; | 223 }; |
224 setmetatable(self.nodes[node], { __index = { data = self.data[node] } }); -- COMPAT | |
225 self.events.fire_event("node-created", { node = node, actor = actor }); | |
222 local ok, err = self:set_affiliation(node, true, actor, "owner"); | 226 local ok, err = self:set_affiliation(node, true, actor, "owner"); |
223 if not ok then | 227 if not ok then |
224 self.nodes[node] = nil; | 228 self.nodes[node] = nil; |
229 self.data[node] = nil; | |
225 end | 230 end |
226 return ok, err; | 231 return ok, err; |
227 end | 232 end |
228 | 233 |
229 function service:delete(node, actor) | 234 function service:delete(node, actor) |
235 local node_obj = self.nodes[node]; | 240 local node_obj = self.nodes[node]; |
236 if not node_obj then | 241 if not node_obj then |
237 return false, "item-not-found"; | 242 return false, "item-not-found"; |
238 end | 243 end |
239 self.nodes[node] = nil; | 244 self.nodes[node] = nil; |
245 self.data[node] = nil; | |
246 self.events.fire_event("node-deleted", { node = node, actor = actor }); | |
240 self.config.broadcaster("delete", node, node_obj.subscribers); | 247 self.config.broadcaster("delete", node, node_obj.subscribers); |
241 return true; | 248 return true; |
249 end | |
250 | |
251 local function remove_item_by_id(data, id) | |
252 if not data[id] then return end | |
253 data[id] = nil; | |
254 for i, _id in ipairs(data) do | |
255 if id == _id then | |
256 t_remove(data, i); | |
257 return i; | |
258 end | |
259 end | |
242 end | 260 end |
243 | 261 |
244 function service:publish(node, actor, id, item) | 262 function service:publish(node, actor, id, item) |
245 -- Access checking | 263 -- Access checking |
246 if not self:may(node, actor, "publish") then | 264 if not self:may(node, actor, "publish") then |
256 if not ok then | 274 if not ok then |
257 return ok, err; | 275 return ok, err; |
258 end | 276 end |
259 node_obj = self.nodes[node]; | 277 node_obj = self.nodes[node]; |
260 end | 278 end |
261 node_obj.data[id] = item; | 279 local node_data = self.data[node]; |
280 remove_item_by_id(node_data, id); | |
281 node_data[#self.data[node] + 1] = id; | |
282 node_data[id] = item; | |
262 self.events.fire_event("item-published", { node = node, actor = actor, id = id, item = item }); | 283 self.events.fire_event("item-published", { node = node, actor = actor, id = id, item = item }); |
263 self.config.broadcaster("items", node, node_obj.subscribers, item); | 284 self.config.broadcaster("items", node, node_obj.subscribers, item); |
264 return true; | 285 return true; |
265 end | 286 end |
266 | 287 |
269 if not self:may(node, actor, "retract") then | 290 if not self:may(node, actor, "retract") then |
270 return false, "forbidden"; | 291 return false, "forbidden"; |
271 end | 292 end |
272 -- | 293 -- |
273 local node_obj = self.nodes[node]; | 294 local node_obj = self.nodes[node]; |
274 if (not node_obj) or (not node_obj.data[id]) then | 295 if (not node_obj) or (not self.data[node][id]) then |
275 return false, "item-not-found"; | 296 return false, "item-not-found"; |
276 end | 297 end |
277 node_obj.data[id] = nil; | 298 self.events.fire_event("item-retracted", { node = node, actor = actor, id = id }); |
299 remove_item_by_id(self.data[node], id); | |
278 if retract then | 300 if retract then |
279 self.config.broadcaster("items", node, node_obj.subscribers, retract); | 301 self.config.broadcaster("items", node, node_obj.subscribers, retract); |
280 end | 302 end |
281 return true | 303 return true |
282 end | 304 end |
289 -- | 311 -- |
290 local node_obj = self.nodes[node]; | 312 local node_obj = self.nodes[node]; |
291 if not node_obj then | 313 if not node_obj then |
292 return false, "item-not-found"; | 314 return false, "item-not-found"; |
293 end | 315 end |
294 node_obj.data = {}; -- Purge | 316 self.data[node] = {}; -- Purge |
317 self.events.fire_event("node-purged", { node = node, actor = actor }); | |
295 if notify then | 318 if notify then |
296 self.config.broadcaster("purge", node, node_obj.subscribers); | 319 self.config.broadcaster("purge", node, node_obj.subscribers); |
297 end | 320 end |
298 return true | 321 return true |
299 end | 322 end |
307 local node_obj = self.nodes[node]; | 330 local node_obj = self.nodes[node]; |
308 if not node_obj then | 331 if not node_obj then |
309 return false, "item-not-found"; | 332 return false, "item-not-found"; |
310 end | 333 end |
311 if id then -- Restrict results to a single specific item | 334 if id then -- Restrict results to a single specific item |
312 return true, { [id] = node_obj.data[id] }; | 335 return true, { id, [id] = self.data[node][id] }; |
313 else | 336 else |
314 return true, node_obj.data; | 337 return true, self.data[node]; |
315 end | 338 end |
316 end | 339 end |
317 | 340 |
318 function service:get_nodes(actor) | 341 function service:get_nodes(actor) |
319 -- Access checking | 342 -- Access checking |