util.stanza: Iterate on childtags instead of all childs.
[prosody.git] / util / pubsub.lua
index 8f6af2fdd2f65bb633e648ce774d4dcde1d774d5..811f4a154c3ddbb25ef73183fc9020efcc9cf48e 100644 (file)
@@ -1,68 +1,84 @@
--- 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.
---
+module("pubsub", package.seeall);
 
+local service = {};
+local service_mt = { __index = service };
 
-local ipairs, pairs, setmetatable, type = 
-        ipairs, pairs, setmetatable, type;
-
-module "pubsub"
+function new(cb)
+       return setmetatable({ cb = cb or {}, nodes = {} }, service_mt);
+end
 
-local pubsub_node_mt = { __index = _M };
+function service:add_subscription(node, actor, jid)
+       local node_obj = self.nodes[node];
+       if not node_obj then
+               return false, "item-not-found";
+       end
+       node_obj.subscribers[jid] = true;
+       return true;
+end
 
-function new_node(name)
-       return setmetatable({ name = name, subscribers = {} }, pubsub_node_mt);
+function service:remove_subscription(node, actor, jid)
+       local node_obj = self.nodes[node];
+       if not node_obj then
+               return false, "item-not-found";
+       end
+       if not node_obj.subscribers[jid] then
+               return false, "not-subscribed";
+       end
+       node_obj.subscribers[jid] = nil;
+       return true;
 end
 
-function set_subscribers(node, subscribers_list, list_type)
-       local subscribers = node.subscribers;
-       
-       if list_type == "array" then
-               for _, jid in ipairs(subscribers_list) do
-                       if not subscribers[jid] then
-                               node:add_subscriber(jid);
-                       end
-               end
-       elseif (not list_type) or list_type == "set" then
-               for jid in pairs(subscribers_list) do
-                       if type(jid) == "string" then
-                               node:add_subscriber(jid);
-                       end
-               end
+function service:get_subscription(node, actor, jid)
+       local node_obj = self.nodes[node];
+       if node_obj then
+               return node_obj.subscribers[jid];
        end
 end
 
-function get_subscribers(node)
-       return node.subscribers;
+function service:create(node, actor)
+       if not self.nodes[node] then
+               self.nodes[node] = { name = node, subscribers = {}, config = {}, data = {} };
+               return true;
+       end
+       return false, "conflict";
 end
 
-function publish(node, item, dispatcher, data)
-       local subscribers = node.subscribers;
-       for i = 1,#subscribers do
-               item.attr.to = subscribers[i];
-               dispatcher(data, item);
+function service:publish(node, actor, id, item)
+       local node_obj = self.nodes[node];
+       if not node_obj then
+               node_obj = { name = node, subscribers = {}, config = {}, data = {} };
+               self.nodes[node] = node_obj;
        end
+       node_obj.data[id] = item;
+       self.cb.broadcaster(node, node_obj.subscribers, item);
+       return true;
 end
 
-function add_subscriber(node, jid)
-       local subscribers = node.subscribers;
-       if not subscribers[jid] then
-               local space = #subscribers;
-               subscribers[space] = jid;
-               subscribers[jid] = space;
+function service:retract(node, actor, id, retract)
+       local node_obj = self.nodes[node];
+       if (not node_obj) or (not node_obj.data[id]) then
+               return false, "item-not-found";
+       end
+       node_obj.data[id] = nil;
+       if retract then
+               self.cb.broadcaster(node, node_obj.subscribers, retract);
        end
+       return true
 end
 
-function remove_subscriber(node, jid)
-       local subscribers = node.subscribers;
-       if subscribers[jid] then
-               subscribers[subscribers[jid]] = nil;
-               subscribers[jid] = nil;
+function service:get(node, actor, id)
+       local node_obj = self.nodes[node];
+       if node_obj then
+               if id then
+                       return { node_obj.data[id] };
+               else
+                       return node_obj.data;
+               end
        end
 end
 
+function service:get_nodes(actor)
+       return true, self.nodes;
+end
+
 return _M;