mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-22 17:28:25 +01:00
PubSub: improve get_entity_* API
SVN Revision: 2090
This commit is contained in:
parent
b5964c2a5f
commit
dffe808895
@ -225,8 +225,8 @@ init_plugins(Host, ServerHost, Opts) ->
|
|||||||
gen_mod:get_opt(nodetree, Opts, ?STDTREE)),
|
gen_mod:get_opt(nodetree, Opts, ?STDTREE)),
|
||||||
?DEBUG("** tree plugin is ~p",[TreePlugin]),
|
?DEBUG("** tree plugin is ~p",[TreePlugin]),
|
||||||
TreePlugin:init(Host, ServerHost, Opts),
|
TreePlugin:init(Host, ServerHost, Opts),
|
||||||
Plugins = lists:usort(gen_mod:get_opt(plugins, Opts, []) ++ [?STDNODE]),
|
Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]),
|
||||||
PepMapping = lists:usort(gen_mod:get_opt(pep_mapping, Opts, [])),
|
PepMapping = gen_mod:get_opt(pep_mapping, Opts, []),
|
||||||
?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
|
?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
|
||||||
lists:foreach(fun(Name) ->
|
lists:foreach(fun(Name) ->
|
||||||
?DEBUG("** init ~s plugin",[Name]),
|
?DEBUG("** init ~s plugin",[Name]),
|
||||||
@ -387,17 +387,13 @@ send_loop(State) ->
|
|||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({Node, subscribed, SubJID}) ->
|
fun({Node, subscribed, SubJID}) ->
|
||||||
if (SubJID == LJID) or (SubJID == BJID) ->
|
if (SubJID == LJID) or (SubJID == BJID) ->
|
||||||
case tree_action(Host, get_node, [Host, Node, JID]) of
|
#pubsub_node{options = Options, type = Type, id = NodeId} = Node,
|
||||||
#pubsub_node{options = Options, type = Type, id = NodeId} ->
|
|
||||||
case get_option(Options, send_last_published_item) of
|
case get_option(Options, send_last_published_item) of
|
||||||
on_sub_and_presence ->
|
on_sub_and_presence ->
|
||||||
send_items(Host, Node, NodeId, Type, SubJID, last);
|
send_items(Host, Node, NodeId, Type, SubJID, last);
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end;
|
end;
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end;
|
|
||||||
true ->
|
true ->
|
||||||
% resource not concerned about that subscription
|
% resource not concerned about that subscription
|
||||||
ok
|
ok
|
||||||
@ -700,18 +696,19 @@ handle_cast({remove_user, LUser, LServer}, State) ->
|
|||||||
lists:foreach(fun(PType) ->
|
lists:foreach(fun(PType) ->
|
||||||
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Owner]),
|
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Owner]),
|
||||||
lists:foreach(fun
|
lists:foreach(fun
|
||||||
({Node, subscribed, JID}) ->
|
({#pubsub_node{nodeid = {H, N}}, subscribed, JID}) ->
|
||||||
unsubscribe_node(Host, Node, Owner, JID, all);
|
unsubscribe_node(H, N, Owner, JID, all);
|
||||||
(_) ->
|
(_) ->
|
||||||
ok
|
ok
|
||||||
end, Subscriptions)
|
end, Subscriptions),
|
||||||
|
{result, Affiliations} = node_action(Host, PType, get_entity_affiliations, [Host, Owner]),
|
||||||
|
lists:foreach(fun
|
||||||
|
({#pubsub_node{nodeid = {H, N}}, owner}) ->
|
||||||
|
delete_node(H, N, Owner);
|
||||||
|
(_) ->
|
||||||
|
ok
|
||||||
|
end, Affiliations)
|
||||||
end, State#state.plugins),
|
end, State#state.plugins),
|
||||||
%% remove user's PEP nodes
|
|
||||||
lists:foreach(fun(#pubsub_node{nodeid={NodeKey, NodeName}}) ->
|
|
||||||
delete_node(NodeKey, NodeName, Owner)
|
|
||||||
end, tree_action(Host, get_nodes, [jlib:jid_tolower(Owner), Owner])),
|
|
||||||
%% remove user's nodes
|
|
||||||
delete_node(Host, ["home", LServer, LUser], Owner),
|
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
|
||||||
handle_cast({unsubscribe, Subscriber, Owner}, State) ->
|
handle_cast({unsubscribe, Subscriber, Owner}, State) ->
|
||||||
@ -721,20 +718,18 @@ handle_cast({unsubscribe, Subscriber, Owner}, State) ->
|
|||||||
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Subscriber]),
|
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Subscriber]),
|
||||||
lists:foreach(fun
|
lists:foreach(fun
|
||||||
({Node, subscribed, JID}) ->
|
({Node, subscribed, JID}) ->
|
||||||
Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId}) ->
|
#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId} = Node,
|
||||||
case get_option(Options, access_model) of
|
case get_option(Options, access_model) of
|
||||||
presence ->
|
presence ->
|
||||||
case lists:member(BJID, Owners) of
|
case lists:member(BJID, Owners) of
|
||||||
true ->
|
true ->
|
||||||
node_call(Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
node_action(Host, Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||||
false ->
|
false ->
|
||||||
{result, ok}
|
{result, ok}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
{result, ok}
|
{result, ok}
|
||||||
end
|
end;
|
||||||
end,
|
|
||||||
transaction(Host, Node, Action, sync_dirty);
|
|
||||||
(_) ->
|
(_) ->
|
||||||
ok
|
ok
|
||||||
end, Subscriptions)
|
end, Subscriptions)
|
||||||
@ -2036,7 +2031,7 @@ get_affiliations(Host, JID, Plugins) when is_list(Plugins) ->
|
|||||||
{ok, Affiliations} ->
|
{ok, Affiliations} ->
|
||||||
Entities = lists:flatmap(
|
Entities = lists:flatmap(
|
||||||
fun({_, none}) -> [];
|
fun({_, none}) -> [];
|
||||||
({Node, Affiliation}) ->
|
({#pubsub_node{nodeid = {_, Node}}, Affiliation}) ->
|
||||||
[{xmlelement, "affiliation",
|
[{xmlelement, "affiliation",
|
||||||
[{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)],
|
[{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)],
|
||||||
[]}]
|
[]}]
|
||||||
@ -2175,7 +2170,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
|||||||
Entities = lists:flatmap(
|
Entities = lists:flatmap(
|
||||||
fun({_, none}) ->
|
fun({_, none}) ->
|
||||||
[];
|
[];
|
||||||
({SubsNode, Subscription}) ->
|
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) ->
|
||||||
case Node of
|
case Node of
|
||||||
[] ->
|
[] ->
|
||||||
[{xmlelement, "subscription",
|
[{xmlelement, "subscription",
|
||||||
@ -2190,7 +2185,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
|||||||
end;
|
end;
|
||||||
({_, none, _}) ->
|
({_, none, _}) ->
|
||||||
[];
|
[];
|
||||||
({SubsNode, Subscription, SubJID}) ->
|
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) ->
|
||||||
case Node of
|
case Node of
|
||||||
[] ->
|
[] ->
|
||||||
[{xmlelement, "subscription",
|
[{xmlelement, "subscription",
|
||||||
|
@ -549,16 +549,22 @@ purge_node(NodeId, Owner) ->
|
|||||||
%% the default PubSub module. Otherwise, it should return its own affiliation,
|
%% the default PubSub module. Otherwise, it should return its own affiliation,
|
||||||
%% that will be added to the affiliation stored in the main
|
%% that will be added to the affiliation stored in the main
|
||||||
%% <tt>pubsub_state</tt> table.</p>
|
%% <tt>pubsub_state</tt> table.</p>
|
||||||
get_entity_affiliations(_Host, Owner) ->
|
get_entity_affiliations(Host, Owner) ->
|
||||||
SubKey = jlib:jid_tolower(Owner),
|
SubKey = jlib:jid_tolower(Owner),
|
||||||
GenKey = jlib:jid_remove_resource(SubKey),
|
GenKey = jlib:jid_remove_resource(SubKey),
|
||||||
States = mnesia:match_object(
|
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
||||||
%% TODO check if Host needed
|
Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) ->
|
||||||
#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
case mnesia:index_read(pubsub_node, N, #pubsub_node.id) of
|
||||||
Tr = fun(#pubsub_state{stateid = {_, N}, affiliation = A}) ->
|
[#pubsub_node{nodeid = {H, _}} = Node] ->
|
||||||
{get_nodename(N), A}
|
case H of
|
||||||
end,
|
Host -> [{Node, A}|Acc];
|
||||||
{result, lists:map(Tr, States)}.
|
_ -> Acc
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Acc
|
||||||
|
end
|
||||||
|
end, [], States),
|
||||||
|
{result, Reply}.
|
||||||
|
|
||||||
get_node_affiliations(NodeId) ->
|
get_node_affiliations(NodeId) ->
|
||||||
{result, States} = get_states(NodeId),
|
{result, States} = get_states(NodeId),
|
||||||
@ -594,7 +600,7 @@ set_affiliation(NodeId, Owner, Affiliation) ->
|
|||||||
%% the default PubSub module. Otherwise, it should return its own affiliation,
|
%% the default PubSub module. Otherwise, it should return its own affiliation,
|
||||||
%% that will be added to the affiliation stored in the main
|
%% that will be added to the affiliation stored in the main
|
||||||
%% <tt>pubsub_state</tt> table.</p>
|
%% <tt>pubsub_state</tt> table.</p>
|
||||||
get_entity_subscriptions(_Host, Owner) ->
|
get_entity_subscriptions(Host, Owner) ->
|
||||||
{U, D, _} = SubKey = jlib:jid_tolower(Owner),
|
{U, D, _} = SubKey = jlib:jid_tolower(Owner),
|
||||||
GenKey = jlib:jid_remove_resource(SubKey),
|
GenKey = jlib:jid_remove_resource(SubKey),
|
||||||
States = case SubKey of
|
States = case SubKey of
|
||||||
@ -605,10 +611,18 @@ get_entity_subscriptions(_Host, Owner) ->
|
|||||||
++ mnesia:match_object(
|
++ mnesia:match_object(
|
||||||
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
||||||
end,
|
end,
|
||||||
Tr = fun(#pubsub_state{stateid = {J, N}, subscription = S}) ->
|
Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscription = S}, Acc) ->
|
||||||
{get_nodename(N), S, J}
|
case mnesia:index_read(pubsub_node, N, #pubsub_node.id) of
|
||||||
end,
|
[#pubsub_node{nodeid = {H, _}} = Node] ->
|
||||||
{result, lists:map(Tr, States)}.
|
case H of
|
||||||
|
Host -> [{Node, S, J}|Acc];
|
||||||
|
_ -> Acc
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Acc
|
||||||
|
end
|
||||||
|
end, [], States),
|
||||||
|
{result, Reply}.
|
||||||
|
|
||||||
get_node_subscriptions(NodeId) ->
|
get_node_subscriptions(NodeId) ->
|
||||||
{result, States} = get_states(NodeId),
|
{result, States} = get_states(NodeId),
|
||||||
@ -813,10 +827,3 @@ can_fetch_item(none, subscribed) -> true;
|
|||||||
can_fetch_item(none, none) -> false;
|
can_fetch_item(none, none) -> false;
|
||||||
can_fetch_item(_Affiliation, _Subscription) -> false.
|
can_fetch_item(_Affiliation, _Subscription) -> false.
|
||||||
|
|
||||||
%% @spec (NodeId) -> Node
|
|
||||||
%% @doc retreive pubsubNode() representation giving a NodeId
|
|
||||||
get_nodename(NodeId) ->
|
|
||||||
case mnesia:index_read(pubsub_node, NodeId, #pubsub_node.id) of
|
|
||||||
[#pubsub_node{nodeid = {_, Node}}] -> Node;
|
|
||||||
_ -> []
|
|
||||||
end.
|
|
||||||
|
@ -180,8 +180,29 @@ get_affiliation(NodeId, Owner) ->
|
|||||||
set_affiliation(NodeId, Owner, Affiliation) ->
|
set_affiliation(NodeId, Owner, Affiliation) ->
|
||||||
node_default:set_affiliation(NodeId, Owner, Affiliation).
|
node_default:set_affiliation(NodeId, Owner, Affiliation).
|
||||||
|
|
||||||
get_entity_subscriptions(_Host, _Owner) ->
|
get_entity_subscriptions(_Host, Owner) ->
|
||||||
{result, []}.
|
{U, D, _} = SubKey = jlib:jid_tolower(Owner),
|
||||||
|
GenKey = jlib:jid_remove_resource(SubKey),
|
||||||
|
States = case SubKey of
|
||||||
|
GenKey -> mnesia:match_object(
|
||||||
|
#pubsub_state{stateid = {{U, D, '_'}, '_'}, _ = '_'});
|
||||||
|
_ -> mnesia:match_object(
|
||||||
|
#pubsub_state{stateid = {GenKey, '_'}, _ = '_'})
|
||||||
|
++ mnesia:match_object(
|
||||||
|
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
||||||
|
end,
|
||||||
|
Reply = lists:foldl(fun(#pubsub_state{stateid = {J, N}, subscription = S}, Acc) ->
|
||||||
|
case mnesia:index_read(pubsub_node, N, #pubsub_node.id) of
|
||||||
|
[#pubsub_node{nodeid = {H, _}} = Node] ->
|
||||||
|
case H of
|
||||||
|
{_, D, _} -> [{Node, S, J}|Acc];
|
||||||
|
_ -> Acc
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Acc
|
||||||
|
end
|
||||||
|
end, [], States),
|
||||||
|
{result, Reply}.
|
||||||
|
|
||||||
get_node_subscriptions(NodeId) ->
|
get_node_subscriptions(NodeId) ->
|
||||||
%% note: get_node_subscriptions is used for broadcasting
|
%% note: get_node_subscriptions is used for broadcasting
|
||||||
@ -191,11 +212,11 @@ get_node_subscriptions(NodeId) ->
|
|||||||
%% DO NOT REMOVE
|
%% DO NOT REMOVE
|
||||||
node_default:get_node_subscriptions(NodeId).
|
node_default:get_node_subscriptions(NodeId).
|
||||||
|
|
||||||
get_subscription(_NodeId, _Owner) ->
|
get_subscription(NodeId, Owner) ->
|
||||||
{result, none}.
|
node_default:get_subscription(NodeId, Owner).
|
||||||
|
|
||||||
set_subscription(_NodeId, _Owner, _Subscription) ->
|
set_subscription(NodeId, Owner, Subscription) ->
|
||||||
ok.
|
node_default:set_subscription(NodeId, Owner, Subscription).
|
||||||
|
|
||||||
get_states(NodeId) ->
|
get_states(NodeId) ->
|
||||||
node_default:get_states(NodeId).
|
node_default:get_states(NodeId).
|
||||||
|
@ -26,10 +26,9 @@
|
|||||||
%%% @doc The module <strong>{@module}</strong> is the PubSub node tree plugin that
|
%%% @doc The module <strong>{@module}</strong> is the PubSub node tree plugin that
|
||||||
%%% allow virtual nodes handling.
|
%%% allow virtual nodes handling.
|
||||||
%%% <p>PubSub node tree plugins are using the {@link gen_nodetree} behaviour.</p>
|
%%% <p>PubSub node tree plugins are using the {@link gen_nodetree} behaviour.</p>
|
||||||
%%% <p><strong>The API isn't stabilized yet</strong>. The pubsub plugin
|
%%% This plugin development is still a work in progress. Due to optimizations in
|
||||||
%%% development is still a work in progress. However, the system is already
|
%%% mod_pubsub, this plugin can not work anymore without altering functioning.
|
||||||
%%% useable and useful as is. Please, send us comments, feedback and
|
%%% Please, send us comments, feedback and improvements.</p>
|
||||||
%%% improvements.</p>
|
|
||||||
|
|
||||||
-module(nodetree_virtual).
|
-module(nodetree_virtual).
|
||||||
-author('christophe.romain@process-one.net').
|
-author('christophe.romain@process-one.net').
|
||||||
@ -83,14 +82,13 @@ options() ->
|
|||||||
set_node(_NodeRecord) ->
|
set_node(_NodeRecord) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
get_node(Host, Node, _From) ->
|
|
||||||
get_node(Host, Node).
|
|
||||||
|
|
||||||
%% @spec (Host, Node) -> pubsubNode()
|
%% @spec (Host, Node) -> pubsubNode()
|
||||||
%% Host = mod_pubsub:host()
|
%% Host = mod_pubsub:host()
|
||||||
%% Node = mod_pubsub:pubsubNode()
|
%% Node = mod_pubsub:pubsubNode()
|
||||||
%% @doc <p>Virtual node tree does not handle a node database. Any node is considered
|
%% @doc <p>Virtual node tree does not handle a node database. Any node is considered
|
||||||
%% as existing. Node record contains default values.</p>
|
%% as existing. Node record contains default values.</p>
|
||||||
|
get_node(Host, Node, _From) ->
|
||||||
|
get_node(Host, Node).
|
||||||
get_node(Host, Node) ->
|
get_node(Host, Node) ->
|
||||||
#pubsub_node{nodeid = {Host, Node}}.
|
#pubsub_node{nodeid = {Host, Node}}.
|
||||||
|
|
||||||
|
@ -82,8 +82,8 @@
|
|||||||
|
|
||||||
%%% @type pubsubNode() = #pubsub_node{
|
%%% @type pubsubNode() = #pubsub_node{
|
||||||
%%% nodeid = {Host::host(), Node::pubsubNode()},
|
%%% nodeid = {Host::host(), Node::pubsubNode()},
|
||||||
%%% parentid = {Host::host(), Node::pubsubNode()},
|
%%% parentid = Node::pubsubNode(),
|
||||||
%%% nodeidx = int().
|
%%% nodeidx = int(). % can be anything you want
|
||||||
%%% type = nodeType(),
|
%%% type = nodeType(),
|
||||||
%%% options = [nodeOption()]}
|
%%% options = [nodeOption()]}
|
||||||
%%% <p>This is the format of the <tt>nodes</tt> table. The type of the table
|
%%% <p>This is the format of the <tt>nodes</tt> table. The type of the table
|
||||||
@ -98,7 +98,7 @@
|
|||||||
}).
|
}).
|
||||||
|
|
||||||
%%% @type pubsubState() = #pubsub_state{
|
%%% @type pubsubState() = #pubsub_state{
|
||||||
%%% stateid = {ljid(), pubsubNodeId()}},
|
%%% stateid = {ljid(), nodeidx()}},
|
||||||
%%% items = [ItemId::string()],
|
%%% items = [ItemId::string()],
|
||||||
%%% affiliation = affiliation(),
|
%%% affiliation = affiliation(),
|
||||||
%%% subscription = subscription()}.
|
%%% subscription = subscription()}.
|
||||||
@ -111,9 +111,9 @@
|
|||||||
}).
|
}).
|
||||||
|
|
||||||
%%% @type pubsubItem() = #pubsub_item{
|
%%% @type pubsubItem() = #pubsub_item{
|
||||||
%%% itemid = {ItemId::string(), pubsubNodeId()}},
|
%%% itemid = {ItemId::string(), nodeidx()}},
|
||||||
%%% creation = {ljid(), now()},
|
%%% creation = {now(), ljid()},
|
||||||
%%% modification = {ljid(), now()},
|
%%% modification = {now(), ljid()},
|
||||||
%%% payload = XMLContent::string()}.
|
%%% payload = XMLContent::string()}.
|
||||||
%%% <p>This is the format of the <tt>published items</tt> table. The type of the
|
%%% <p>This is the format of the <tt>published items</tt> table. The type of the
|
||||||
%%% table is: <tt>set</tt>,<tt>disc</tt>,<tt>fragmented</tt>.</p>
|
%%% table is: <tt>set</tt>,<tt>disc</tt>,<tt>fragmented</tt>.</p>
|
||||||
|
Loading…
Reference in New Issue
Block a user