26
1
mirror of https://github.com/processone/ejabberd.git synced 2025-01-01 17:53:00 +01:00

EJAB-739 and EJAB-751 improvements

SVN Revision: 1576
This commit is contained in:
Christophe Romain 2008-09-25 17:26:06 +00:00
parent eabd25a8bf
commit 70dd325aef
13 changed files with 262 additions and 59 deletions

View File

@ -1,3 +1,22 @@
2008-09-24 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: Allow PEP node type to be mapped with
namespace (EJAB-739). Change get_items to use From (EJAB-751). (Thanks
to Eric Cestari)
* src/mod_pubsub/gen_pubsub_node.erl: Likewise
* src/mod_pubsub/node_dispatch.erl: Likewise
* src/mod_pubsub/node_buddy.erl: Likewise
* src/mod_pubsub/node_zoo.erl: Likewise
* src/mod_pubsub/node.template: Likewise
* src/mod_pubsub/node_private.erl: Likewise
* src/mod_pubsub/node_public.erl: Likewise
* src/mod_pubsub/node_default.erl: Likewise
* src/mod_pubsub/node_pep.erl: Likewise
* src/mod_pubsub/node_club.erl: Likewise
* src/mod_pubsub/node_mb.erl: Added PEP microglobing node (Thanks to
Eric Cestari)
2008-09-22 Mickael Remond <mremond@process-one.net>
* src/mod_configure.erl: Fix adhoc commands reply types for

View File

@ -63,7 +63,7 @@ behaviour_info(callbacks) ->
{get_state, 3},
{set_state, 1},
{get_items, 7},
{get_items, 2},
{get_items, 3},
{get_item, 8},
{get_item, 3},
{set_item, 1},

View File

@ -77,7 +77,8 @@
delete_item/4,
get_configure/4,
set_configure/5,
get_items/2,
get_items/3,
tree_action/3,
node_action/3,
node_action/4
]).
@ -114,6 +115,7 @@
-record(state, {server_host,
host,
access,
pep_mapping = [],
nodetree = ?STDTREE,
plugins = [?STDNODE]}).
@ -175,7 +177,7 @@ init([ServerHost, Opts]) ->
{?NS_PUBSUB, ejabberd_sm, iq_sm},
{?NS_PUBSUB_OWNER, ejabberd_sm, iq_sm}]),
ejabberd_router:register_route(Host),
{Plugins, NodeTree} = init_plugins(Host, ServerHost, Opts),
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
update_database(Host),
ets:new(gen_mod:get_module_proc(Host, pubsub_state), [set, named_table]),
ets:insert(gen_mod:get_module_proc(Host, pubsub_state), {nodetree, NodeTree}),
@ -183,10 +185,12 @@ init([ServerHost, Opts]) ->
ets:new(gen_mod:get_module_proc(ServerHost, pubsub_state), [set, named_table]),
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {nodetree, NodeTree}),
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {plugins, Plugins}),
ets:insert(gen_mod:get_module_proc(ServerHost, pubsub_state), {pep_mapping, PepMapping}),
init_nodes(Host, ServerHost),
{ok, #state{host = Host,
server_host = ServerHost,
access = Access,
pep_mapping = PepMapping,
nodetree = NodeTree,
plugins = Plugins}}.
@ -209,12 +213,14 @@ init_plugins(Host, ServerHost, Opts) ->
?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]),
lists:foreach(fun(Name) ->
?DEBUG("** init ~s plugin",[Name]),
Plugin = list_to_atom(?PLUGIN_PREFIX ++ Name),
Plugin:init(Host, ServerHost, Opts)
end, Plugins),
{Plugins, TreePlugin}.
{Plugins, TreePlugin, PepMapping}.
terminate_plugins(Host, ServerHost, Plugins, TreePlugin) ->
lists:foreach(fun(Name) ->
@ -371,11 +377,11 @@ disco_sm_items(Acc, _From, To, [], _Lang) ->
{result, NodeItems ++ Items}
end;
disco_sm_items(Acc, _From, To, Node, _Lang) ->
disco_sm_items(Acc, From, To, Node, _Lang) ->
%% TODO, use iq_disco_items(Host, Node, From)
Host = To#jid.lserver,
LJID = jlib:jid_tolower(jlib:jid_remove_resource(To)),
case get_items(Host, Node) of
case get_items(Host, Node, From) of
[] ->
Acc;
AllItems ->
@ -430,6 +436,8 @@ handle_call(server_host, _From, State) ->
{reply, State#state.server_host, State};
handle_call(plugins, _From, State) ->
{reply, State#state.plugins, State};
handle_call(pep_mapping, _From, State) ->
{reply, State#state.pep_mapping, State};
handle_call(nodetree, _From, State) ->
{reply, State#state.nodetree, State};
handle_call(stop, _From, State) ->
@ -717,7 +725,7 @@ node_disco_info(Host, Node, From, Identity, Features) ->
[] ->
["leaf"]; %% No sub-nodes: it's a leaf node
_ ->
case node_call(Type, get_items, [Host, Node]) of
case node_call(Type, get_items, [Host, Node, From]) of
{result, []} -> ["collection"];
{result, _} -> ["leaf", "collection"];
_ -> []
@ -782,7 +790,7 @@ iq_disco_items(Host, Item, From) ->
%% TODO That is, remove name attribute
Action =
fun(#pubsub_node{type = Type}) ->
NodeItems = case node_call(Type, get_items, [Host, Node]) of
NodeItems = case node_call(Type, get_items, [Host, Node, From]) of
{result, I} -> I;
_ -> []
end,
@ -1183,10 +1191,7 @@ create_node(Host, ServerHost, [], Owner, Type, Access, Configuration) ->
{error, extended_error(?ERR_NOT_ACCEPTABLE, "nodeid-required")}
end;
create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
Type = case Host of
{_User, _Server, _Resource} -> ?PEPNODE;
_ -> GivenType
end,
Type = select_type(ServerHost, Host, Node, GivenType),
Parent = lists:sublist(Node, length(Node) - 1),
%% TODO, check/set node_type = Type
ParseOptions = case xml:remove_cdata(Configuration) of
@ -1488,12 +1493,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
%% handles auto-create feature
%% for automatic node creation. we'll take the default node type:
%% first listed into the plugins configuration option, or pep
Type = case Host of
{_User, _Server, _Resource} ->
?PEPNODE;
_ ->
hd(plugins(ServerHost))
end,
Type = select_type(ServerHost, Host, Node),
case lists:member("auto-create", features(Type)) of
true ->
case create_node(Host, ServerHost, Node, Publisher, Type) of
@ -1712,8 +1712,8 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
end
end.
get_items(Host, Node) ->
case node_action(Host, Node, get_items, [Host, Node]) of
get_items(Host, Node, From) ->
case node_action(Host, Node, get_items, [Host, Node, From]) of
{result, Items} -> Items;
_ -> []
end.
@ -1723,15 +1723,15 @@ get_items(Host, Node) ->
%% Node = pubsubNode()
%% LJID = {U, S, []}
%% @doc <p>Resend the items of a node to the user.</p>
send_all_items(Host, Node, LJID) ->
send_items(Host, Node, LJID, all).
%send_all_items(Host, Node, LJID) ->
% send_items(Host, Node, LJID, all).
send_last_item(Host, Node, LJID) ->
send_items(Host, Node, LJID, last).
%% TODO use cache-last-item feature
send_items(Host, Node, LJID, Number) ->
ToSend = case get_items(Host, Node) of
ToSend = case get_items(Host, Node, LJID) of
[] ->
[];
Items ->
@ -2411,11 +2411,8 @@ get_configure(Host, Node, From, Lang) ->
end,
transaction(Host, Node, Action, sync_dirty).
get_default(Host, _Node, _From, Lang) ->
Type = case Host of
{_, _, _} -> ?PEPNODE;
_ -> hd(plugins(Host))
end,
get_default(Host, Node, _From, Lang) ->
Type=select_type(Host, Host, Node),
Options = node_options(Type),
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
[{xmlelement, "default", [],
@ -2663,6 +2660,19 @@ plugins(Host) ->
[{plugins, PL}] -> PL;
_ -> [?STDNODE]
end.
select_type(ServerHost, Host, Node, Type)->
?DEBUG("SELECT_TYPE : ~p~n", [Node]),
case Host of
{_User, _Server, _Resource} ->
case ets:lookup(gen_mod:get_module_proc(ServerHost, pubsub_state), pep_mapping) of
[{pep_mapping, PM}] -> ?DEBUG("SELECT_TYPE : ~p~n", [PM]), proplists:get_value(Node, PM,?PEPNODE);
R -> ?DEBUG("SELECT_TYPE why ?: ~p~n", [R]), ?PEPNODE
end;
_ ->
Type
end.
select_type(ServerHost, Host, Node) ->
select_type(ServerHost, Host, Node,hd(plugins(ServerHost))).
features() ->
[
@ -2811,3 +2821,4 @@ uniqid() ->
get_item_name(Host, Node, Id) ->
{result, Name} = node_action(Host, Node, get_item_name, [Host, Node, Id]),
Name.

View File

@ -62,7 +62,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1
@ -168,8 +168,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId)
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -63,7 +63,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -171,8 +171,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -63,7 +63,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -170,8 +170,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -1,4 +1,4 @@
%%% ====================================================================
%%% ====================================================================
%%% ``The contents of this file are subject to the Erlang Public License,
%%% Version 1.1, (the "License"); you may not use this file except in
%%% compliance with the License. You should have received a copy of the
@ -70,7 +70,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -705,9 +705,9 @@ set_state(_) ->
%% relational database), or they can even decide not to persist any items.</p>
%% <p>If a PubSub plugin wants to delegate the item storage to the default node,
%% they can implement this function like this:
%% ```get_items(Host, Node) ->
%% node_default:get_items(Host, Node).'''</p>
get_items(Host, Node) ->
%% ```get_items(Host, Node, From) ->
%% node_default:get_items(Host, Node, From).'''</p>
get_items(Host, Node, _From) ->
Items = mnesia:match_object(
#pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}),
{result, Items}.
@ -747,7 +747,7 @@ get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubI
%% % Payment is required for a subscription
%% {error, ?ERR_PAYMENT_REQUIRED};
true ->
get_items(Host, Node)
get_items(Host, Node, JID)
end.
%% @spec (Host, Node, ItemId) -> [Item] | []

View File

@ -61,7 +61,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -173,8 +173,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

172
src/mod_pubsub/node_mb.erl Normal file
View File

@ -0,0 +1,172 @@
%%% @doc The module <strong>{@module}</strong> is the pep microblog PubSub plugin.
%%% <p> To be used, mod_pubsub must be configured :
%%% {mod_pubsub, [ % requires mod_caps
%%% {access_createnode, pubsub_createnode},
%%% {plugins, ["default", "pep","mb"]},
%%% {pep_mapping, [{"urn:xmpp:microblog", "mb"}]}
%%% ]},
%%% <p>PubSub plugin nodes are using the {@link gen_pubsub_node} behaviour.</p>
-module(node_mb).
-author('eric@ohmforce.com').
-include("ejabberd.hrl").
-include("pubsub.hrl").
-include("jlib.hrl").
-behaviour(gen_pubsub_node).
%% API definition
-export([init/3, terminate/2,
options/0, features/0,
create_node_permission/6,
create_node/3,
delete_node/2,
purge_node/3,
subscribe_node/8,
unsubscribe_node/5,
publish_item/7,
delete_item/4,
remove_extra_items/4,
get_entity_affiliations/2,
get_node_affiliations/2,
get_affiliation/3,
set_affiliation/4,
get_entity_subscriptions/2,
get_node_subscriptions/2,
get_subscription/3,
set_subscription/4,
get_states/2,
get_state/3,
set_state/1,
get_items/7,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
get_item_name/3
]).
init(Host, ServerHost, Opts) ->
node_pep:init(Host, ServerHost, Opts).
terminate(Host, ServerHost) ->
node_pep:terminate(Host, ServerHost),
ok.
options() ->
[{node_type, pep},
{deliver_payloads, true},
{notify_config, false},
{notify_delete, false},
{notify_retract, false},
{persist_items, true},
{max_items, ?MAXITEMS},
{subscribe, true},
{access_model, presence},
{roster_groups_allowed, []},
{publish_model, publishers},
{max_payload_size, ?MAX_PAYLOAD_SIZE},
{send_last_published_item, on_sub_and_presence},
{deliver_notifications, true},
{presence_based_delivery, true}].
features() ->
["create-nodes", %*
"auto-create", %*
"auto-subscribe", %*
"delete-nodes", %*
"filtered-notifications", %*
"modify-affiliations",
"outcast-affiliation",
"persistent-items",
"publish", %*
"purge-nodes",
"retract-items",
"retrieve-affiliations",
"retrieve-items", %*
"retrieve-subscriptions",
"subscribe" %*
].
create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) ->
node_pep:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access).
create_node(Host, Node, Owner) ->
node_pep:create_node(Host, Node, Owner).
delete_node(Host, Removed) ->
node_pep:delete_node(Host, Removed).
subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
SendLast, PresenceSubscription, RosterGroup) ->
node_pep:subscribe_node(
Host, Node, Sender, Subscriber, AccessModel, SendLast,
PresenceSubscription, RosterGroup).
unsubscribe_node(Host, Node, Sender, Subscriber, SubID) ->
node_pep:unsubscribe_node(Host, Node, Sender, Subscriber, SubID).
publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload) ->
node_pep:publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload).
remove_extra_items(Host, Node, MaxItems, ItemIds) ->
node_pep:remove_extra_items(Host, Node, MaxItems, ItemIds).
delete_item(Host, Node, JID, ItemId) ->
node_pep:delete_item(Host, Node, JID, ItemId).
purge_node(Host, Node, Owner) ->
node_pep:purge_node(Host, Node, Owner).
get_entity_affiliations(Host, Owner) ->
node_pep:get_entity_affiliations(Host, Owner).
get_node_affiliations(Host, Node) ->
node_pep:get_node_affiliations(Host, Node).
get_affiliation(Host, Node, Owner) ->
node_pep:get_affiliation(Host, Node, Owner).
set_affiliation(Host, Node, Owner, Affiliation) ->
node_pep:set_affiliation(Host, Node, Owner, Affiliation).
get_entity_subscriptions(Host,Owner) ->
node_pep:get_entity_subscriptions(Host, Owner).
get_node_subscriptions(Host, Node) ->
node_pep:get_node_subscriptions(Host, Node).
get_subscription(Host,Node,Owner) ->
node_pep:get_subscription(Host,Node,Owner).
set_subscription(Host, Node, Owner, Subscription) ->
node_pep:set_subscription(Host, Node, Owner, Subscription).
get_states(Host, Node) ->
node_pep:get_states(Host, Node).
get_state(Host, Node, JID) ->
node_pep:get_state(Host, Node, JID).
set_state(State) ->
node_pep:set_state(State).
get_items(Host, Node, From) ->
node_pep:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_pep:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
get_item(Host, Node, ItemId) ->
node_pep:get_item(Host, Node, ItemId).
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_pep:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
set_item(Item) ->
node_pep:set_item(Item).
get_item_name(Host, Node, Id) ->
node_pep:get_item_name(Host, Node, Id).

View File

@ -59,7 +59,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -123,7 +123,8 @@ create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
{User, Server, _} -> true;
_ -> false
end;
_ ->
E ->
?DEBUG("Create not allowed : ~p~n", [E]),
false
end
end,
@ -215,8 +216,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -63,7 +63,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -173,8 +173,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -63,7 +63,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -170,8 +170,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).

View File

@ -54,7 +54,7 @@
get_state/3,
set_state/1,
get_items/7,
get_items/2,
get_items/3,
get_item/8,
get_item/3,
set_item/1,
@ -163,8 +163,8 @@ get_state(Host, Node, JID) ->
set_state(State) ->
node_default:set_state(State).
get_items(Host, Node) ->
node_default:get_items(Host, Node).
get_items(Host, Node, From) ->
node_default:get_items(Host, Node, From).
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).