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,9 +225,9 @@ init_plugins(Host, ServerHost, Opts) ->
|
||||
gen_mod:get_opt(nodetree, Opts, ?STDTREE)),
|
||||
?DEBUG("** tree plugin is ~p",[TreePlugin]),
|
||||
TreePlugin:init(Host, ServerHost, Opts),
|
||||
Plugins = lists:usort(gen_mod:get_opt(plugins, Opts, []) ++ [?STDNODE]),
|
||||
PepMapping = lists:usort(gen_mod:get_opt(pep_mapping, Opts, [])),
|
||||
?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
|
||||
Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]),
|
||||
PepMapping = gen_mod:get_opt(pep_mapping, Opts, []),
|
||||
?DEBUG("** PEP Mapping : ~p~n",[PepMapping]),
|
||||
lists:foreach(fun(Name) ->
|
||||
?DEBUG("** init ~s plugin",[Name]),
|
||||
Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name),
|
||||
@ -387,14 +387,10 @@ send_loop(State) ->
|
||||
lists:foreach(
|
||||
fun({Node, subscribed, SubJID}) ->
|
||||
if (SubJID == LJID) or (SubJID == BJID) ->
|
||||
case tree_action(Host, get_node, [Host, Node, JID]) of
|
||||
#pubsub_node{options = Options, type = Type, id = NodeId} ->
|
||||
case get_option(Options, send_last_published_item) of
|
||||
on_sub_and_presence ->
|
||||
send_items(Host, Node, NodeId, Type, SubJID, last);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
#pubsub_node{options = Options, type = Type, id = NodeId} = Node,
|
||||
case get_option(Options, send_last_published_item) of
|
||||
on_sub_and_presence ->
|
||||
send_items(Host, Node, NodeId, Type, SubJID, last);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
@ -700,18 +696,19 @@ handle_cast({remove_user, LUser, LServer}, State) ->
|
||||
lists:foreach(fun(PType) ->
|
||||
{result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Owner]),
|
||||
lists:foreach(fun
|
||||
({Node, subscribed, JID}) ->
|
||||
unsubscribe_node(Host, Node, Owner, JID, all);
|
||||
({#pubsub_node{nodeid = {H, N}}, subscribed, JID}) ->
|
||||
unsubscribe_node(H, N, Owner, JID, all);
|
||||
(_) ->
|
||||
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),
|
||||
%% 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};
|
||||
|
||||
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]),
|
||||
lists:foreach(fun
|
||||
({Node, subscribed, JID}) ->
|
||||
Action = fun(#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId}) ->
|
||||
case get_option(Options, access_model) of
|
||||
presence ->
|
||||
case lists:member(BJID, Owners) of
|
||||
true ->
|
||||
node_call(Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||
false ->
|
||||
{result, ok}
|
||||
end;
|
||||
_ ->
|
||||
{result, ok}
|
||||
end
|
||||
end,
|
||||
transaction(Host, Node, Action, sync_dirty);
|
||||
#pubsub_node{options = Options, owners = Owners, type = Type, id = NodeId} = Node,
|
||||
case get_option(Options, access_model) of
|
||||
presence ->
|
||||
case lists:member(BJID, Owners) of
|
||||
true ->
|
||||
node_action(Host, Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||
false ->
|
||||
{result, ok}
|
||||
end;
|
||||
_ ->
|
||||
{result, ok}
|
||||
end;
|
||||
(_) ->
|
||||
ok
|
||||
end, Subscriptions)
|
||||
@ -2036,7 +2031,7 @@ get_affiliations(Host, JID, Plugins) when is_list(Plugins) ->
|
||||
{ok, Affiliations} ->
|
||||
Entities = lists:flatmap(
|
||||
fun({_, none}) -> [];
|
||||
({Node, Affiliation}) ->
|
||||
({#pubsub_node{nodeid = {_, Node}}, Affiliation}) ->
|
||||
[{xmlelement, "affiliation",
|
||||
[{"affiliation", affiliation_to_string(Affiliation)}|nodeAttr(Node)],
|
||||
[]}]
|
||||
@ -2175,7 +2170,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
Entities = lists:flatmap(
|
||||
fun({_, none}) ->
|
||||
[];
|
||||
({SubsNode, Subscription}) ->
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
[{xmlelement, "subscription",
|
||||
@ -2190,7 +2185,7 @@ get_subscriptions(Host, Node, JID, Plugins) when is_list(Plugins) ->
|
||||
end;
|
||||
({_, none, _}) ->
|
||||
[];
|
||||
({SubsNode, Subscription, SubJID}) ->
|
||||
({#pubsub_node{nodeid = {_, SubsNode}}, Subscription, SubJID}) ->
|
||||
case Node of
|
||||
[] ->
|
||||
[{xmlelement, "subscription",
|
||||
|
@ -549,16 +549,22 @@ purge_node(NodeId, Owner) ->
|
||||
%% the default PubSub module. Otherwise, it should return its own affiliation,
|
||||
%% that will be added to the affiliation stored in the main
|
||||
%% <tt>pubsub_state</tt> table.</p>
|
||||
get_entity_affiliations(_Host, Owner) ->
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
SubKey = jlib:jid_tolower(Owner),
|
||||
GenKey = jlib:jid_remove_resource(SubKey),
|
||||
States = mnesia:match_object(
|
||||
%% TODO check if Host needed
|
||||
#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
||||
Tr = fun(#pubsub_state{stateid = {_, N}, affiliation = A}) ->
|
||||
{get_nodename(N), A}
|
||||
end,
|
||||
{result, lists:map(Tr, States)}.
|
||||
States = mnesia:match_object(#pubsub_state{stateid = {GenKey, '_'}, _ = '_'}),
|
||||
Reply = lists:foldl(fun(#pubsub_state{stateid = {_, N}, affiliation = A}, Acc) ->
|
||||
case mnesia:index_read(pubsub_node, N, #pubsub_node.id) of
|
||||
[#pubsub_node{nodeid = {H, _}} = Node] ->
|
||||
case H of
|
||||
Host -> [{Node, A}|Acc];
|
||||
_ -> Acc
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, [], States),
|
||||
{result, Reply}.
|
||||
|
||||
get_node_affiliations(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,
|
||||
%% that will be added to the affiliation stored in the main
|
||||
%% <tt>pubsub_state</tt> table.</p>
|
||||
get_entity_subscriptions(_Host, Owner) ->
|
||||
get_entity_subscriptions(Host, Owner) ->
|
||||
{U, D, _} = SubKey = jlib:jid_tolower(Owner),
|
||||
GenKey = jlib:jid_remove_resource(SubKey),
|
||||
States = case SubKey of
|
||||
@ -605,10 +611,18 @@ get_entity_subscriptions(_Host, Owner) ->
|
||||
++ mnesia:match_object(
|
||||
#pubsub_state{stateid = {SubKey, '_'}, _ = '_'})
|
||||
end,
|
||||
Tr = fun(#pubsub_state{stateid = {J, N}, subscription = S}) ->
|
||||
{get_nodename(N), S, J}
|
||||
end,
|
||||
{result, lists:map(Tr, States)}.
|
||||
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
|
||||
Host -> [{Node, S, J}|Acc];
|
||||
_ -> Acc
|
||||
end;
|
||||
_ ->
|
||||
Acc
|
||||
end
|
||||
end, [], States),
|
||||
{result, Reply}.
|
||||
|
||||
get_node_subscriptions(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(_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) ->
|
||||
node_default:set_affiliation(NodeId, Owner, Affiliation).
|
||||
|
||||
get_entity_subscriptions(_Host, _Owner) ->
|
||||
{result, []}.
|
||||
get_entity_subscriptions(_Host, Owner) ->
|
||||
{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) ->
|
||||
%% note: get_node_subscriptions is used for broadcasting
|
||||
@ -191,11 +212,11 @@ get_node_subscriptions(NodeId) ->
|
||||
%% DO NOT REMOVE
|
||||
node_default:get_node_subscriptions(NodeId).
|
||||
|
||||
get_subscription(_NodeId, _Owner) ->
|
||||
{result, none}.
|
||||
get_subscription(NodeId, Owner) ->
|
||||
node_default:get_subscription(NodeId, Owner).
|
||||
|
||||
set_subscription(_NodeId, _Owner, _Subscription) ->
|
||||
ok.
|
||||
set_subscription(NodeId, Owner, Subscription) ->
|
||||
node_default:set_subscription(NodeId, Owner, Subscription).
|
||||
|
||||
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
|
||||
%%% allow virtual nodes handling.
|
||||
%%% <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
|
||||
%%% development is still a work in progress. However, the system is already
|
||||
%%% useable and useful as is. Please, send us comments, feedback and
|
||||
%%% improvements.</p>
|
||||
%%% This plugin development is still a work in progress. Due to optimizations in
|
||||
%%% mod_pubsub, this plugin can not work anymore without altering functioning.
|
||||
%%% Please, send us comments, feedback and improvements.</p>
|
||||
|
||||
-module(nodetree_virtual).
|
||||
-author('christophe.romain@process-one.net').
|
||||
@ -83,14 +82,13 @@ options() ->
|
||||
set_node(_NodeRecord) ->
|
||||
ok.
|
||||
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
|
||||
%% @spec (Host, Node) -> pubsubNode()
|
||||
%% Host = mod_pubsub:host()
|
||||
%% Node = mod_pubsub:pubsubNode()
|
||||
%% @doc <p>Virtual node tree does not handle a node database. Any node is considered
|
||||
%% as existing. Node record contains default values.</p>
|
||||
get_node(Host, Node, _From) ->
|
||||
get_node(Host, Node).
|
||||
get_node(Host, Node) ->
|
||||
#pubsub_node{nodeid = {Host, Node}}.
|
||||
|
||||
|
@ -82,8 +82,8 @@
|
||||
|
||||
%%% @type pubsubNode() = #pubsub_node{
|
||||
%%% nodeid = {Host::host(), Node::pubsubNode()},
|
||||
%%% parentid = {Host::host(), Node::pubsubNode()},
|
||||
%%% nodeidx = int().
|
||||
%%% parentid = Node::pubsubNode(),
|
||||
%%% nodeidx = int(). % can be anything you want
|
||||
%%% type = nodeType(),
|
||||
%%% options = [nodeOption()]}
|
||||
%%% <p>This is the format of the <tt>nodes</tt> table. The type of the table
|
||||
@ -98,7 +98,7 @@
|
||||
}).
|
||||
|
||||
%%% @type pubsubState() = #pubsub_state{
|
||||
%%% stateid = {ljid(), pubsubNodeId()}},
|
||||
%%% stateid = {ljid(), nodeidx()}},
|
||||
%%% items = [ItemId::string()],
|
||||
%%% affiliation = affiliation(),
|
||||
%%% subscription = subscription()}.
|
||||
@ -111,9 +111,9 @@
|
||||
}).
|
||||
|
||||
%%% @type pubsubItem() = #pubsub_item{
|
||||
%%% itemid = {ItemId::string(), pubsubNodeId()}},
|
||||
%%% creation = {ljid(), now()},
|
||||
%%% modification = {ljid(), now()},
|
||||
%%% itemid = {ItemId::string(), nodeidx()}},
|
||||
%%% creation = {now(), ljid()},
|
||||
%%% modification = {now(), ljid()},
|
||||
%%% payload = XMLContent::string()}.
|
||||
%%% <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>
|
||||
|
Loading…
Reference in New Issue
Block a user