Mercurial > prosody-hg
comparison util/pubsub.lua @ 5973:905b4fd863b4
Merge 0.10->trunk and Happy New Year!
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 31 Dec 2013 19:09:34 +0100 |
| parents | cdcfd93e2f43 f365d3c8fd2c |
| children | 0f4025abbe8f |
comparison
equal
deleted
inserted
replaced
| 5967:3b7206981317 | 5973:905b4fd863b4 |
|---|---|
| 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) |
| 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[#node_obj.data + 1] = id; | 279 local node_data = self.data[node]; |
| 262 node_obj.data[id] = item; | 280 remove_item_by_id(node_data, id); |
| 281 node_data[#self.data[node] + 1] = id; | |
| 282 node_data[id] = item; | |
| 263 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 }); |
| 264 self.config.broadcaster("items", node, node_obj.subscribers, item); | 284 self.config.broadcaster("items", node, node_obj.subscribers, item); |
| 265 return true; | 285 return true; |
| 266 end | 286 end |
| 267 | 287 |
| 270 if not self:may(node, actor, "retract") then | 290 if not self:may(node, actor, "retract") then |
| 271 return false, "forbidden"; | 291 return false, "forbidden"; |
| 272 end | 292 end |
| 273 -- | 293 -- |
| 274 local node_obj = self.nodes[node]; | 294 local node_obj = self.nodes[node]; |
| 275 if (not node_obj) or (not node_obj.data[id]) then | 295 if (not node_obj) or (not self.data[node][id]) then |
| 276 return false, "item-not-found"; | 296 return false, "item-not-found"; |
| 277 end | 297 end |
| 278 node_obj.data[id] = nil; | 298 self.events.fire_event("item-retracted", { node = node, actor = actor, id = id }); |
| 279 for i, _id in ipairs(node_obj.data) do | 299 remove_item_by_id(self.data[node], id); |
| 280 if id == _id then | |
| 281 table.remove(node_obj, i); | |
| 282 break; | |
| 283 end | |
| 284 end | |
| 285 if retract then | 300 if retract then |
| 286 self.config.broadcaster("items", node, node_obj.subscribers, retract); | 301 self.config.broadcaster("items", node, node_obj.subscribers, retract); |
| 287 end | 302 end |
| 288 return true | 303 return true |
| 289 end | 304 end |
| 296 -- | 311 -- |
| 297 local node_obj = self.nodes[node]; | 312 local node_obj = self.nodes[node]; |
| 298 if not node_obj then | 313 if not node_obj then |
| 299 return false, "item-not-found"; | 314 return false, "item-not-found"; |
| 300 end | 315 end |
| 301 node_obj.data = {}; -- Purge | 316 self.data[node] = {}; -- Purge |
| 317 self.events.fire_event("node-purged", { node = node, actor = actor }); | |
| 302 if notify then | 318 if notify then |
| 303 self.config.broadcaster("purge", node, node_obj.subscribers); | 319 self.config.broadcaster("purge", node, node_obj.subscribers); |
| 304 end | 320 end |
| 305 return true | 321 return true |
| 306 end | 322 end |
| 314 local node_obj = self.nodes[node]; | 330 local node_obj = self.nodes[node]; |
| 315 if not node_obj then | 331 if not node_obj then |
| 316 return false, "item-not-found"; | 332 return false, "item-not-found"; |
| 317 end | 333 end |
| 318 if id then -- Restrict results to a single specific item | 334 if id then -- Restrict results to a single specific item |
| 319 return true, { id, [id] = node_obj.data[id] }; | 335 return true, { id, [id] = self.data[node][id] }; |
| 320 else | 336 else |
| 321 return true, node_obj.data; | 337 return true, self.data[node]; |
| 322 end | 338 end |
| 323 end | 339 end |
| 324 | 340 |
| 325 function service:get_nodes(actor) | 341 function service:get_nodes(actor) |
| 326 -- Access checking | 342 -- Access checking |
