From f0f4b2719cb80d0f8484ef0f67e0f5ff371018df Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 12 May 2010 13:54:44 +0200 Subject: [PATCH] sync pubsub_odbc with latest code --- src/mod_pubsub/mod_pubsub_odbc.erl | 86 +++++++++++++++++++++++++----- src/mod_pubsub/pubsub_odbc.patch | 20 +++---- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/mod_pubsub/mod_pubsub_odbc.erl b/src/mod_pubsub/mod_pubsub_odbc.erl index e1753a45f..63e2277ad 100644 --- a/src/mod_pubsub/mod_pubsub_odbc.erl +++ b/src/mod_pubsub/mod_pubsub_odbc.erl @@ -2677,15 +2677,66 @@ node_to_deliver(LJID, NodeOptions) -> presence_can_deliver(LJID, PresenceDelivery). presence_can_deliver(_, false) -> true; -presence_can_deliver({User, Server, _}, true) -> +presence_can_deliver({User, Server, Resource}, true) -> case mnesia:dirty_match_object({session, '_', '_', {User, Server}, '_', '_'}) of [] -> false; Ss -> - lists:foldl(fun({session, _, _, _, undefined, _}, Acc) -> Acc; - ({session, _, _, _, _Priority, _}, _Acc) -> true + lists:foldl(fun(_, true) -> true; + ({session, _, _ , _, undefined, _}, _Acc) -> false; + ({session, _, {_, _, R}, _, _Priority, _}, _Acc) -> + case Resource of + [] -> true; + R -> true; + _ -> false + end end, false, Ss) end. +state_can_deliver({U, S, R}, []) -> [{U, S, R}]; +state_can_deliver({U, S, R}, SubOptions) -> + %% Check SubOptions for 'show_values' + case lists:keysearch('show_values', 1, SubOptions) of + %% If not in suboptions, item can be delivered, case doesn't apply + false -> [{U, S, R}]; + %% If in a suboptions ... + {_, {_, ShowValues}} -> + %% Get subscriber resources + Resources = case R of + %% If the subscriber JID is a bare one, get all its resources + [] -> user_resources(U, S); + %% If the subscriber JID is a full one, use its resource + R -> [R] + end, + %% For each resource, test if the item is allowed to be delivered + %% based on resource state + lists:foldl( + fun(Resource, Acc) -> + get_resource_state({U, S, Resource}, ShowValues, Acc) + end, [], Resources) + end. + +get_resource_state({U, S, R}, ShowValues, JIDs) -> + %% Get user session PID + case ejabberd_sm:get_session_pid(U, S, R) of + %% If no PID, item can be delivered + none -> lists:append([{U, S, R}], JIDs); + %% If PID ... + Pid -> + %% Get user resource state + %% TODO : add a catch clause + Show = case ejabberd_c2s:get_presence(Pid) of + {_, _, "available", _} -> "online"; + {_, _, State, _} -> State + end, + %% Is current resource state listed in 'show-values' suboption ? + case lists:member(Show, ShowValues) of %andalso Show =/= "online" of + %% If yes, item can be delivered + true -> lists:append([{U, S, R}], JIDs); + %% If no, item can't be delivered + false -> JIDs + end + end. + %% @spec (Payload) -> int() %% Payload = term() %% @doc

Count occurence of XML elements in payload.

@@ -2944,20 +2995,25 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> NodeOptions = Node#pubsub_node.options, lists:foldl(fun({LJID, SubID, SubOptions}, {JIDs, Recipients}) -> case is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) of - true -> - %% If is to deliver : - case lists:member(LJID, JIDs) of + true -> + %% If is to deliver : + case state_can_deliver(LJID, SubOptions) of + [] -> {JIDs, Recipients}; + JIDsToDeliver -> + lists:foldl( + fun(JIDToDeliver, {JIDsAcc, RecipientsAcc}) -> + case lists:member(JIDToDeliver, JIDs) of %% check if the JIDs co-accumulator contains the Subscription Jid, - false -> + false -> %% - if not, %% - add the Jid to JIDs list co-accumulator ; %% - create a tuple of the Jid, NodeId, and SubID (as list), %% and add the tuple to the Recipients list co-accumulator - {[LJID | JIDs], [{LJID, NodeName, [SubID]} | Recipients]}; - true -> + {[JIDToDeliver | JIDsAcc], [{JIDToDeliver, NodeName, [SubID]} | RecipientsAcc]}; + true -> %% - if the JIDs co-accumulator contains the Jid %% get the tuple containing the Jid from the Recipient list co-accumulator - {_, {LJID, NodeName1, SubIDs}} = lists:keysearch(LJID, 1, Recipients), + {_, {JIDToDeliver, NodeName1, SubIDs}} = lists:keysearch(JIDToDeliver, 1, RecipientsAcc), %% delete the tuple from the Recipients list % v1 : Recipients1 = lists:keydelete(LJID, 1, Recipients), % v2 : Recipients1 = lists:keyreplace(LJID, 1, Recipients, {LJID, NodeId1, [SubID | SubIDs]}), @@ -2966,17 +3022,19 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> % v1.1 : {JIDs, lists:append(Recipients1, [{LJID, NodeId1, lists:append(SubIDs, [SubID])}])} % v1.2 : {JIDs, [{LJID, NodeId1, [SubID | SubIDs]} | Recipients1]} % v2: {JIDs, Recipients1} - {JIDs, lists:keyreplace(LJID, 1, Recipients, {LJID, NodeName1, [SubID | SubIDs]})} - end; + {JIDsAcc, lists:keyreplace(JIDToDeliver, 1, RecipientsAcc, {JIDToDeliver, NodeName1, [SubID | SubIDs]})} + end + end, {JIDs, Recipients}, JIDsToDeliver) + end; false -> {JIDs, Recipients} end end, Acc, Subs) end, - DepthsToDeliver = fun({Depth, SubsByNode}, Acc) -> + DepthsToDeliver = fun({Depth, SubsByNode}, Acc1) -> lists:foldl(fun({Node, Subs}, Acc2) -> NodesToDeliver(Depth, Node, Subs, Acc2) - end, Acc, SubsByNode) + end, Acc1, SubsByNode) end, {_, JIDSubs} = lists:foldl(DepthsToDeliver, {[], []}, SubsByDepth), JIDSubs. diff --git a/src/mod_pubsub/pubsub_odbc.patch b/src/mod_pubsub/pubsub_odbc.patch index 6de093d02..f2b1f0ef6 100644 --- a/src/mod_pubsub/pubsub_odbc.patch +++ b/src/mod_pubsub/pubsub_odbc.patch @@ -1,5 +1,5 @@ ---- mod_pubsub.erl 2010-03-11 15:55:35.000000000 +0100 -+++ mod_pubsub_odbc.erl 2010-03-11 15:59:40.000000000 +0100 +--- mod_pubsub.erl 2010-05-12 13:54:26.000000000 +0200 ++++ mod_pubsub_odbc.erl 2010-05-12 13:54:33.000000000 +0200 @@ -42,7 +42,7 @@ %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. @@ -637,7 +637,7 @@ true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> -@@ -3023,7 +2832,7 @@ +@@ -3074,7 +2883,7 @@ {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, @@ -646,7 +646,7 @@ {result, CollSubs} -> CollSubs; _ -> [] end. -@@ -3037,9 +2846,9 @@ +@@ -3088,9 +2897,9 @@ get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> @@ -658,7 +658,7 @@ _ -> Acc end; (_, Acc) -> -@@ -3236,6 +3045,30 @@ +@@ -3294,6 +3103,30 @@ Result end. @@ -689,7 +689,7 @@ %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] -@@ -3631,7 +3464,13 @@ +@@ -3689,7 +3522,13 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, @@ -704,7 +704,7 @@ %% @doc

node plugin call.

node_call(Type, Function, Args) -> -@@ -3651,13 +3490,13 @@ +@@ -3709,13 +3548,13 @@ node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), @@ -720,7 +720,7 @@ case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of -@@ -3670,8 +3509,14 @@ +@@ -3728,8 +3567,14 @@ end end, Trans). @@ -737,7 +737,7 @@ {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; -@@ -3679,6 +3524,15 @@ +@@ -3737,6 +3582,15 @@ {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -753,7 +753,7 @@ {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; -@@ -3687,6 +3541,17 @@ +@@ -3745,6 +3599,17 @@ {error, ?ERR_INTERNAL_SERVER_ERROR} end.