From 0f964142799cd987b612dc2134c7a11573ab80b7 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Tue, 7 Jul 2015 00:24:06 +0200 Subject: [PATCH] Trigger PEP notifications on CAPS updates Let mod_pubsub send last items whenever a contact updates the entity capabilities. This was already done for remote contacts and is now also done for local contacts. --- src/mod_caps.erl | 39 ++++++++++++++++++--------------------- src/mod_pubsub.erl | 23 +++++++++++++++-------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 4d166ce70..6d647908c 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -243,27 +243,24 @@ c2s_presence_in(C2SState, error -> gb_trees:empty() end, Caps = read_caps(Els), - {CapsUpdated, NewRs} = case Caps of - nothing when Insert == true -> {false, Rs}; - _ when Insert == true -> - case gb_trees:lookup(LFrom, Rs) of - {value, Caps} -> {false, Rs}; - none -> - {true, - gb_trees:insert(LFrom, Caps, - Rs)}; - _ -> - {true, - gb_trees:update(LFrom, Caps, Rs)} - end; - _ -> {false, gb_trees:delete_any(LFrom, Rs)} - end, - if CapsUpdated -> - ejabberd_hooks:run(caps_update, To#jid.lserver, - [From, To, - get_features(To#jid.lserver, Caps)]); - true -> ok - end, + NewRs = case Caps of + nothing when Insert == true -> Rs; + _ when Insert == true -> + case gb_trees:lookup(LFrom, Rs) of + {value, Caps} -> Rs; + none -> + ejabberd_hooks:run(caps_add, To#jid.lserver, + [From, To, + get_features(To#jid.lserver, Caps)]), + gb_trees:insert(LFrom, Caps, Rs); + _ -> + ejabberd_hooks:run(caps_update, To#jid.lserver, + [From, To, + get_features(To#jid.lserver, Caps)]), + gb_trees:update(LFrom, Caps, Rs) + end; + _ -> gb_trees:delete_any(LFrom, Rs) + end, ejabberd_c2s:set_aux_field(caps_resources, NewRs, C2SState); true -> C2SState diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index ee6407793..218445cfb 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -62,7 +62,7 @@ -define(PEPNODE, <<"pep">>). %% exports for hooks --export([presence_probe/3, caps_update/3, +-export([presence_probe/3, caps_add/3, caps_update/3, in_subscription/6, out_subscription/4, on_user_offline/3, remove_user/2, disco_local_identity/5, disco_local_features/5, @@ -293,6 +293,8 @@ init([ServerHost, Opts]) -> ?MODULE, remove_user, 50), case lists:member(?PEPNODE, Plugins) of true -> + ejabberd_hooks:add(caps_add, ServerHost, + ?MODULE, caps_add, 80), ejabberd_hooks:add(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:add(disco_sm_identity, ServerHost, @@ -683,21 +685,24 @@ disco_items(Host, Node, From) -> %% presence hooks handling functions %% -caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) +caps_add(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) when Host =/= S -> %% When a remote contact goes online while the local user is offline, the %% remote contact won't receive last items from the local user even if %% ignore_pep_from_offline is set to false. To work around this issue a bit, %% we'll also send the last items to remote contacts when the local user - %% connects. That's the reason to use the caps_update hook instead of the + %% connects. That's the reason to use the caps_add hook instead of the %% presence_probe_hook for remote contacts: The latter is only called when a - %% contact becomes available; the former also is also executed when the - %% local user goes online (because that triggers the contact to send a - %% presence packet with CAPS). + %% contact becomes available; the former is also executed when the local + %% user goes online (because that triggers the contact to send a presence + %% packet with CAPS). presence(Host, {presence, U, S, [R], JID}); -caps_update(_From, _To, _Feature) -> +caps_add(_From, _To, _Feature) -> ok. +caps_update(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = Host} = JID, _Features) -> + presence(Host, {presence, U, S, [R], JID}). + presence_probe(#jid{luser = U, lserver = S, lresource = R} = JID, JID, Pid) -> presence(S, {presence, JID, Pid}), presence(S, {presence, U, S, [R], JID}); @@ -709,7 +714,7 @@ presence_probe(#jid{luser = U, lserver = S, lresource = R}, #jid{lserver = S} = presence(S, {presence, U, S, [R], JID}); presence_probe(_Host, _JID, _Pid) -> %% ignore presence_probe from remote contacts, - %% those are handled via caps_update + %% those are handled via caps_add ok. presence(ServerHost, Presence) -> @@ -881,6 +886,8 @@ terminate(_Reason, ejabberd_router:unregister_route(Host), case lists:member(?PEPNODE, Plugins) of true -> + ejabberd_hooks:delete(caps_add, ServerHost, + ?MODULE, caps_add, 80), ejabberd_hooks:delete(caps_update, ServerHost, ?MODULE, caps_update, 80), ejabberd_hooks:delete(disco_sm_identity, ServerHost,