25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-22 17:28:25 +01:00

pubsub presence handler bugfix

SVN Revision: 1068
This commit is contained in:
Christophe Romain 2007-12-12 16:16:00 +00:00
parent ca894f8ad8
commit 348427fab0
4 changed files with 69 additions and 97 deletions

View File

@ -1,3 +1,8 @@
2007-12-12 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: presence handler bugfix
* src/mod_pubsub/node_default.erl: Allow send last item on presence
2007-12-12 Badlop <badlop@process-one.net>
* src/msgs/it.msg: Updated (thanks to Luca Brivio)

View File

@ -458,56 +458,55 @@ handle_cast({presence, From, To, Packet}, State) ->
end,
if PreviouslyAvailable == false,
PresenceType == available ->
%% A new resource is available. Loop through all nodes
%% and see if the contact is subscribed, and if so, and if
%% the node is so configured, send the last item.
Host = From#jid.lserver,
%% A new resource is available. Loop through all subscriptions
%% and if the node is so configured, send the last item.
JID = jlib:jid_tolower(From),
Host = State#state.host,
ServerHost = State#state.server_host,
lists:foreach(
fun(Type) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]),
lists:foreach(
fun(Type) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, From]),
Options = node_options(Type),
SendLast = get_option(Options, send_last_published_item),
AccessModel = get_option(Options, access_model),
AllowedGroups = get_option(Options, roster_groups_allowed),
lists:foreach(
fun({Node, Subscription}) ->
Options = node_options(Type),
SendLast = get_option(Options, send_last_published_item),
if
Subscription /= none, Subscription /= pending, SendLast == on_sub_and_presence ->
send_last_item(Host, Node, JID);
SendLast == on_sub_and_presence ->
AccessModel = get_option(Options, access_model),
AllowedGroups = get_option(Options, roster_groups_allowed),
{PresenceSubscription, RosterGroup} = get_roster_info(
To#jid.luser, To#jid.lserver, JID, AllowedGroups),
Features = case catch mod_caps:get_features(Host, mod_caps:read_caps(element(4, Packet))) of
F when is_list(F) -> F;
_ -> []
end,
case lists:member(Node ++ "+notify", Features) of
true ->
MaySubscribe =
case AccessModel of
open -> true;
presence -> PresenceSubscription;
whitelist -> false; % subscribers are added manually
authorize -> false; % likewise
roster -> RosterGroup
end,
if MaySubscribe ->
send_last_item(
Host, Node, JID);
true ->
ok
end;
false ->
ok
end;
true ->
ok
end;
(_) ->
ok
end, Subscriptions)
end, Plugins),
if
Subscription /= none, Subscription /= pending, SendLast == on_sub_and_presence ->
send_last_item(Host, Node, JID);
SendLast == on_sub_and_presence ->
{PresenceSubscription, RosterGroup} = get_roster_info(
To#jid.luser, To#jid.lserver, JID, AllowedGroups),
Features = case catch mod_caps:get_features(ServerHost, mod_caps:read_caps(element(4, Packet))) of
F when is_list(F) -> F;
_ -> []
end,
case lists:member(Node ++ "+notify", Features) of
true ->
MaySubscribe =
case AccessModel of
open -> true;
presence -> PresenceSubscription;
whitelist -> false; % subscribers are added manually
authorize -> false; % likewise
roster -> RosterGroup
end,
if MaySubscribe ->
send_last_item(Host, Node, JID);
true ->
ok
end;
false ->
ok
end;
true ->
ok
end;
(_) ->
ok
end, Subscriptions)
end, Plugins),
{noreply, State};
true ->
{noreply, State}
@ -517,46 +516,6 @@ handle_cast({set_presence, _User, _Server, _Resource, _Presence}, State) ->
{noreply, State};
handle_cast({unset_presence, _User, _Server, _Resource, _Status}, State) ->
{noreply, State};
% Owner = jlib:jid_tolower(jlib:jid_remove_resource(#jid{luser = User, lserver = Server, lresource = Resource})),
% JID = User ++ "@" ++ Server ++ "/" ++ Resource,
% F = fun() ->
% case mnesia:dirty_match_object(#pubsub_state{stateid = {Owner, '_'}, _ = '_'}) of
% [] ->
% {error, ?ERR_ITEM_NOT_FOUND};
% States ->
% {result, lists:foldl(
% fun(#pubsub_state{stateid = {_, {Host, Node}}, items = Items} = S, ItemsList) ->
% %% To make this code work for nodetree_default system, we must be sure node type is correct
% %% this can be done asking a match {Host, Node} when Type=this_module_type
% %% case mnesia:dirty_match_object(#pubsub_node{nodeid={Host, Node}, type=virtual, _ = '_'})
% %% this call should be handled by the nodetree plugin
% %% but at this stage we don't know what is the actual nodetree plugin
% %% this must be implemented into the API, mod_pubsub telling us what is the nodetree plugin
% NewItems = lists:filter(fun(ItemID) -> ItemID /= JID end, Items),
% if NewItems /= Items ->
% mnesia:dirty_write(S#pubsub_state{items = NewItems}),
% Key = {JID, {Host, Node}},
% mnesia:dirty_delete({pubsub_item, Key}),
% ItemsList ++ [Key];
% true ->
% ItemsList
% end
% end, [], States)}
% end
% end,
% case catch mnesia:sync_dirty(F) of
% {'EXIT', Reason} ->
% {error, Reason};
% {error, Reason} ->
% {error, Reason};
% {result, Items} ->
% lists:foreach(fun({ItemID, {Host, Node}}) ->
% mod_pubsub:broadcast_retract_item(Host, Node, ItemID)
% end, Items),
% {result, []};
% _ ->
% {error, ?ERR_INTERNAL_SERVER_ERROR}
% end.
handle_cast(_Msg, State) ->
{noreply, State}.
@ -2327,7 +2286,7 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
LookingFor = Node ++ "+notify",
lists:foreach(
fun({JID, Caps}) ->
case catch mod_caps:get_features(?MYNAME, Caps) of
case catch mod_caps:get_features(LServer, Caps) of
Features when is_list(Features) ->
case lists:member(LookingFor, Features) of
true ->

View File

@ -130,7 +130,7 @@ options() ->
{access_roster_groups, []},
{publish_model, publishers},
{max_payload_size, ?MAX_PAYLOAD_SIZE},
{send_last_published_item, never},
{send_last_published_item, on_sub_and_presence},
{deliver_notifications, true},
{presence_based_delivery, false}].

View File

@ -131,28 +131,36 @@ purge_node(Host, Node, Owner) ->
node_default:purge_node(Host, Node, Owner).
get_entity_affiliations(Host, Owner) ->
node_default:get_entity_affiliations(Host, Owner).
%node_default:get_entity_affiliations(Host, Owner).
{result, []}.
get_node_affiliations(Host, Node) ->
node_default:get_node_affiliations(Host, Node).
%node_default:get_node_affiliations(Host, Node).
{result, []}.
get_affiliation(Host, Node, Owner) ->
node_default:get_affiliation(Host, Node, Owner).
%node_default:get_affiliation(Host, Node, Owner).
{result, unknown}.
set_affiliation(Host, Node, Owner, Affiliation) ->
node_default:set_affiliation(Host, Node, Owner, Affiliation).
%node_default:set_affiliation(Host, Node, Owner, Affiliation).
ok.
get_entity_subscriptions(Host, Owner) ->
node_default:get_entity_subscriptions(Host, Owner).
%node_default:get_entity_subscriptions(Host, Owner).
{result, []}.
get_node_subscriptions(Host, Node) ->
node_default:get_node_subscriptions(Host, Node).
%node_default:get_node_subscriptions(Host, Node).
{result, []}.
get_subscription(Host, Node, Owner) ->
node_default:get_subscription(Host, Node, Owner).
%node_default:get_subscription(Host, Node, Owner).
{result, unknown}.
set_subscription(Host, Node, Owner, Subscription) ->
node_default:set_subscription(Host, Node, Owner, Subscription).
%node_default:set_subscription(Host, Node, Owner, Subscription).
ok.
get_states(Host, Node) ->
node_default:get_states(Host, Node).