Merge 0.9->0.10
authorKim Alvefur <zash@zash.se>
Sun, 22 May 2016 12:39:14 +0000 (14:39 +0200)
committerKim Alvefur <zash@zash.se>
Sun, 22 May 2016 12:39:14 +0000 (14:39 +0200)
1  2 
plugins/mod_presence.lua

diff --combined plugins/mod_presence.lua
index 5e1eb404334f25fed64eec7dbfb12b04d59fcb96,a5b4f282a4da5635cedf7b81f7e86ac5c9bc17de..cf762edc880cf6c5cfa8a05fbb8d0015aadf094f
@@@ -1,7 -1,7 +1,7 @@@
  -- Prosody IM
  -- Copyright (C) 2008-2010 Matthew Wild
  -- Copyright (C) 2008-2010 Waqas Hussain
 --- 
 +--
  -- This project is MIT/X11 licensed. Please see the
  -- COPYING file in the source package for more information.
  --
@@@ -10,7 -10,7 +10,7 @@@ local log = module._log
  
  local require = require;
  local pairs = pairs;
 -local t_concat, t_insert = table.concat, table.insert;
 +local t_concat = table.concat;
  local s_find = string.find;
  local tonumber = tonumber;
  
@@@ -27,20 -27,42 +27,20 @@@ local NULL = {}
  local rostermanager = require "core.rostermanager";
  local sessionmanager = require "core.sessionmanager";
  
 -local function select_top_resources(user)
 -      local priority = 0;
 -      local recipients = {};
 -      for _, session in pairs(user.sessions) do -- find resource with greatest priority
 -              if session.presence then
 -                      -- TODO check active privacy list for session
 -                      local p = session.priority;
 -                      if p > priority then
 -                              priority = p;
 -                              recipients = {session};
 -                      elseif p == priority then
 -                              t_insert(recipients, session);
 -                      end
 -              end
 -      end
 -      return recipients;
 -end
 -local function recalc_resource_map(user)
 -      if user then
 -              user.top_resources = select_top_resources(user);
 -              if #user.top_resources == 0 then user.top_resources = nil; end
 -      end
 -end
 +local recalc_resource_map = require "util.presence".recalc_resource_map;
  
 -local ignore_presence_priority = module:get_option("ignore_presence_priority");
 +local ignore_presence_priority = module:get_option_boolean("ignore_presence_priority", false);
  
  function handle_normal_presence(origin, stanza)
        if ignore_presence_priority then
 -              local priority = stanza:child_with_name("priority");
 +              local priority = stanza:get_child("priority");
                if priority and priority[1] ~= "0" then
                        for i=#priority.tags,1,-1 do priority.tags[i] = nil; end
                        for i=#priority,1,-1 do priority[i] = nil; end
                        priority[1] = "0";
                end
        end
 -      local priority = stanza:child_with_name("priority");
 +      local priority = stanza:get_child("priority");
        if priority and #priority > 0 then
                priority = t_concat(priority);
                if s_find(priority, "^[+-]?[0-9]+$") then
@@@ -68,7 -90,6 +68,7 @@@
                end
        end
        if stanza.attr.type == nil and not origin.presence then -- initial presence
 +              module:fire_event("presence/initial", { origin = origin, stanza = stanza } );
                origin.presence = stanza; -- FIXME repeated later
                local probe = st.presence({from = origin.full_jid, type = "probe"});
                for jid, item in pairs(roster) do -- probe all contacts we are subscribed to
                                res.presence.attr.to = nil;
                        end
                end
 -              if roster.pending then -- resend incoming subscription requests
 -                      for jid in pairs(roster.pending) do
 -                              origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original?
 -                      end
 +              for jid in pairs(roster[false].pending) do -- resend incoming subscription requests
 +                      origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original?
                end
                local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host});
                for jid, item in pairs(roster) do -- resend outgoing subscription requests
@@@ -178,6 -201,7 +178,7 @@@ function handle_outbound_presence_subsc
                end
                core_post_stanza(origin, stanza);
                send_presence_of_available_resources(node, host, to_bare, origin);
+               core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare }));
        elseif stanza.attr.type == "unsubscribed" then
                -- 1. send unavailable
                -- 2. route stanza
@@@ -204,7 -228,7 +205,7 @@@ function handle_inbound_presence_subscr
        local st_from, st_to = stanza.attr.from, stanza.attr.to;
        stanza.attr.from, stanza.attr.to = from_bare, to_bare;
        log("debug", "inbound presence %s from %s for %s", stanza.attr.type, from_bare, to_bare);
 -      
 +
        if stanza.attr.type == "probe" then
                local result, err = rostermanager.is_contact_subscribed(node, host, from_bare);
                if result then
@@@ -289,7 -313,7 +290,7 @@@ module:hook("presence/bare", function(d
                if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes sent to bare JID
                        return handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to));
                end
 -      
 +
                local user = bare_sessions[to];
                if user then
                        for _, session in pairs(user.sessions) do
@@@ -324,7 -348,7 +325,7 @@@ end)
  module:hook("presence/host", function(data)
        -- inbound presence to the host
        local stanza = data.stanza;
 -      
 +
        local from_bare = jid_bare(stanza.attr.from);
        local t = stanza.attr.type;
        if t == "probe" then
@@@ -357,27 -381,3 +358,27 @@@ module:hook("resource-unbind", function
                session.directed = nil;
        end
  end);
 +
 +module:hook("roster-item-removed", function (event)
 +      local username = event.username;
 +      local session = event.origin;
 +      local roster = event.roster or session and session.roster;
 +      local jid = event.jid;
 +      local item = event.item;
 +      local from_jid = session.full_jid or (username .. "@" .. module.host);
 +
 +      local subscription = item and item.subscription or "none";
 +      local ask = item and item.ask;
 +      local pending = roster and roster[false].pending[jid];
 +
 +      if subscription == "both" or subscription == "from" or pending then
 +              core_post_stanza(session, st.presence({type="unsubscribed", from=from_jid, to=jid}));
 +      end
 +
 +      if subscription == "both" or subscription == "to" or ask then
 +              send_presence_of_available_resources(username, module.host, jid, session, st.presence({type="unavailable"}));
 +              core_post_stanza(session, st.presence({type="unsubscribe", from=from_jid, to=jid}));
 +      end
 +
 +end, -1);
 +