mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
port all recent fixes from trunk related to odbc subscriptions
SVN Revision: 2559
This commit is contained in:
parent
adfca08e43
commit
fab29f4cf0
@ -1434,12 +1434,21 @@ send_pending_auth_events(Host, Node, Owner) ->
|
|||||||
?DEBUG("Sending pending auth events for ~s on ~s:~s",
|
?DEBUG("Sending pending auth events for ~s on ~s:~s",
|
||||||
[exmpp_jid:jid_to_string(Owner), Host, node_to_string(Node)]),
|
[exmpp_jid:jid_to_string(Owner), Host, node_to_string(Node)]),
|
||||||
Action =
|
Action =
|
||||||
fun (#pubsub_node{id = NodeID, type = Type} = N) ->
|
fun(#pubsub_node{id = NodeID, type = Type}) ->
|
||||||
case lists:member("get-pending", features(Type)) of
|
case lists:member("get-pending", features(Type)) of
|
||||||
true ->
|
true ->
|
||||||
case node_call(Type, get_affiliation, [NodeID, Owner]) of
|
case node_call(Type, get_affiliation, [NodeID, Owner]) of
|
||||||
{result, owner} ->
|
{result, owner} ->
|
||||||
broadcast_pending_auth_events(N),
|
{result, Subscriptions} = node_call(Type, get_node_subscriptions, [NodeID]),
|
||||||
|
lists:foreach(fun({J, pending, _SubID}) ->
|
||||||
|
{U, S, R} = J,
|
||||||
|
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
||||||
|
({J, pending}) ->
|
||||||
|
{U, S, R} = J,
|
||||||
|
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end, Subscriptions),
|
||||||
{result, ok};
|
{result, ok};
|
||||||
_ ->
|
_ ->
|
||||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}
|
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}
|
||||||
@ -1455,16 +1464,6 @@ send_pending_auth_events(Host, Node, Owner) ->
|
|||||||
Err
|
Err
|
||||||
end.
|
end.
|
||||||
|
|
||||||
broadcast_pending_auth_events(#pubsub_node{type = Type, id = NodeID} = Node) ->
|
|
||||||
{result, Subscriptions} = node_call(Type, get_node_subscriptions, [NodeID]),
|
|
||||||
lists:foreach(fun ({J, pending, _SubID}) ->
|
|
||||||
{U, S, R} = J,
|
|
||||||
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
|
||||||
({J, pending}) ->
|
|
||||||
{U, S, R} = J,
|
|
||||||
send_authorization_request(Node, exmpp_jid:make(U,S,R))
|
|
||||||
end, Subscriptions).
|
|
||||||
|
|
||||||
%%% authorization handling
|
%%% authorization handling
|
||||||
|
|
||||||
send_authorization_request(#pubsub_node{owners = Owners, nodeid = {Host, Node}}, Subscriber) ->
|
send_authorization_request(#pubsub_node{owners = Owners, nodeid = {Host, Node}}, Subscriber) ->
|
||||||
@ -1795,18 +1794,19 @@ delete_node(_Host, [], _Owner) ->
|
|||||||
{error, 'not-allowed'};
|
{error, 'not-allowed'};
|
||||||
delete_node(Host, Node, Owner) ->
|
delete_node(Host, Node, Owner) ->
|
||||||
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||||
SubsByDepth = get_collection_subscriptions(Host, Node),
|
case node_call(Type, get_affiliation, [NodeId, Owner]) of
|
||||||
case node_call(Type, get_affiliation, [NodeId, Owner]) of
|
{result, owner} ->
|
||||||
{result, owner} ->
|
ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]),
|
||||||
Removed = tree_call(Host, delete_node, [Host, Node]),
|
SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree],
|
||||||
case node_call(Type, delete_node, [Removed]) of
|
Removed = tree_call(Host, delete_node, [Host, Node]),
|
||||||
|
case node_call(Type, delete_node, [Removed]) of
|
||||||
{result, Res} -> {result, {SubsByDepth, Res}};
|
{result, Res} -> {result, {SubsByDepth, Res}};
|
||||||
Error -> Error
|
Error -> Error
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
%% Entity is not an owner
|
%% Entity is not an owner
|
||||||
{error, 'forbidden'}
|
{error, 'forbidden'}
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
Reply = [],
|
Reply = [],
|
||||||
case transaction(Host, Node, Action, transaction) of
|
case transaction(Host, Node, Action, transaction) of
|
||||||
@ -2559,8 +2559,7 @@ set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
write_sub(Subscriber, NodeID, SubID, Options) ->
|
write_sub(Subscriber, NodeID, SubID, Options) ->
|
||||||
case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID,
|
case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||||
Options) of
|
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
{error, extended_error('not-acceptable', "invalid-subid")};
|
{error, extended_error('not-acceptable', "invalid-subid")};
|
||||||
{result, _} ->
|
{result, _} ->
|
||||||
@ -3016,24 +3015,28 @@ broadcast_config_notification(Host, Node, NodeId, Type, NodeOptions, Lang) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_collection_subscriptions(Host, Node) ->
|
get_collection_subscriptions(Host, Node) ->
|
||||||
lists:map(fun ({Depth, Nodes}) ->
|
Action = fun() ->
|
||||||
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
{result, lists:map(fun({Depth, Nodes}) ->
|
||||||
end, tree_action(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)])).
|
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
||||||
|
end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
|
||||||
get_node_subs(#pubsub_node{type = Type,
|
end,
|
||||||
nodeid = {Host, Node},
|
case transaction(Action, sync_dirty) of
|
||||||
id = NodeID}) ->
|
{result, CollSubs} -> CollSubs;
|
||||||
case node_action(Host, Type, get_node_subscriptions, [NodeID]) of
|
_ -> []
|
||||||
{result, Subs} ->
|
|
||||||
get_options_for_subs(Host, Node, NodeID, Subs);
|
|
||||||
Other ->
|
|
||||||
Other
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_options_for_subs(_Host, Node, NodeID, Subs) ->
|
get_node_subs(#pubsub_node{type = Type,
|
||||||
|
id = NodeID}) ->
|
||||||
|
case node_call(Type, get_node_subscriptions, [NodeID]) of
|
||||||
|
{result, Subs} -> get_options_for_subs(NodeID, Subs);
|
||||||
|
Other -> Other
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_options_for_subs(NodeID, Subs) ->
|
||||||
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
||||||
case pubsub_subscription:get_subscription(JID, NodeID, SubID) of
|
case pubsub_subscription:read_subscription(JID, NodeID, SubID) of
|
||||||
{result, #pubsub_subscription{options = Options}} -> [{JID, Node, Options} | Acc];
|
{error, notfound} -> [{JID, SubID, []} | Acc];
|
||||||
|
#pubsub_subscription{options = Options} -> [{JID, SubID, Options} | Acc];
|
||||||
_ -> Acc
|
_ -> Acc
|
||||||
end;
|
end;
|
||||||
(_, Acc) ->
|
(_, Acc) ->
|
||||||
@ -3063,8 +3066,7 @@ broadcast_stanza(Host, Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTyp
|
|||||||
BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull
|
BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull
|
||||||
From = service_jid(Host),
|
From = service_jid(Host),
|
||||||
%% Handles explicit subscriptions
|
%% Handles explicit subscriptions
|
||||||
FilteredSubsByDepth = depths_to_deliver(NotifyType, SubsByDepth),
|
NodesByJID = subscribed_nodes_by_jid(NotifyType, SubsByDepth),
|
||||||
NodesByJID = collate_subs_by_jid(FilteredSubsByDepth),
|
|
||||||
lists:foreach(fun ({LJID, Nodes}) ->
|
lists:foreach(fun ({LJID, Nodes}) ->
|
||||||
LJIDs = case BroadcastAll of
|
LJIDs = case BroadcastAll of
|
||||||
true ->
|
true ->
|
||||||
@ -3125,36 +3127,28 @@ broadcast_stanza(Host, Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTyp
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
depths_to_deliver(NotifyType, SubsByDepth) ->
|
subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
|
||||||
NodesToDeliver =
|
NodesToDeliver = fun(Depth, Node, Subs, Acc) ->
|
||||||
fun (Depth, Node, Subs, Acc) ->
|
NodeId = case Node#pubsub_node.nodeid of
|
||||||
lists:foldl(fun ({LJID, _Node, SubOptions} = S, Acc2) ->
|
{_, N} -> N;
|
||||||
|
Other -> Other
|
||||||
|
end,
|
||||||
|
NodeOptions = Node#pubsub_node.options,
|
||||||
|
lists:foldl(fun({LJID, _SubID, SubOptions}, Acc2) ->
|
||||||
case is_to_deliver(LJID, NotifyType, Depth,
|
case is_to_deliver(LJID, NotifyType, Depth,
|
||||||
Node#pubsub_node.options,
|
NodeOptions, SubOptions) of
|
||||||
SubOptions) of
|
true -> [{LJID, NodeId}|Acc2];
|
||||||
true -> [S | Acc2];
|
|
||||||
false -> Acc2
|
false -> Acc2
|
||||||
end
|
end
|
||||||
end, Acc, Subs)
|
end, Acc, Subs)
|
||||||
end,
|
end,
|
||||||
|
DepthsToDeliver = fun({Depth, SubsByNode}, Acc) ->
|
||||||
DepthsToDeliver =
|
lists:foldl(fun({Node, Subs}, Acc2) ->
|
||||||
fun ({Depth, SubsByNode}, Acc) ->
|
|
||||||
lists:foldl(fun ({Node, Subs}, Acc2) ->
|
|
||||||
NodesToDeliver(Depth, Node, Subs, Acc2)
|
NodesToDeliver(Depth, Node, Subs, Acc2)
|
||||||
end, Acc, SubsByNode)
|
end, Acc, SubsByNode)
|
||||||
end,
|
end,
|
||||||
|
JIDSubs = lists:foldl(DepthsToDeliver, [], SubsByDepth),
|
||||||
lists:foldl(DepthsToDeliver, [], SubsByDepth).
|
[{LJID, proplists:append_values(LJID, JIDSubs)} || LJID <- proplists:get_keys(JIDSubs)].
|
||||||
|
|
||||||
collate_subs_by_jid(SubsByDepth) ->
|
|
||||||
lists:foldl(fun ({JID, Node, _Options}, Acc) ->
|
|
||||||
OldNodes = case lists:keysearch(JID, 1, Acc) of
|
|
||||||
{value, {JID, Nodes}} -> Nodes;
|
|
||||||
false -> []
|
|
||||||
end,
|
|
||||||
lists:keystore(JID, 1, Acc, {JID, [Node | OldNodes]})
|
|
||||||
end, [], SubsByDepth).
|
|
||||||
|
|
||||||
%% If we don't know the resource, just pick first if any
|
%% If we don't know the resource, just pick first if any
|
||||||
%% If no resource available, check if caps anyway (remote online)
|
%% If no resource available, check if caps anyway (remote online)
|
||||||
|
@ -1120,11 +1120,9 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, Lang, Access, Plugins) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
||||||
SubEls = exmpp_xml:get_child_elements(SubEl),
|
Action = lists:filter(fun(#xmlel{name = 'set'}) -> false;
|
||||||
NoRSM = lists:filter(fun(#xmlel{name = Name}) ->
|
(_) -> true
|
||||||
Name == 'set'
|
end, exmpp_xml:get_child_elements(SubEl)),
|
||||||
end, SubEls),
|
|
||||||
Action = SubEls -- NoRSM, %%pablo why not doing it once on lists:filter?
|
|
||||||
case Action of
|
case Action of
|
||||||
[#xmlel{name = Name, attrs = Attrs, children = Els}] ->
|
[#xmlel{name = Name, attrs = Attrs, children = Els}] ->
|
||||||
Node = case Host of
|
Node = case Host of
|
||||||
@ -1268,12 +1266,21 @@ send_pending_auth_events(Host, Node, Owner) ->
|
|||||||
?DEBUG("Sending pending auth events for ~s on ~s:~s",
|
?DEBUG("Sending pending auth events for ~s on ~s:~s",
|
||||||
[exmpp_jid:jid_to_string(Owner), Host, node_to_string(Node)]),
|
[exmpp_jid:jid_to_string(Owner), Host, node_to_string(Node)]),
|
||||||
Action =
|
Action =
|
||||||
fun (#pubsub_node{id = NodeID, type = Type} = N) ->
|
fun(#pubsub_node{id = NodeID, type = Type}) ->
|
||||||
case lists:member("get-pending", features(Type)) of
|
case lists:member("get-pending", features(Type)) of
|
||||||
true ->
|
true ->
|
||||||
case node_call(Type, get_affiliation, [NodeID, Owner]) of
|
case node_call(Type, get_affiliation, [NodeID, Owner]) of
|
||||||
{result, owner} ->
|
{result, owner} ->
|
||||||
broadcast_pending_auth_events(N),
|
{result, Subscriptions} = node_call(Type, get_node_subscriptions, [NodeID]),
|
||||||
|
lists:foreach(fun({J, pending, _SubID}) ->
|
||||||
|
{U, S, R} = J,
|
||||||
|
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
||||||
|
({J, pending}) ->
|
||||||
|
{U, S, R} = J,
|
||||||
|
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end, Subscriptions),
|
||||||
{result, ok};
|
{result, ok};
|
||||||
_ ->
|
_ ->
|
||||||
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}
|
{error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'forbidden')}
|
||||||
@ -1289,16 +1296,6 @@ send_pending_auth_events(Host, Node, Owner) ->
|
|||||||
Err
|
Err
|
||||||
end.
|
end.
|
||||||
|
|
||||||
broadcast_pending_auth_events(#pubsub_node{type = Type, id = NodeID} = Node) ->
|
|
||||||
{result, Subscriptions} = node_call(Type, get_node_subscriptions, [NodeID]),
|
|
||||||
lists:foreach(fun ({J, pending, _SubID}) ->
|
|
||||||
{U, S, R} = J,
|
|
||||||
send_authorization_request(Node, exmpp_jid:make(U,S,R));
|
|
||||||
({J, pending}) ->
|
|
||||||
{U, S, R} = J,
|
|
||||||
send_authorization_request(Node, exmpp_jid:make(U,S,R))
|
|
||||||
end, Subscriptions).
|
|
||||||
|
|
||||||
%%% authorization handling
|
%%% authorization handling
|
||||||
|
|
||||||
send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = NodeId}, Subscriber) ->
|
send_authorization_request(#pubsub_node{nodeid = {Host, Node}, type = Type, id = NodeId}, Subscriber) ->
|
||||||
@ -1629,18 +1626,19 @@ delete_node(_Host, [], _Owner) ->
|
|||||||
{error, 'not-allowed'};
|
{error, 'not-allowed'};
|
||||||
delete_node(Host, Node, Owner) ->
|
delete_node(Host, Node, Owner) ->
|
||||||
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
|
||||||
SubsByDepth = get_collection_subscriptions(Host, Node),
|
case node_call(Type, get_affiliation, [NodeId, Owner]) of
|
||||||
case node_call(Type, get_affiliation, [NodeId, Owner]) of
|
{result, owner} ->
|
||||||
{result, owner} ->
|
ParentTree = tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]),
|
||||||
Removed = tree_call(Host, delete_node, [Host, Node]),
|
SubsByDepth = [{Depth, [{N, get_node_subs(N)} || N <- Nodes]} || {Depth, Nodes} <- ParentTree],
|
||||||
case node_call(Type, delete_node, [Removed]) of
|
Removed = tree_call(Host, delete_node, [Host, Node]),
|
||||||
|
case node_call(Type, delete_node, [Removed]) of
|
||||||
{result, Res} -> {result, {SubsByDepth, Res}};
|
{result, Res} -> {result, {SubsByDepth, Res}};
|
||||||
Error -> Error
|
Error -> Error
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
%% Entity is not an owner
|
%% Entity is not an owner
|
||||||
{error, 'forbidden'}
|
{error, 'forbidden'}
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
Reply = [],
|
Reply = [],
|
||||||
case transaction(Host, Node, Action, transaction) of
|
case transaction(Host, Node, Action, transaction) of
|
||||||
@ -1693,7 +1691,7 @@ delete_node(Host, Node, Owner) ->
|
|||||||
%%<li>The node does not exist.</li>
|
%%<li>The node does not exist.</li>
|
||||||
%%</ul>
|
%%</ul>
|
||||||
subscribe_node(Host, Node, From, JID, Configuration) ->
|
subscribe_node(Host, Node, From, JID, Configuration) ->
|
||||||
{result, SubOpts} = pubsub_subscription:parse_options_xform(Configuration),
|
{result, SubOpts} = pubsub_subscription_odbc:parse_options_xform(Configuration),
|
||||||
Subscriber = try
|
Subscriber = try
|
||||||
jlib:short_prepd_jid(exmpp_jid:parse(JID))
|
jlib:short_prepd_jid(exmpp_jid:parse(JID))
|
||||||
catch
|
catch
|
||||||
@ -2338,11 +2336,11 @@ get_options_helper(JID, Lang, NodeID, SubID, Type) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
read_sub(Subscriber, NodeID, SubID, Lang) ->
|
read_sub(Subscriber, NodeID, SubID, Lang) ->
|
||||||
case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of
|
case pubsub_subscription_odbc:get_subscription(Subscriber, NodeID, SubID) of
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
{error, extended_error('not-acceptable', "invalid-subid")};
|
pubsub_subscription_odbc:get_options_xform(Lang, []);
|
||||||
{result, #pubsub_subscription{options = Options}} ->
|
{result, #pubsub_subscription{options = Options}} ->
|
||||||
pubsub_subscription:get_options_xform(Lang, Options)
|
pubsub_subscription_odbc:get_options_xform(Lang, Options)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
set_options(Host, Node, JID, SubID, Configuration) ->
|
set_options(Host, Node, JID, SubID, Configuration) ->
|
||||||
@ -2369,7 +2367,7 @@ set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
|
|||||||
_ ->
|
_ ->
|
||||||
{"", "", ""} %%pablo TODO: "" or <<>> ?. short_jid uses exmpp_jid:node/1, etc. that returns binaries
|
{"", "", ""} %%pablo TODO: "" or <<>> ?. short_jid uses exmpp_jid:node/1, etc. that returns binaries
|
||||||
end,
|
end,
|
||||||
{result, SubOpts} = pubsub_subscription:parse_options_xform(Configuration),
|
{result, SubOpts} = pubsub_subscription_odbc:parse_options_xform(Configuration),
|
||||||
{result, Subs} = node_call(Type, get_subscriptions,
|
{result, Subs} = node_call(Type, get_subscriptions,
|
||||||
[NodeID, Subscriber]),
|
[NodeID, Subscriber]),
|
||||||
SubIDs = lists:foldl(fun({subscribed, SID}, Acc) ->
|
SubIDs = lists:foldl(fun({subscribed, SID}, Acc) ->
|
||||||
@ -2389,8 +2387,7 @@ set_options_helper(Configuration, JID, NodeID, SubID, Type) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
write_sub(Subscriber, NodeID, SubID, Options) ->
|
write_sub(Subscriber, NodeID, SubID, Options) ->
|
||||||
case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID,
|
case pubsub_subscription_odbc:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||||
Options) of
|
|
||||||
{error, notfound} ->
|
{error, notfound} ->
|
||||||
{error, extended_error('not-acceptable', "invalid-subid")};
|
{error, extended_error('not-acceptable', "invalid-subid")};
|
||||||
{result, _} ->
|
{result, _} ->
|
||||||
@ -2846,24 +2843,28 @@ broadcast_config_notification(Host, Node, NodeId, Type, NodeOptions, Lang) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
get_collection_subscriptions(Host, Node) ->
|
get_collection_subscriptions(Host, Node) ->
|
||||||
lists:map(fun ({Depth, Nodes}) ->
|
Action = fun() ->
|
||||||
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
{result, lists:map(fun({Depth, Nodes}) ->
|
||||||
end, tree_action(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)])).
|
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
||||||
|
end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
|
||||||
get_node_subs(#pubsub_node{type = Type,
|
end,
|
||||||
nodeid = {Host, Node},
|
case transaction(Host, Action, sync_dirty) of
|
||||||
id = NodeID}) ->
|
{result, CollSubs} -> CollSubs;
|
||||||
case node_action(Host, Type, get_node_subscriptions, [NodeID]) of
|
_ -> []
|
||||||
{result, Subs} ->
|
|
||||||
get_options_for_subs(Host, Node, NodeID, Subs);
|
|
||||||
Other ->
|
|
||||||
Other
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_options_for_subs(_Host, Node, NodeID, Subs) ->
|
get_node_subs(#pubsub_node{type = Type,
|
||||||
|
id = NodeID}) ->
|
||||||
|
case node_call(Type, get_node_subscriptions, [NodeID]) of
|
||||||
|
{result, Subs} -> get_options_for_subs(NodeID, Subs);
|
||||||
|
Other -> Other
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_options_for_subs(NodeID, Subs) ->
|
||||||
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
||||||
case pubsub_subscription:get_subscription(JID, NodeID, SubID) of
|
case pubsub_subscription_odbc:get_subscription(JID, NodeID, SubID) of
|
||||||
{result, #pubsub_subscription{options = Options}} -> [{JID, Node, Options} | Acc];
|
{error, notfound} -> [{JID, SubID, []} | Acc];
|
||||||
|
{result, #pubsub_subscription{options = Options}} -> [{JID, SubID, Options} | Acc];
|
||||||
_ -> Acc
|
_ -> Acc
|
||||||
end;
|
end;
|
||||||
(_, Acc) ->
|
(_, Acc) ->
|
||||||
@ -2893,8 +2894,7 @@ broadcast_stanza(Host, Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTyp
|
|||||||
BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull
|
BroadcastAll = get_option(NodeOptions, broadcast_all_resources), %% XXX this is not standard, but usefull
|
||||||
From = service_jid(Host),
|
From = service_jid(Host),
|
||||||
%% Handles explicit subscriptions
|
%% Handles explicit subscriptions
|
||||||
FilteredSubsByDepth = depths_to_deliver(NotifyType, SubsByDepth),
|
NodesByJID = subscribed_nodes_by_jid(NotifyType, SubsByDepth),
|
||||||
NodesByJID = collate_subs_by_jid(FilteredSubsByDepth),
|
|
||||||
lists:foreach(fun ({LJID, Nodes}) ->
|
lists:foreach(fun ({LJID, Nodes}) ->
|
||||||
LJIDs = case BroadcastAll of
|
LJIDs = case BroadcastAll of
|
||||||
true ->
|
true ->
|
||||||
@ -2955,36 +2955,28 @@ broadcast_stanza(Host, Node, _NodeId, _Type, NodeOptions, SubsByDepth, NotifyTyp
|
|||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
depths_to_deliver(NotifyType, SubsByDepth) ->
|
subscribed_nodes_by_jid(NotifyType, SubsByDepth) ->
|
||||||
NodesToDeliver =
|
NodesToDeliver = fun(Depth, Node, Subs, Acc) ->
|
||||||
fun (Depth, Node, Subs, Acc) ->
|
NodeId = case Node#pubsub_node.nodeid of
|
||||||
lists:foldl(fun ({LJID, _Node, SubOptions} = S, Acc2) ->
|
{_, N} -> N;
|
||||||
|
Other -> Other
|
||||||
|
end,
|
||||||
|
NodeOptions = Node#pubsub_node.options,
|
||||||
|
lists:foldl(fun({LJID, _SubID, SubOptions}, Acc2) ->
|
||||||
case is_to_deliver(LJID, NotifyType, Depth,
|
case is_to_deliver(LJID, NotifyType, Depth,
|
||||||
Node#pubsub_node.options,
|
NodeOptions, SubOptions) of
|
||||||
SubOptions) of
|
true -> [{LJID, NodeId}|Acc2];
|
||||||
true -> [S | Acc2];
|
|
||||||
false -> Acc2
|
false -> Acc2
|
||||||
end
|
end
|
||||||
end, Acc, Subs)
|
end, Acc, Subs)
|
||||||
end,
|
end,
|
||||||
|
DepthsToDeliver = fun({Depth, SubsByNode}, Acc) ->
|
||||||
DepthsToDeliver =
|
lists:foldl(fun({Node, Subs}, Acc2) ->
|
||||||
fun ({Depth, SubsByNode}, Acc) ->
|
|
||||||
lists:foldl(fun ({Node, Subs}, Acc2) ->
|
|
||||||
NodesToDeliver(Depth, Node, Subs, Acc2)
|
NodesToDeliver(Depth, Node, Subs, Acc2)
|
||||||
end, Acc, SubsByNode)
|
end, Acc, SubsByNode)
|
||||||
end,
|
end,
|
||||||
|
JIDSubs = lists:foldl(DepthsToDeliver, [], SubsByDepth),
|
||||||
lists:foldl(DepthsToDeliver, [], SubsByDepth).
|
[{LJID, proplists:append_values(LJID, JIDSubs)} || LJID <- proplists:get_keys(JIDSubs)].
|
||||||
|
|
||||||
collate_subs_by_jid(SubsByDepth) ->
|
|
||||||
lists:foldl(fun ({JID, Node, _Options}, Acc) ->
|
|
||||||
OldNodes = case lists:keysearch(JID, 1, Acc) of
|
|
||||||
{value, {JID, Nodes}} -> Nodes;
|
|
||||||
false -> []
|
|
||||||
end,
|
|
||||||
lists:keystore(JID, 1, Acc, {JID, [Node | OldNodes]})
|
|
||||||
end, [], SubsByDepth).
|
|
||||||
|
|
||||||
%% If we don't know the resource, just pick first if any
|
%% If we don't know the resource, just pick first if any
|
||||||
%% If no resource available, check if caps anyway (remote online)
|
%% If no resource available, check if caps anyway (remote online)
|
||||||
@ -3067,7 +3059,7 @@ node_options(Type) ->
|
|||||||
Result
|
Result
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @spec (NodeId) -> [ljid()]
|
%% @spec (Host, Type, NodeId) -> [ljid()]
|
||||||
%% NodeId = pubsubNodeId()
|
%% NodeId = pubsubNodeId()
|
||||||
%% @doc <p>Return list of node owners.</p>
|
%% @doc <p>Return list of node owners.</p>
|
||||||
node_owners(Host, Type, NodeId) ->
|
node_owners(Host, Type, NodeId) ->
|
||||||
|
@ -59,7 +59,8 @@
|
|||||||
get_item/7,
|
get_item/7,
|
||||||
get_item/2,
|
get_item/2,
|
||||||
set_item/1,
|
set_item/1,
|
||||||
get_item_name/3
|
get_item_name/3,
|
||||||
|
get_last_items/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
|
||||||
@ -181,3 +182,6 @@ set_item(Item) ->
|
|||||||
|
|
||||||
get_item_name(Host, Node, Id) ->
|
get_item_name(Host, Node, Id) ->
|
||||||
node_hometree_odbc:get_item_name(Host, Node, Id).
|
node_hometree_odbc:get_item_name(Host, Node, Id).
|
||||||
|
|
||||||
|
get_last_items(NodeId, From, Count) ->
|
||||||
|
node_hometree_odbc:get_last_items(NodeId, From, Count).
|
||||||
|
@ -398,8 +398,7 @@ unsubscribe_node(NodeId, Sender, Subscriber, SubId) ->
|
|||||||
delete_subscription(SubKey, NodeId, S, Affiliation, Subscriptions),
|
delete_subscription(SubKey, NodeId, S, Affiliation, Subscriptions),
|
||||||
{result, default};
|
{result, default};
|
||||||
false ->
|
false ->
|
||||||
{error, ?ERR_EXTENDED('unexpected-request',
|
{error, ?ERR_EXTENDED('unexpected-request', "not-subscribed")}
|
||||||
"not-subscribed")}
|
|
||||||
end;
|
end;
|
||||||
%% No subid supplied, but there's only one matching
|
%% No subid supplied, but there's only one matching
|
||||||
%% subscription, so use that.
|
%% subscription, so use that.
|
||||||
@ -652,25 +651,33 @@ get_entity_subscriptions(Host, Owner) ->
|
|||||||
SJ = encode_jid(SubKey),
|
SJ = encode_jid(SubKey),
|
||||||
GJ = encode_jid(GenKey),
|
GJ = encode_jid(GenKey),
|
||||||
Query = case SubKey of
|
Query = case SubKey of
|
||||||
GenKey ->
|
GenKey ->
|
||||||
["select node, type, i.nodeid, jid, subscriptions "
|
["select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n "
|
"from pubsub_state i, pubsub_node n "
|
||||||
"where i.nodeid = n.nodeid "
|
"where i.nodeid = n.nodeid "
|
||||||
"and jid like '", GJ, "%' "
|
"and jid like '", GJ, "%' "
|
||||||
"and host='", H, "';"];
|
"and host='", H, "';"];
|
||||||
_ ->
|
_ ->
|
||||||
["select node, type, i.nodeid, jid, subscriptions "
|
["select node, type, i.nodeid, jid, subscriptions "
|
||||||
"from pubsub_state i, pubsub_node n "
|
"from pubsub_state i, pubsub_node n "
|
||||||
"where i.nodeid = n.nodeid "
|
"where i.nodeid = n.nodeid "
|
||||||
"and jid in ('", SJ, "', '", GJ, "') "
|
"and jid in ('", SJ, "', '", GJ, "') "
|
||||||
"and host='", H, "';"]
|
"and host='", H, "';"]
|
||||||
end,
|
end,
|
||||||
Reply = case catch ejabberd_odbc:sql_query_t(Query) of
|
Reply = case catch ejabberd_odbc:sql_query_t(Query) of
|
||||||
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
||||||
lists:map(fun({N, T, I, J, S}) ->
|
lists:foldl(fun({N, T, I, J, S}, Acc) ->
|
||||||
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
||||||
{Node, decode_subscriptions(S), decode_jid(J)}
|
Jid = decode_jid(J),
|
||||||
end, RItems);
|
case decode_subscriptions(S) of
|
||||||
|
[] ->
|
||||||
|
[{Node, none, Jid}|Acc];
|
||||||
|
Subs ->
|
||||||
|
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2];
|
||||||
|
(Sub, Acc2) -> [{Node, Sub, Jid}|Acc2]
|
||||||
|
end, Acc, Subs)
|
||||||
|
end
|
||||||
|
end, [], RItems);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end,
|
end,
|
||||||
@ -702,10 +709,18 @@ get_entity_subscriptions_for_send_last(Host, Owner) ->
|
|||||||
end,
|
end,
|
||||||
Reply = case catch ejabberd_odbc:sql_query_t(Query) of
|
Reply = case catch ejabberd_odbc:sql_query_t(Query) of
|
||||||
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
{selected, ["node", "type", "nodeid", "jid", "subscriptions"], RItems} ->
|
||||||
lists:map(fun({N, T, I, J, S}) ->
|
lists:foldl(fun({N, T, I, J, S}, Acc) ->
|
||||||
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
Node = nodetree_tree_odbc:raw_to_node(Host, {N, "", T, I}),
|
||||||
{Node, decode_subscriptions(S), decode_jid(J)}
|
Jid = decode_jid(J),
|
||||||
end, RItems);
|
case decode_subscriptions(S) of
|
||||||
|
[] ->
|
||||||
|
[{Node, none, Jid}|Acc];
|
||||||
|
Subs ->
|
||||||
|
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Node, Sub, SubId, Jid}|Acc2];
|
||||||
|
(Sub, Acc2) -> [{Node, Sub, Jid}|Acc2]
|
||||||
|
end, Acc, Subs)
|
||||||
|
end
|
||||||
|
end, [], RItems);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end,
|
end,
|
||||||
@ -717,8 +732,17 @@ get_node_subscriptions(NodeId) ->
|
|||||||
"from pubsub_state "
|
"from pubsub_state "
|
||||||
"where nodeid='", NodeId, "';"]) of
|
"where nodeid='", NodeId, "';"]) of
|
||||||
{selected, ["jid", "subscriptions"], RItems} ->
|
{selected, ["jid", "subscriptions"], RItems} ->
|
||||||
lists:map(fun({J, S}) -> {decode_jid(J), decode_subscriptions(S)} end, RItems);
|
lists:foldl(fun({J, S}, Acc) ->
|
||||||
% TODO {J, S, SubId}
|
Jid = decode_jid(J),
|
||||||
|
case decode_subscriptions(S) of
|
||||||
|
[] ->
|
||||||
|
[{Jid, none}|Acc];
|
||||||
|
Subs ->
|
||||||
|
lists:foldl(fun({Sub, SubId}, Acc2) -> [{Jid, Sub, SubId}|Acc2];
|
||||||
|
(Sub, Acc2) -> [{Jid, Sub}|Acc2]
|
||||||
|
end, Acc, Subs)
|
||||||
|
end
|
||||||
|
end, [], RItems);
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
end,
|
end,
|
||||||
@ -732,7 +756,7 @@ get_subscriptions(NodeId, Owner) ->
|
|||||||
["select subscriptions from pubsub_state "
|
["select subscriptions from pubsub_state "
|
||||||
"where nodeid='", NodeId, "' and jid='", J, "';"]) of
|
"where nodeid='", NodeId, "' and jid='", J, "';"]) of
|
||||||
{selected, ["subscriptions"], [{S}]} -> decode_subscriptions(S);
|
{selected, ["subscriptions"], [{S}]} -> decode_subscriptions(S);
|
||||||
_ -> none
|
_ -> []
|
||||||
end,
|
end,
|
||||||
{result, Reply}.
|
{result, Reply}.
|
||||||
|
|
||||||
@ -1224,7 +1248,7 @@ select_affiliation_subscriptions(NodeId, JID) ->
|
|||||||
{selected, ["affiliation", "subscriptions"], [{A, S}]} ->
|
{selected, ["affiliation", "subscriptions"], [{A, S}]} ->
|
||||||
{decode_affiliation(A), decode_subscriptions(S)};
|
{decode_affiliation(A), decode_subscriptions(S)};
|
||||||
_ ->
|
_ ->
|
||||||
{none, none}
|
{none, []}
|
||||||
end.
|
end.
|
||||||
select_affiliation_subscriptions(NodeId, JID, JID) ->
|
select_affiliation_subscriptions(NodeId, JID, JID) ->
|
||||||
select_affiliation_subscriptions(NodeId, JID);
|
select_affiliation_subscriptions(NodeId, JID);
|
||||||
|
@ -149,8 +149,9 @@ get_parentnodes(_Host, _Node, _From) ->
|
|||||||
get_parentnodes_tree(Host, Node, From) ->
|
get_parentnodes_tree(Host, Node, From) ->
|
||||||
case get_node(Host, Node, From) of
|
case get_node(Host, Node, From) of
|
||||||
N when is_record(N, pubsub_node) -> [{0, [N]}];
|
N when is_record(N, pubsub_node) -> [{0, [N]}];
|
||||||
Error -> Error
|
_Error -> []
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @spec (Host, Node, From) -> [pubsubNode()] | {error, Reason}
|
%% @spec (Host, Node, From) -> [pubsubNode()] | {error, Reason}
|
||||||
%% Host = mod_pubsub:host()
|
%% Host = mod_pubsub:host()
|
||||||
%% Node = mod_pubsub:pubsubNode()
|
%% Node = mod_pubsub:pubsubNode()
|
||||||
|
@ -163,7 +163,7 @@ get_parentnodes(_Host, _Node, _From) ->
|
|||||||
get_parentnodes_tree(Host, Node, From) ->
|
get_parentnodes_tree(Host, Node, From) ->
|
||||||
case get_node(Host, Node, From) of
|
case get_node(Host, Node, From) of
|
||||||
N when is_record(N, pubsub_node) -> [{0, [N]}];
|
N when is_record(N, pubsub_node) -> [{0, [N]}];
|
||||||
Error -> Error
|
_Error -> []
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_subnodes(Host, Node, _From) ->
|
get_subnodes(Host, Node, _From) ->
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
--- mod_pubsub.erl 2009-08-27 10:43:45.000000000 +0200
|
--- mod_pubsub.erl 2009-08-28 01:07:30.000000000 +0200
|
||||||
+++ mod_pubsub_odbc.erl 2009-08-27 10:47:31.000000000 +0200
|
+++ mod_pubsub_odbc.erl 2009-08-28 01:08:15.000000000 +0200
|
||||||
@@ -45,7 +45,7 @@
|
@@ -45,7 +45,7 @@
|
||||||
%%% TODO
|
%%% TODO
|
||||||
%%% plugin: generate Reply (do not use broadcast atom anymore)
|
%%% plugin: generate Reply (do not use broadcast atom anymore)
|
||||||
@ -359,21 +359,19 @@
|
|||||||
{get, 'subscriptions'} ->
|
{get, 'subscriptions'} ->
|
||||||
get_subscriptions(Host, Node, From, Plugins);
|
get_subscriptions(Host, Node, From, Plugins);
|
||||||
{get, 'affiliations'} ->
|
{get, 'affiliations'} ->
|
||||||
@@ -1290,8 +1120,11 @@
|
@@ -1290,8 +1120,9 @@
|
||||||
end.
|
end.
|
||||||
|
|
||||||
iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) ->
|
||||||
- SubEls = SubEl#xmlel.children,
|
- SubEls = SubEl#xmlel.children,
|
||||||
- Action = exmpp_xml:remove_cdata_from_list(SubEls),
|
- Action = exmpp_xml:remove_cdata_from_list(SubEls),
|
||||||
+ SubEls = exmpp_xml:get_child_elements(SubEl),
|
+ Action = lists:filter(fun(#xmlel{name = 'set'}) -> false;
|
||||||
+ NoRSM = lists:filter(fun(#xmlel{name = Name}) ->
|
+ (_) -> true
|
||||||
+ Name == 'set'
|
+ end, exmpp_xml:get_child_elements(SubEl)),
|
||||||
+ end, SubEls),
|
|
||||||
+ Action = SubEls -- NoRSM, %%pablo why not doing it once on lists:filter?
|
|
||||||
case Action of
|
case Action of
|
||||||
[#xmlel{name = Name, attrs = Attrs, children = Els}] ->
|
[#xmlel{name = Name, attrs = Attrs, children = Els}] ->
|
||||||
Node = case Host of
|
Node = case Host of
|
||||||
@@ -1421,7 +1254,8 @@
|
@@ -1421,7 +1252,8 @@
|
||||||
_ -> []
|
_ -> []
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
@ -383,7 +381,7 @@
|
|||||||
sync_dirty) of
|
sync_dirty) of
|
||||||
{result, Res} -> Res;
|
{result, Res} -> Res;
|
||||||
Err -> Err
|
Err -> Err
|
||||||
@@ -1467,7 +1301,7 @@
|
@@ -1466,7 +1298,7 @@
|
||||||
|
|
||||||
%%% authorization handling
|
%%% authorization handling
|
||||||
|
|
||||||
@ -392,7 +390,7 @@
|
|||||||
Lang = "en", %% TODO fix
|
Lang = "en", %% TODO fix
|
||||||
{U, S, R} = Subscriber,
|
{U, S, R} = Subscriber,
|
||||||
Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
|
Stanza = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', children =
|
||||||
@@ -1497,7 +1331,7 @@
|
@@ -1496,7 +1328,7 @@
|
||||||
lists:foreach(fun(Owner) ->
|
lists:foreach(fun(Owner) ->
|
||||||
{U, S, R} = Owner,
|
{U, S, R} = Owner,
|
||||||
ejabberd_router ! {route, service_jid(Host), exmpp_jid:make(U, S, R), Stanza}
|
ejabberd_router ! {route, service_jid(Host), exmpp_jid:make(U, S, R), Stanza}
|
||||||
@ -401,7 +399,7 @@
|
|||||||
|
|
||||||
find_authorization_response(Packet) ->
|
find_authorization_response(Packet) ->
|
||||||
Els = Packet#xmlel.children,
|
Els = Packet#xmlel.children,
|
||||||
@@ -1560,8 +1394,8 @@
|
@@ -1559,8 +1391,8 @@
|
||||||
"true" -> true;
|
"true" -> true;
|
||||||
_ -> false
|
_ -> false
|
||||||
end,
|
end,
|
||||||
@ -412,7 +410,7 @@
|
|||||||
{result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]),
|
{result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]),
|
||||||
if
|
if
|
||||||
not IsApprover ->
|
not IsApprover ->
|
||||||
@@ -1751,7 +1585,7 @@
|
@@ -1750,7 +1582,7 @@
|
||||||
end,
|
end,
|
||||||
Reply = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
Reply = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
||||||
[#xmlel{ns = ?NS_PUBSUB, name = 'create', attrs = nodeAttr(Node)}]},
|
[#xmlel{ns = ?NS_PUBSUB, name = 'create', attrs = nodeAttr(Node)}]},
|
||||||
@ -421,7 +419,16 @@
|
|||||||
{result, {Result, broadcast}} ->
|
{result, {Result, broadcast}} ->
|
||||||
%%Lang = "en", %% TODO: fix
|
%%Lang = "en", %% TODO: fix
|
||||||
%%OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
%%OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||||
@@ -1867,7 +1701,7 @@
|
@@ -1859,7 +1691,7 @@
|
||||||
|
%%<li>The node does not exist.</li>
|
||||||
|
%%</ul>
|
||||||
|
subscribe_node(Host, Node, From, JID, Configuration) ->
|
||||||
|
- {result, SubOpts} = pubsub_subscription:parse_options_xform(Configuration),
|
||||||
|
+ {result, SubOpts} = pubsub_subscription_odbc:parse_options_xform(Configuration),
|
||||||
|
Subscriber = try
|
||||||
|
jlib:short_prepd_jid(exmpp_jid:parse(JID))
|
||||||
|
catch
|
||||||
|
@@ -1867,7 +1699,7 @@
|
||||||
{undefined, undefined, undefined}
|
{undefined, undefined, undefined}
|
||||||
end,
|
end,
|
||||||
SubId = uniqid(),
|
SubId = uniqid(),
|
||||||
@ -430,7 +437,7 @@
|
|||||||
Features = features(Type),
|
Features = features(Type),
|
||||||
SubscribeFeature = lists:member("subscribe", Features),
|
SubscribeFeature = lists:member("subscribe", Features),
|
||||||
OptionsFeature = lists:member("subscription-options", Features),
|
OptionsFeature = lists:member("subscription-options", Features),
|
||||||
@@ -1886,9 +1720,13 @@
|
@@ -1886,9 +1718,13 @@
|
||||||
{"", "", ""} ->
|
{"", "", ""} ->
|
||||||
{false, false};
|
{false, false};
|
||||||
_ ->
|
_ ->
|
||||||
@ -447,7 +454,7 @@
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
if
|
if
|
||||||
@@ -2213,7 +2051,7 @@
|
@@ -2213,7 +2049,7 @@
|
||||||
%% <p>The permission are not checked in this function.</p>
|
%% <p>The permission are not checked in this function.</p>
|
||||||
%% @todo We probably need to check that the user doing the query has the right
|
%% @todo We probably need to check that the user doing the query has the right
|
||||||
%% to read the items.
|
%% to read the items.
|
||||||
@ -456,7 +463,7 @@
|
|||||||
MaxItems =
|
MaxItems =
|
||||||
if
|
if
|
||||||
SMaxItems == "" -> ?MAXITEMS;
|
SMaxItems == "" -> ?MAXITEMS;
|
||||||
@@ -2252,11 +2090,11 @@
|
@@ -2252,11 +2088,11 @@
|
||||||
node_call(Type, get_items,
|
node_call(Type, get_items,
|
||||||
[NodeId, From,
|
[NodeId, From,
|
||||||
AccessModel, PresenceSubscription, RosterGroup,
|
AccessModel, PresenceSubscription, RosterGroup,
|
||||||
@ -470,7 +477,7 @@
|
|||||||
SendItems = case ItemIDs of
|
SendItems = case ItemIDs of
|
||||||
[] ->
|
[] ->
|
||||||
Items;
|
Items;
|
||||||
@@ -2269,7 +2107,7 @@
|
@@ -2269,7 +2105,7 @@
|
||||||
%% number of items sent to MaxItems:
|
%% number of items sent to MaxItems:
|
||||||
{result, #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
{result, #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children =
|
||||||
[#xmlel{ns = ?NS_PUBSUB, name = 'items', attrs = nodeAttr(Node), children =
|
[#xmlel{ns = ?NS_PUBSUB, name = 'items', attrs = nodeAttr(Node), children =
|
||||||
@ -479,7 +486,7 @@
|
|||||||
Error ->
|
Error ->
|
||||||
Error
|
Error
|
||||||
end
|
end
|
||||||
@@ -2301,16 +2139,25 @@
|
@@ -2301,16 +2137,25 @@
|
||||||
%% @doc <p>Resend the items of a node to the user.</p>
|
%% @doc <p>Resend the items of a node to the user.</p>
|
||||||
%% @todo use cache-last-item feature
|
%% @todo use cache-last-item feature
|
||||||
send_items(Host, Node, NodeId, Type, LJID, last) ->
|
send_items(Host, Node, NodeId, Type, LJID, last) ->
|
||||||
@ -512,7 +519,7 @@
|
|||||||
send_items(Host, Node, NodeId, Type, {LU, LS, LR} = LJID, Number) ->
|
send_items(Host, Node, NodeId, Type, {LU, LS, LR} = LJID, Number) ->
|
||||||
ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of
|
ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of
|
||||||
{result, []} ->
|
{result, []} ->
|
||||||
@@ -2431,29 +2278,12 @@
|
@@ -2431,29 +2276,12 @@
|
||||||
error ->
|
error ->
|
||||||
{error, 'bad-request'};
|
{error, 'bad-request'};
|
||||||
_ ->
|
_ ->
|
||||||
@ -545,7 +552,40 @@
|
|||||||
end, Entities),
|
end, Entities),
|
||||||
{result, []};
|
{result, []};
|
||||||
_ ->
|
_ ->
|
||||||
@@ -2733,8 +2563,8 @@
|
@@ -2508,11 +2336,11 @@
|
||||||
|
end.
|
||||||
|
|
||||||
|
read_sub(Subscriber, NodeID, SubID, Lang) ->
|
||||||
|
- case pubsub_subscription:get_subscription(Subscriber, NodeID, SubID) of
|
||||||
|
+ case pubsub_subscription_odbc:get_subscription(Subscriber, NodeID, SubID) of
|
||||||
|
{error, notfound} ->
|
||||||
|
- {error, extended_error('not-acceptable', "invalid-subid")};
|
||||||
|
+ pubsub_subscription_odbc:get_options_xform(Lang, []);
|
||||||
|
{result, #pubsub_subscription{options = Options}} ->
|
||||||
|
- pubsub_subscription:get_options_xform(Lang, Options)
|
||||||
|
+ pubsub_subscription_odbc:get_options_xform(Lang, Options)
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_options(Host, Node, JID, SubID, Configuration) ->
|
||||||
|
@@ -2539,7 +2367,7 @@
|
||||||
|
_ ->
|
||||||
|
{"", "", ""} %%pablo TODO: "" or <<>> ?. short_jid uses exmpp_jid:node/1, etc. that returns binaries
|
||||||
|
end,
|
||||||
|
- {result, SubOpts} = pubsub_subscription:parse_options_xform(Configuration),
|
||||||
|
+ {result, SubOpts} = pubsub_subscription_odbc:parse_options_xform(Configuration),
|
||||||
|
{result, Subs} = node_call(Type, get_subscriptions,
|
||||||
|
[NodeID, Subscriber]),
|
||||||
|
SubIDs = lists:foldl(fun({subscribed, SID}, Acc) ->
|
||||||
|
@@ -2559,7 +2387,7 @@
|
||||||
|
end.
|
||||||
|
|
||||||
|
write_sub(Subscriber, NodeID, SubID, Options) ->
|
||||||
|
- case pubsub_subscription:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||||
|
+ case pubsub_subscription_odbc:set_subscription(Subscriber, NodeID, SubID, Options) of
|
||||||
|
{error, notfound} ->
|
||||||
|
{error, extended_error('not-acceptable', "invalid-subid")};
|
||||||
|
{result, _} ->
|
||||||
|
@@ -2732,8 +2560,8 @@
|
||||||
?XMLATTR('subsription', subscription_to_string(Sub)) | nodeAttr(Node)]}]}]},
|
?XMLATTR('subsription', subscription_to_string(Sub)) | nodeAttr(Node)]}]}]},
|
||||||
ejabberd_router ! {route, service_jid(Host), JID, Stanza}
|
ejabberd_router ! {route, service_jid(Host), JID, Stanza}
|
||||||
end,
|
end,
|
||||||
@ -556,11 +596,32 @@
|
|||||||
true ->
|
true ->
|
||||||
Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) ->
|
Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) ->
|
||||||
|
|
||||||
@@ -3237,6 +3067,30 @@
|
@@ -3020,7 +2848,7 @@
|
||||||
|
{Depth, [{N, get_node_subs(N)} || N <- Nodes]}
|
||||||
|
end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))}
|
||||||
|
end,
|
||||||
|
- case transaction(Action, sync_dirty) of
|
||||||
|
+ case transaction(Host, Action, sync_dirty) of
|
||||||
|
{result, CollSubs} -> CollSubs;
|
||||||
|
_ -> []
|
||||||
|
end.
|
||||||
|
@@ -3034,9 +2862,9 @@
|
||||||
|
|
||||||
|
get_options_for_subs(NodeID, Subs) ->
|
||||||
|
lists:foldl(fun({JID, subscribed, SubID}, Acc) ->
|
||||||
|
- case pubsub_subscription:read_subscription(JID, NodeID, SubID) of
|
||||||
|
+ case pubsub_subscription_odbc:get_subscription(JID, NodeID, SubID) of
|
||||||
|
{error, notfound} -> [{JID, SubID, []} | Acc];
|
||||||
|
- #pubsub_subscription{options = Options} -> [{JID, SubID, Options} | Acc];
|
||||||
|
+ {result, #pubsub_subscription{options = Options}} -> [{JID, SubID, Options} | Acc];
|
||||||
|
_ -> Acc
|
||||||
|
end;
|
||||||
|
(_, Acc) ->
|
||||||
|
@@ -3231,6 +3059,30 @@
|
||||||
Result
|
Result
|
||||||
end.
|
end.
|
||||||
|
|
||||||
+%% @spec (NodeId) -> [ljid()]
|
+%% @spec (Host, Type, NodeId) -> [ljid()]
|
||||||
+%% NodeId = pubsubNodeId()
|
+%% NodeId = pubsubNodeId()
|
||||||
+%% @doc <p>Return list of node owners.</p>
|
+%% @doc <p>Return list of node owners.</p>
|
||||||
+node_owners(Host, Type, NodeId) ->
|
+node_owners(Host, Type, NodeId) ->
|
||||||
@ -587,7 +648,7 @@
|
|||||||
%% @spec (Host, Options) -> MaxItems
|
%% @spec (Host, Options) -> MaxItems
|
||||||
%% Host = host()
|
%% Host = host()
|
||||||
%% Options = [Option]
|
%% Options = [Option]
|
||||||
@@ -3613,7 +3467,13 @@
|
@@ -3607,7 +3459,13 @@
|
||||||
tree_action(Host, Function, Args) ->
|
tree_action(Host, Function, Args) ->
|
||||||
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
|
?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]),
|
||||||
Fun = fun() -> tree_call(Host, Function, Args) end,
|
Fun = fun() -> tree_call(Host, Function, Args) end,
|
||||||
@ -602,7 +663,7 @@
|
|||||||
|
|
||||||
%% @doc <p>node plugin call.</p>
|
%% @doc <p>node plugin call.</p>
|
||||||
node_call(Type, Function, Args) ->
|
node_call(Type, Function, Args) ->
|
||||||
@@ -3633,13 +3493,13 @@
|
@@ -3627,13 +3485,13 @@
|
||||||
|
|
||||||
node_action(Host, Type, Function, Args) ->
|
node_action(Host, Type, Function, Args) ->
|
||||||
?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
|
?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]),
|
||||||
@ -618,7 +679,7 @@
|
|||||||
case tree_call(Host, get_node, [Host, Node]) of
|
case tree_call(Host, get_node, [Host, Node]) of
|
||||||
N when is_record(N, pubsub_node) ->
|
N when is_record(N, pubsub_node) ->
|
||||||
case Action(N) of
|
case Action(N) of
|
||||||
@@ -3652,8 +3512,15 @@
|
@@ -3646,8 +3504,15 @@
|
||||||
end
|
end
|
||||||
end, Trans).
|
end, Trans).
|
||||||
|
|
||||||
@ -636,7 +697,7 @@
|
|||||||
{result, Result} -> {result, Result};
|
{result, Result} -> {result, Result};
|
||||||
{error, Error} -> {error, Error};
|
{error, Error} -> {error, Error};
|
||||||
{atomic, {result, Result}} -> {result, Result};
|
{atomic, {result, Result}} -> {result, Result};
|
||||||
@@ -3661,6 +3528,15 @@
|
@@ -3655,6 +3520,15 @@
|
||||||
{aborted, Reason} ->
|
{aborted, Reason} ->
|
||||||
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
|
?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]),
|
||||||
{error, 'internal-server-error'};
|
{error, 'internal-server-error'};
|
||||||
@ -652,7 +713,7 @@
|
|||||||
{'EXIT', Reason} ->
|
{'EXIT', Reason} ->
|
||||||
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
|
?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]),
|
||||||
{error, 'internal-server-error'};
|
{error, 'internal-server-error'};
|
||||||
@@ -3669,6 +3545,16 @@
|
@@ -3663,6 +3537,16 @@
|
||||||
{error, 'internal-server-error'}
|
{error, 'internal-server-error'}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -90,14 +90,18 @@ init() ->
|
|||||||
ok = create_table().
|
ok = create_table().
|
||||||
|
|
||||||
subscribe_node(_JID, _NodeID, Options) ->
|
subscribe_node(_JID, _NodeID, Options) ->
|
||||||
SubId = make_subid(),
|
SubID = make_subid(),
|
||||||
ok = ?DB_MOD:add_subscription(#pubsub_subscription{subid = SubId, options = Options}),
|
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||||
{result, SubId}.
|
{result, SubID}.
|
||||||
|
|
||||||
unsubscribe_node(_JID, _NodeID, SubID) ->
|
unsubscribe_node(_JID, _NodeID, SubID) ->
|
||||||
{ok, Sub} = ?DB_MOD:read_subscription(SubID),
|
case ?DB_MOD:read_subscription(SubID) of
|
||||||
ok = ?DB_MOD:delete_subscription(SubID),
|
{ok, Sub} ->
|
||||||
{result, Sub}.
|
?DB_MOD:delete_subscription(SubID),
|
||||||
|
{result, Sub};
|
||||||
|
notfound ->
|
||||||
|
{error, notfound}
|
||||||
|
end.
|
||||||
|
|
||||||
get_subscription(_JID, _NodeID, SubID) ->
|
get_subscription(_JID, _NodeID, SubID) ->
|
||||||
case ?DB_MOD:read_subscription(SubID) of
|
case ?DB_MOD:read_subscription(SubID) of
|
||||||
@ -108,10 +112,11 @@ get_subscription(_JID, _NodeID, SubID) ->
|
|||||||
set_subscription(_JID, _NodeID, SubID, Options) ->
|
set_subscription(_JID, _NodeID, SubID, Options) ->
|
||||||
case ?DB_MOD:read_subscription(SubID) of
|
case ?DB_MOD:read_subscription(SubID) of
|
||||||
{ok, _} ->
|
{ok, _} ->
|
||||||
ok = ?DB_MOD:update_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
?DB_MOD:update_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||||
{result, ok};
|
{result, ok};
|
||||||
notfound ->
|
notfound ->
|
||||||
{error, notfound}
|
?DB_MOD:add_subscription(#pubsub_subscription{subid = SubID, options = Options}),
|
||||||
|
{result, ok}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
get_options_xform(Lang, Options) ->
|
get_options_xform(Lang, Options) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user