25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

merge to lattest trunk r1716

SVN Revision: 1720
This commit is contained in:
Christophe Romain 2008-12-09 00:32:36 +00:00
parent 3bfb2b5cc1
commit 9f2fda6060
7 changed files with 161 additions and 127 deletions

View File

@ -42,7 +42,9 @@ behaviour_info(callbacks) ->
{terminate, 2}, {terminate, 2},
{options, 0}, {options, 0},
{set_node, 1}, {set_node, 1},
{get_node, 3},
{get_node, 2}, {get_node, 2},
{get_nodes, 2},
{get_nodes, 1}, {get_nodes, 1},
{get_subnodes, 3}, {get_subnodes, 3},
{get_subnodes_tree, 2}, {get_subnodes_tree, 2},

View File

@ -356,11 +356,11 @@ disco_sm_features(Acc, From, To, Node, _Lang) ->
Acc Acc
end. end.
disco_sm_items(Acc, _From, To, [], _Lang) -> disco_sm_items(Acc, From, To, [], _Lang) ->
%% TODO, use iq_disco_items(Host, [], From) %% TODO, use iq_disco_items(Host, [], From)
Host = To#jid.ldomain, Host = To#jid.ldomain,
LJID = jlib:short_prepd_bare_jid(To), LJID = jlib:short_prepd_bare_jid(To),
case tree_action(Host, get_nodes, [Host]) of case tree_action(Host, get_nodes, [Host, From]) of
[] -> [] ->
Acc; Acc;
Nodes -> Nodes ->
@ -460,7 +460,7 @@ handle_cast({presence, JID, Pid}, State) ->
{result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]), {result, Subscriptions} = node_action(Type, get_entity_subscriptions, [Host, JID]),
lists:foreach( lists:foreach(
fun({Node, subscribed}) -> fun({Node, subscribed}) ->
case tree_action(Host, get_node, [Host, Node]) of case tree_action(Host, get_node, [Host, Node, JID]) of
#pubsub_node{options = Options} -> #pubsub_node{options = Options} ->
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 ->
@ -477,17 +477,14 @@ handle_cast({presence, JID, Pid}, State) ->
end, State#state.plugins), end, State#state.plugins),
%% and send to From last PEP events published by its contacts %% and send to From last PEP events published by its contacts
case catch ejabberd_c2s:get_subscribed(Pid) of case catch ejabberd_c2s:get_subscribed(Pid) of
ContactsWithCaps when is_list(ContactsWithCaps) -> Contacts when is_list(Contacts) ->
Caps = proplists:get_value(LJID, ContactsWithCaps),
ContactsUsers = lists:usort(lists:map(
fun({{User, Server, _}, _}) -> {User, Server} end, ContactsWithCaps)),
lists:foreach( lists:foreach(
fun({User, Server}) -> fun({User, Server, _}) ->
PepKey = {User, Server, undefined}, Owner = {User, Server, undefined},
lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) -> lists:foreach(fun(#pubsub_node{nodeid = {_, Node}, options = Options}) ->
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 ->
case is_caps_notify(ServerHost, Node, Caps) of case is_caps_notify(ServerHost, Node, LJID) of
true -> true ->
Subscribed = case get_option(Options, access_model) of Subscribed = case get_option(Options, access_model) of
open -> true; open -> true;
@ -499,8 +496,7 @@ handle_cast({presence, JID, Pid}, State) ->
element(2, get_roster_info(User, Server, LJID, Grps)) element(2, get_roster_info(User, Server, LJID, Grps))
end, end,
if Subscribed -> if Subscribed ->
?DEBUG("send ~s's ~s event to ~s",[exmpp_jid:jid_to_list(User, Server),Node,exmpp_jid:jid_to_list(JID)]), send_last_item(Owner, Node, LJID);
send_last_item(PepKey, Node, LJID);
true -> true ->
ok ok
end; end;
@ -510,8 +506,8 @@ handle_cast({presence, JID, Pid}, State) ->
_ -> _ ->
ok ok
end end
end, tree_action(Host, get_nodes, [PepKey])) end, tree_action(Host, get_nodes, [Owner, JID]))
end, ContactsUsers); end, Contacts);
_ -> _ ->
ok ok
end, end,
@ -786,7 +782,7 @@ iq_disco_items(Host, Item, From) ->
Node = string_to_node(SNode), Node = string_to_node(SNode),
%% Note: Multiple Node Discovery not supported (mask on pubsub#type) %% Note: Multiple Node Discovery not supported (mask on pubsub#type)
%% TODO this code is also back-compatible with pubsub v1.8 (for client issue) %% TODO this code is also back-compatible with pubsub v1.8 (for client issue)
%% TODO make it pubsub v1.10 compliant (this breaks client compatibility) %% TODO make it pubsub v1.12 compliant (breaks client compatibility ?)
%% TODO That is, remove name attribute %% TODO That is, remove name attribute
Action = Action =
fun(#pubsub_node{type = Type}) -> fun(#pubsub_node{type = Type}) ->
@ -951,6 +947,10 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
get_subscriptions(Host, From, Plugins); get_subscriptions(Host, From, Plugins);
{get, 'affiliations'} -> {get, 'affiliations'} ->
get_affiliations(Host, From, Plugins); get_affiliations(Host, From, Plugins);
{get, "options"} ->
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")};
{set, "options"} ->
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "subscription-options")};
_ -> _ ->
{error, 'feature-not-implemented'} {error, 'feature-not-implemented'}
end; end;
@ -1024,7 +1024,7 @@ send_authorization_request(Host, Node, Subscriber) ->
#xmlattr{name = 'type', value = "boolean"}, #xmlattr{name = 'type', value = "boolean"},
#xmlattr{name = 'label', value = translate:translate(Lang, "Allow this JID to subscribe to this pubsub node?")}], children = #xmlattr{name = 'label', value = translate:translate(Lang, "Allow this JID to subscribe to this pubsub node?")}], children =
[#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"false">>}]}]}]}]}, [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"false">>}]}]}]}]},
case tree_action(Host, get_node, [Host, Node]) of case tree_action(Host, get_node, [Host, Node, Subscriber]) of
#pubsub_node{owners = Owners} -> #pubsub_node{owners = Owners} ->
lists:foreach( lists:foreach(
fun({U1, S1, R1}) -> fun({U1, S1, R1}) ->
@ -1053,19 +1053,37 @@ find_authorization_response(Packet) ->
[] -> none; [] -> none;
[XFields] when is_list(XFields) -> [XFields] when is_list(XFields) ->
case lists:keysearch("FORM_TYPE", 1, XFields) of case lists:keysearch("FORM_TYPE", 1, XFields) of
{value, {_, ?NS_PUBSUB_SUBSCRIBE_AUTH_s}} -> {value, {_, [?NS_PUBSUB_SUBSCRIBE_AUTH_s]}} ->
XFields; XFields;
_ -> _ ->
invalid invalid
end end
end. end.
%% @spec (Host, JID, Node, Subscription) -> void
%% Host = mod_pubsub:host()
%% JID = jlib:jid()
%% Node = string()
%% Subscription = atom()
%% Plugins = [Plugin::string()]
%% @doc Send a message to JID with the supplied Subscription
send_authorization_approval(Host, JID, Node, Subscription) ->
Stanza = {xmlelement, "message",
[],
[{xmlelement, "event", [{"xmlns", ?NS_PUBSUB_EVENT}],
[{xmlelement, "subscription",
[{"node", Node},
{"jid", jlib:jid_to_string(JID)},
{"subscription", subscription_to_string(Subscription)}],
[]}]}]},
ejabberd_router ! {route, service_jid(Host), JID, Stanza}.
handle_authorization_response(Host, From, To, Packet, XFields) -> handle_authorization_response(Host, From, To, Packet, XFields) ->
case {lists:keysearch("pubsub#node", 1, XFields), case {lists:keysearch("pubsub#node", 1, XFields),
lists:keysearch("pubsub#subscriber_jid", 1, XFields), lists:keysearch("pubsub#subscriber_jid", 1, XFields),
lists:keysearch("pubsub#allow", 1, XFields)} of lists:keysearch("pubsub#allow", 1, XFields)} of
{{value, {_, SNode}}, {value, {_, SSubscriber}}, {{value, {_, [SNode]}}, {value, {_, [SSubscriber]}},
{value, {_, SAllow}}} -> {value, {_, [SAllow]}}} ->
Node = case Host of Node = case Host of
{_, _, _} -> [SNode]; {_, _, _} -> [SNode];
_ -> string:tokens(SNode, "/") _ -> string:tokens(SNode, "/")
@ -1080,7 +1098,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
%%options = Options, %%options = Options,
owners = Owners}) -> owners = Owners}) ->
IsApprover = lists:member(jlib:short_prepd_bare_jid(From), Owners), IsApprover = lists:member(jlib:short_prepd_bare_jid(From), Owners),
Subscription = node_call(Type, get_subscription, [Host, Node, Subscriber]), {result, Subscription} = node_call(Type, get_subscription, [Host, Node, Subscriber]),
if if
not IsApprover -> not IsApprover ->
{error, 'forbidden'}; {error, 'forbidden'};
@ -1091,6 +1109,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
true -> subscribed; true -> subscribed;
false -> none false -> none
end, end,
send_authorization_approval(Host, Subscriber, SNode, NewSubscription),
node_call(Type, set_subscription, [Host, Node, Subscriber, NewSubscription]) node_call(Type, set_subscription, [Host, Node, Subscriber, NewSubscription])
end end
end, end,
@ -1461,8 +1480,11 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
PublishFeature = lists:member("publish", Features), PublishFeature = lists:member("publish", Features),
PublishModel = get_option(Options, publish_model), PublishModel = get_option(Options, publish_model),
MaxItems = max_items(Options), MaxItems = max_items(Options),
PayloadCount = payload_elements(xmlelement, Payload),
PayloadSize = size(term_to_binary(Payload)), PayloadSize = size(term_to_binary(Payload)),
PayloadMaxSize = get_option(Options, max_payload_size), PayloadMaxSize = get_option(Options, max_payload_size),
% pubsub#deliver_payloads true
% pubsub#persist_items true -> 1 item; false -> 0 item
if if
not PublishFeature -> not PublishFeature ->
%% Node does not support item publication %% Node does not support item publication
@ -1470,17 +1492,18 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
PayloadSize > PayloadMaxSize -> PayloadSize > PayloadMaxSize ->
%% Entity attempts to publish very large payload %% Entity attempts to publish very large payload
{error, extended_error('not-acceptable', "payload-too-big")}; {error, extended_error('not-acceptable', "payload-too-big")};
%%?? -> iq_pubsub just does that matchs PayloadCount > 1 ->
%% % Entity attempts to publish item with multiple payload elements or namespace does not match %% Entity attempts to publish item with multiple payload elements
%% {error, extended_error('bad-request', "invalid-payload")}; {error, extended_error('bad-request', "invalid-payload")};
%% % Publisher attempts to publish to persistent node with no item
%% {error, extended_error('bad-request', "item-required")};
Payload == "" -> Payload == "" ->
%% Publisher attempts to publish to payload node with no payload %% Publisher attempts to publish to payload node with no payload
{error, extended_error('bad-request', "payload-required")}; {error, extended_error('bad-request', "payload-required")};
%%?? -> (MaxItems == 0) and (PayloadSize > 0) ->
%% % Publisher attempts to publish to transient notification node with item % Publisher attempts to publish to transient notification node with item
%% {error, extended_error('bad-request', "item-forbidden")}; {error, extended_error('bad-request', "item-forbidden")};
(MaxItems > 0) and (PayloadSize == 0) ->
% Publisher attempts to publish to persistent node with no item
{error, extended_error('bad-request', "item-required")};
true -> true ->
node_call(Type, publish_item, [Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload]) node_call(Type, publish_item, [Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload])
end end
@ -1556,7 +1579,7 @@ delete_item(Host, Node, Publisher, ItemId, ForceNotify) ->
PersistentFeature = lists:member("persistent-items", Features), PersistentFeature = lists:member("persistent-items", Features),
DeleteFeature = lists:member("delete-nodes", Features), DeleteFeature = lists:member("delete-nodes", Features),
if if
%%?? -> iq_pubsub just does that matchs %%-> iq_pubsub just does that matchs
%% %% Request does not specify an item %% %% Request does not specify an item
%% {error, extended_error('bad-request', "item-required")}; %% {error, extended_error('bad-request', "item-required")};
not PersistentFeature -> not PersistentFeature ->
@ -1735,7 +1758,7 @@ send_items(Host, Node, {LU, LS, LR} = LJID, Number) ->
[]; [];
Items -> Items ->
case Number of case Number of
last -> lists:sublist(lists:reverse(Items), 1); last -> lists:last(Items);
all -> Items; all -> Items;
N when N > 0 -> lists:nthtail(length(Items)-N, Items); N when N > 0 -> lists:nthtail(length(Items)-N, Items);
_ -> Items _ -> Items
@ -2098,6 +2121,15 @@ is_to_delivered({User, Server, _}, _, true) ->
end, false, Ss) end, false, Ss)
end. end.
%% @spec (Elem, Payload) -> int()
%% Elem = atom()
%% Payload = term()
%% @doc <p>Count occurence of given element in payload.</p>
payload_elements(Elem, Payload) -> payload_elements(Elem, Payload, 0).
payload_elements(_, [], Count) -> Count;
payload_elements(Elem, [Elem|Tail], Count) -> payload_elements(Elem, Tail, Count+1);
payload_elements(Elem, [_|Tail], Count) -> payload_elements(Elem, Tail, Count).
%%%%%% broadcast functions %%%%%% broadcast functions
broadcast_publish_item(Host, Node, ItemId, _From, Payload) -> broadcast_publish_item(Host, Node, ItemId, _From, Payload) ->
@ -2324,25 +2356,7 @@ broadcast_config_notification(Host, Node, Lang) ->
%% broadcast Stanza to all contacts of the user that are advertising %% broadcast Stanza to all contacts of the user that are advertising
%% interest in this kind of Node. %% interest in this kind of Node.
broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) -> broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
?DEBUG("looking for pid of ~p@~p/~p", [LUser, LServer, LResource]), SenderResource = user_resource(LUser, LServer, LResource),
%% We need to know the resource, so we can ask for presence data.
SenderResource = case LResource of
undefined ->
%% If we don't know the resource, just pick one.
case ejabberd_sm:get_user_resources(LUser, LServer) of
[R|_] ->
R;
[] ->
undefined
end;
_ ->
LResource
end,
case SenderResource of
undefined ->
?DEBUG("~p@~p is offline; can't deliver ~p to contacts", [LUser, LServer, Stanza]),
ok;
_ ->
case ejabberd_sm:get_session_pid(LUser, LServer, SenderResource) of case ejabberd_sm:get_session_pid(LUser, LServer, SenderResource) of
C2SPid when is_pid(C2SPid) -> C2SPid when is_pid(C2SPid) ->
%% set the from address on the notification to the bare JID of the account owner %% set the from address on the notification to the bare JID of the account owner
@ -2350,19 +2364,22 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
%% See XEP-0163 1.1 section 4.3.1 %% See XEP-0163 1.1 section 4.3.1
Sender = exmpp_jid:make_jid(LUser, LServer), Sender = exmpp_jid:make_jid(LUser, LServer),
%%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used %%ReplyTo = jlib:make_jid(LUser, LServer, SenderResource), % This has to be used
case catch ejabberd_c2s:get_subscribed_and_online(C2SPid) of case catch ejabberd_c2s:get_subscribed(C2SPid) of
ContactsWithCaps when is_list(ContactsWithCaps) -> Contacts when is_list(Contacts) ->
?DEBUG("found contacts with caps: ~p", [ContactsWithCaps]), Online = lists:foldl(fun({U, S, R}, Acc) ->
lists:foreach( case user_resource(U, S, R) of
fun({{U1, S1, R1}, Caps}) -> [] -> Acc;
case is_caps_notify(LServer, Node, Caps) of OR -> [{U, S, OR}|Acc]
end
end, [], Contacts),
lists:foreach(fun({U, S, R}) ->
case is_caps_notify(LServer, Node, {U, S, R}) of
true -> true ->
To = exmpp_jid:make_jid(U1, S1, R1), ejabberd_router ! {route, Sender, exmpp_jlib:make_jid(U, S, R), Stanza};
ejabberd_router ! {route, Sender, To, Stanza};
false -> false ->
ok ok
end end
end, ContactsWithCaps); end, Online);
_ -> _ ->
ok ok
end, end,
@ -2370,12 +2387,21 @@ broadcast_by_caps({LUser, LServer, LResource}, Node, _Type, Stanza) ->
_ -> _ ->
?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, Stanza]), ?DEBUG("~p@~p has no session; can't deliver ~p to contacts", [LUser, LServer, Stanza]),
ok ok
end
end; end;
broadcast_by_caps(_, _, _, _) -> broadcast_by_caps(_, _, _, _) ->
ok. ok.
is_caps_notify(Host, Node, Caps) -> user_resource(LUser, LServer, []) ->
%% If we don't know the resource, just pick first if any
case ejabberd_sm:get_user_resources(LUser, LServer) of
[R|_] -> R;
[] -> []
end;
user_resource(_, _, LResource) ->
LResource.
is_caps_notify(Host, Node, LJID) ->
Caps = mod_caps:get_caps(LJID),
case catch mod_caps:get_features(Host, Caps) of case catch mod_caps:get_features(Host, Caps) of
Features when is_list(Features) -> lists:member(Node ++ "+notify", Features); Features when is_list(Features) -> lists:member(Node ++ "+notify", Features);
_ -> false _ -> false
@ -2647,7 +2673,8 @@ set_xoption([{"pubsub#type", Value} | Opts], NewOpts) ->
set_xoption([{"pubsub#body_xslt", Value} | Opts], NewOpts) -> set_xoption([{"pubsub#body_xslt", Value} | Opts], NewOpts) ->
?SET_STRING_XOPT(body_xslt, Value); ?SET_STRING_XOPT(body_xslt, Value);
set_xoption([_ | _Opts], _NewOpts) -> set_xoption([_ | _Opts], _NewOpts) ->
{error, 'not-acceptable'}. % skip unknown field
set_xoption(Opts, NewOpts).
%%%% plugin handling %%%% plugin handling
@ -2657,7 +2684,7 @@ plugins(Host) ->
_ -> [?STDNODE] _ -> [?STDNODE]
end. end.
select_type(ServerHost, Host, Node, Type)-> select_type(ServerHost, Host, Node, Type)->
?DEBUG("SELECT_TYPE : ~p~n", [Node]), ?DEBUG("SELECT_TYPE : ~p~n", [[ServerHost, Host, Node, Type]]),
case Host of case Host of
{_User, _Server, _Resource} -> {_User, _Server, _Resource} ->
case ets:lookup(gen_mod:get_module_proc(ServerHost, pubsub_state), pep_mapping) of case ets:lookup(gen_mod:get_module_proc(ServerHost, pubsub_state), pep_mapping) of

View File

@ -382,6 +382,10 @@ unsubscribe_node(Host, Node, Sender, Subscriber, _SubId) ->
%% Requesting entity is prohibited from unsubscribing entity %% Requesting entity is prohibited from unsubscribing entity
not Authorized -> not Authorized ->
{error, 'forbidden'}; {error, 'forbidden'};
%% Was just subscriber, remove the record
State#pubsub_state.affiliation == none ->
mnesia:delete({pubsub_state, State#pubsub_state.stateid}),
{result, default};
true -> true ->
set_state(State#pubsub_state{subscription = none}), set_state(State#pubsub_state{subscription = none}),
{result, default} {result, default}

View File

@ -22,7 +22,7 @@
%%% @end %%% @end
%%% ==================================================================== %%% ====================================================================
-module(node_zoo). -module(node_flat).
-author('christophe.romain@process-one.net'). -author('christophe.romain@process-one.net').
-include_lib("exmpp/include/exmpp.hrl"). -include_lib("exmpp/include/exmpp.hrl").
@ -70,7 +70,7 @@ terminate(Host, ServerHost) ->
node_default:terminate(Host, ServerHost). node_default:terminate(Host, ServerHost).
options() -> options() ->
[{node_type, zoo}, [{node_type, flat},
{deliver_payloads, true}, {deliver_payloads, true},
{notify_config, false}, {notify_config, false},
{notify_delete, false}, {notify_delete, false},
@ -99,12 +99,7 @@ create_node_permission(Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
true; % pubsub service always allowed true; % pubsub service always allowed
_ -> _ ->
{LU, LS, LR} = LOwner, {LU, LS, LR} = LOwner,
case acl:match_rule(ServerHost, Access, exmpp_jid:make_jid(LU, LS, LR)) of acl:match_rule(ServerHost, Access, exmpp_jid:make_jid(LU, LS, LR)) =:= allow
allow ->
true;
_ ->
false
end
end, end,
{result, Allowed}. {result, Allowed}.

View File

@ -46,7 +46,9 @@
terminate/2, terminate/2,
options/0, options/0,
set_node/1, set_node/1,
get_node/3,
get_node/2, get_node/2,
get_nodes/2,
get_nodes/1, get_nodes/1,
get_subnodes/3, get_subnodes/3,
get_subnodes_tree/2, get_subnodes_tree/2,
@ -98,6 +100,9 @@ set_node(_) ->
%% @spec (Host, Node) -> pubsubNode() | {error, Reason} %% @spec (Host, Node) -> pubsubNode() | {error, Reason}
%% Host = mod_pubsub:host() %% Host = mod_pubsub:host()
%% Node = mod_pubsub:pubsubNode() %% Node = mod_pubsub:pubsubNode()
get_node(Host, Node, _From) ->
get_node(Host, Node).
get_node(Host, Node) -> get_node(Host, Node) ->
case catch mnesia:read({pubsub_node, {Host, Node}}) of case catch mnesia:read({pubsub_node, {Host, Node}}) of
[Record] when is_record(Record, pubsub_node) -> Record; [Record] when is_record(Record, pubsub_node) -> Record;
@ -107,6 +112,9 @@ get_node(Host, Node) ->
%% @spec (Key) -> [pubsubNode()] | {error, Reason} %% @spec (Key) -> [pubsubNode()] | {error, Reason}
%% Key = mod_pubsub:host() | mod_pubsub:jid() %% Key = mod_pubsub:host() | mod_pubsub:jid()
get_nodes(Key, _From) ->
get_nodes(Key).
get_nodes(Key) -> get_nodes(Key) ->
mnesia:match_object(#pubsub_node{nodeid = {Key, '_'}, _ = '_'}). mnesia:match_object(#pubsub_node{nodeid = {Key, '_'}, _ = '_'}).

View File

@ -44,7 +44,9 @@
terminate/2, terminate/2,
options/0, options/0,
set_node/1, set_node/1,
get_node/3,
get_node/2, get_node/2,
get_nodes/2,
get_nodes/1, get_nodes/1,
get_subnodes/3, get_subnodes/3,
get_subnodes_tree/2, get_subnodes_tree/2,
@ -87,6 +89,9 @@ set_node(_NodeRecord) ->
%% 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}}.
@ -94,6 +99,9 @@ get_node(Host, Node) ->
%% Host = mod_pubsub:host() | mod_pubsub:jid() %% Host = mod_pubsub:host() | mod_pubsub:jid()
%% @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. Nodes list can not be determined.</p> %% as existing. Nodes list can not be determined.</p>
get_nodes(Key, _From) ->
get_nodes(Key).
get_nodes(_Key) -> get_nodes(_Key) ->
[]. [].

View File

@ -119,13 +119,3 @@
payload = [] payload = []
}). }).
%% @type pubsubPresence() = #pubsub_presence{
%% key = {Host::host(), User::string(), Server::string()},
%% presence = list()}.
%%% <p>This is the format of the <tt>published presence</tt> table. The type of the
%%% table is: <tt>set</tt>,<tt>ram</tt>.</p>
-record(pubsub_presence, {key,
resource
}).