From 0964724b2a5fafb163e098dc3cfbac1f376e901a Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 12 May 2010 13:54:21 +0200 Subject: [PATCH] sync pubsub_odbc with latest code --- src/mod_pubsub/mod_pubsub_odbc.erl | 74 +++++++++++++++++++++++++----- src/mod_pubsub/pubsub_odbc.patch | 22 ++++----- 2 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/mod_pubsub/mod_pubsub_odbc.erl b/src/mod_pubsub/mod_pubsub_odbc.erl index 340fb2cf4..6b2e8bb07 100644 --- a/src/mod_pubsub/mod_pubsub_odbc.erl +++ b/src/mod_pubsub/mod_pubsub_odbc.erl @@ -2775,6 +2775,51 @@ presence_can_deliver({User, Server, Resource}, true) -> end, false, Sessions) 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.

@@ -3060,20 +3105,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]}), @@ -3082,17 +3132,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 04be371f1..5ccefc52a 100644 --- a/src/mod_pubsub/pubsub_odbc.patch +++ b/src/mod_pubsub/pubsub_odbc.patch @@ -1,5 +1,5 @@ ---- mod_pubsub.erl 2010-05-12 12:00:56.000000000 +0200 -+++ mod_pubsub_odbc.erl 2010-05-12 12:01:12.000000000 +0200 +--- mod_pubsub.erl 2010-05-12 13:53:23.000000000 +0200 ++++ mod_pubsub_odbc.erl 2010-05-12 13:53:48.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. @@ -690,7 +690,7 @@ true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> -@@ -3117,7 +2931,7 @@ +@@ -3162,7 +2976,7 @@ {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, @@ -699,7 +699,7 @@ {result, CollSubs} -> CollSubs; _ -> [] end. -@@ -3131,9 +2945,9 @@ +@@ -3176,9 +2990,9 @@ get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> @@ -711,7 +711,7 @@ _ -> Acc end; (_, Acc) -> -@@ -3348,6 +3162,30 @@ +@@ -3400,6 +3214,30 @@ Result end. @@ -742,7 +742,7 @@ %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] -@@ -3749,7 +3587,13 @@ +@@ -3801,7 +3639,13 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, @@ -757,7 +757,7 @@ %% @doc

node plugin call.

node_call(Type, Function, Args) -> -@@ -3769,13 +3613,13 @@ +@@ -3821,13 +3665,13 @@ node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), @@ -773,7 +773,7 @@ case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of -@@ -3788,8 +3632,15 @@ +@@ -3840,8 +3684,15 @@ end end, Trans). @@ -791,7 +791,7 @@ {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; -@@ -3797,6 +3648,15 @@ +@@ -3849,6 +3700,15 @@ {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, 'internal-server-error'}; @@ -807,7 +807,7 @@ {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, 'internal-server-error'}; -@@ -3805,6 +3665,16 @@ +@@ -3857,6 +3717,16 @@ {error, 'internal-server-error'} end. @@ -824,7 +824,7 @@ %%%% helpers %% Add pubsub-specific error element -@@ -3893,7 +3763,7 @@ +@@ -3945,7 +3815,7 @@ %% If the sender Server equals Host, the message comes from the Pubsub server Host -> allow; %% Else, the message comes from PEP