Merge 0.10->trunk
[prosody.git] / plugins / mod_pep_plus.lua
index 4a74e437ed475f7797ccff0ff4e7ba48a19ecbf7..f45d5ef3d7772b988bb487d97cf85aabf0703608 100644 (file)
@@ -14,6 +14,8 @@ local lib_pubsub = module:require "pubsub";
 local handlers = lib_pubsub.handlers;
 local pubsub_error_reply = lib_pubsub.pubsub_error_reply;
 
+local empty_set = set_new();
+
 local services = {};
 local recipients = {};
 local hash_map = {};
@@ -52,11 +54,12 @@ local function get_broadcaster(name)
        return simple_broadcast;
 end
 
-local function get_pep_service(name)
-       if services[name] then
-               return services[name];
+function get_pep_service(name)
+       local service = services[name];
+       if service then
+               return service;
        end
-       services[name] = pubsub.new({
+       service = pubsub.new({
                capabilities = {
                        none = {
                                create = false;
@@ -130,6 +133,7 @@ local function get_pep_service(name)
                                retract = true;
                                delete = true;
                                get_nodes = true;
+                               configure = true;
 
                                subscribe = true;
                                unsubscribe = true;
@@ -150,6 +154,10 @@ local function get_pep_service(name)
                        };
                };
 
+               node_defaults = {
+                       ["pubsub#max_items"] = "1";
+               };
+
                autocreate_on_publish = true;
                autocreate_on_subscribe = true;
 
@@ -164,7 +172,9 @@ local function get_pep_service(name)
 
                normalize_jid = jid_bare;
        });
-       return services[name];
+       services[name] = service;
+       module:add_item("pep-service", { service = service, jid = name });
+       return service;
 end
 
 function handle_pubsub_iq(event)
@@ -222,22 +232,37 @@ end
 
 local function update_subscriptions(recipient, service_name, nodes)
        local service = get_pep_service(service_name);
+       nodes = nodes or empty_set;
 
-       recipients[service_name] = recipients[service_name] or {};
-       nodes = nodes or set_new();
-       local old = recipients[service_name][recipient];
+       local service_recipients = recipients[service_name];
+       if not service_recipients then
+               service_recipients = {};
+               recipients[service_name] = service_recipients;
+       end
 
-       if old and type(old) == table then
-               for node in pairs((old - nodes):items()) do
-                       service:remove_subscription(node, recipient, recipient);
-               end
+       local current = service_recipients[recipient];
+       if not current or type(current) ~= "table" then
+               current = empty_set;
        end
 
-       for node in nodes:items() do
+       if (current == empty_set or current:empty()) and (nodes == empty_set or nodes:empty()) then
+               return;
+       end
+
+       for node in current - nodes do
+               service:remove_subscription(node, recipient, recipient);
+       end
+
+       for node in nodes - current do
                service:add_subscription(node, recipient, recipient);
                resend_last_item(recipient, node, service);
        end
-       recipients[service_name][recipient] = nodes;
+
+       if nodes == empty_set or nodes:empty() then
+               nodes = nil;
+       end
+
+       service_recipients[recipient] = nodes;
 end
 
 module:hook("presence/bare", function(event)