mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
PubSub: improve get_entity_* API
SVN Revision: 2091
This commit is contained in:
parent
b473862da6
commit
2e26b6bf8b
@ -227,8 +227,8 @@ 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, [])),
|
||||
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]),
|
||||
@ -389,17 +389,13 @@ 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} ->
|
||||
#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;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
true ->
|
||||
% resource not concerned about that subscription
|
||||
ok
|
||||
@ -708,18 +704,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:short_prepd_bare_jid(Owner), Owner])),
|
||||
%% remove user's nodes
|
||||
delete_node(Host, ["home", LServer, LUser], Owner),
|
||||
{noreply, State};
|
||||
|
||||
handle_cast({unsubscribe, Subscriber, Owner}, State) ->
|
||||
@ -729,20 +726,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}) ->
|
||||
#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_call(Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||
node_action(Host, Type, unsubscribe_node, [NodeId, Subscriber, JID, all]);
|
||||
false ->
|
||||
{result, ok}
|
||||
end;
|
||||
_ ->
|
||||
{result, ok}
|
||||
end
|
||||
end,
|
||||
transaction(Host, Node, Action, sync_dirty);
|
||||
end;
|
||||
(_) ->
|
||||
ok
|
||||
end, Subscriptions)
|
||||
@ -2047,7 +2042,7 @@ get_affiliations(Host, JID, Plugins) when is_list(Plugins) ->
|
||||
{ok, Affiliations} ->
|
||||
Entities = lists:flatmap(
|
||||
fun({_, none}) -> [];
|
||||
({Node, Affiliation}) ->
|
||||
({#pubsub_node{nodeid = {_, Node}}, Affiliation}) ->
|
||||
[#xmlel{ns = ?NS_PUBSUB, name = 'affiliation', attrs =
|
||||
[?XMLATTR('node', node_to_string(Node)),
|
||||
?XMLATTR('affiliation', affiliation_to_string(Affiliation))]}]
|
||||
@ -2189,7 +2184,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
|
||||
[] ->
|
||||
[#xmlel{ns = ?NS_PUBSUB, name = 'subscription', attrs =
|
||||
@ -2203,7 +2198,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
|
||||
[] ->
|
||||
[#xmlel{ns = ?NS_PUBSUB, name = 'subscription', attrs =
|
||||
|
@ -549,14 +549,21 @@ 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) ->
|
||||
GenKey = jlib:short_prepd_bare_jid(Owner),
|
||||
States = mnesia:match_object(
|
||||
#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),
|
||||
@ -590,7 +597,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:short_prepd_jid(Owner),
|
||||
GenKey = jlib:short_prepd_bare_jid(SubKey),
|
||||
States = case SubKey of
|
||||
@ -601,10 +608,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),
|
||||
@ -808,10 +823,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.
|
||||
|
@ -182,8 +182,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
|
||||
@ -193,11 +214,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').
|
||||
@ -84,14 +83,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