mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
Add support for '@online@' Shared Roster Group (thanks to Martin Langhoff)(EJAB-1391)
New version of the @online@ patch originally by Collabora. Notes: - the presence push is mediated via the group rather than per user - this may reduce memory footprint... _if_ ejabberd has some smart optimisation in that codepath - it assumes that any group with membership @online@ _displays_ online as well -- this is a simplification and breaks the decoupling that ejabberd has in this regard.
This commit is contained in:
parent
850218c2df
commit
677d8b1a29
@ -4055,11 +4055,13 @@ has a unique identification and the following parameters:
|
||||
\item[Name] The name of the group, which will be displayed in the roster.
|
||||
\item[Description] The description of the group. This parameter does not affect
|
||||
anything.
|
||||
\item[Members] A list of full JIDs of group members, entered one per line in
|
||||
\item[Members] A list of JIDs of group members, entered one per line in
|
||||
the Web Admin.
|
||||
To put as members all the registered users in the virtual hosts,
|
||||
you can use the special directive: @all@.
|
||||
Note that this directive is designed for a small server with just a few hundred users.
|
||||
The special member directive \term{@all@}
|
||||
represents all the registered users in the virtual host;
|
||||
which is only recommended for a small server with just a few hundred users.
|
||||
The special member directive \term{@online@}
|
||||
represents the online users in the virtual host.
|
||||
\item[Displayed groups] A list of groups that will be in the rosters of this
|
||||
group's members.
|
||||
\end{description}
|
||||
|
@ -37,6 +37,8 @@
|
||||
process_item/2,
|
||||
in_subscription/6,
|
||||
out_subscription/4,
|
||||
user_available/1,
|
||||
unset_presence/4,
|
||||
register_user/2,
|
||||
remove_user/2,
|
||||
list_groups/1,
|
||||
@ -85,6 +87,10 @@ start(Host, _Opts) ->
|
||||
?MODULE, get_jid_info, 70),
|
||||
ejabberd_hooks:add(roster_process_item, Host,
|
||||
?MODULE, process_item, 50),
|
||||
ejabberd_hooks:add(user_available_hook, Host,
|
||||
?MODULE, user_available, 50),
|
||||
ejabberd_hooks:add(unset_presence_hook, Host,
|
||||
?MODULE, unset_presence, 50),
|
||||
ejabberd_hooks:add(register_user, Host,
|
||||
?MODULE, register_user, 50),
|
||||
ejabberd_hooks:add(remove_user, Host,
|
||||
@ -109,6 +115,10 @@ stop(Host) ->
|
||||
?MODULE, get_jid_info, 70),
|
||||
ejabberd_hooks:delete(roster_process_item, Host,
|
||||
?MODULE, process_item, 50),
|
||||
ejabberd_hooks:delete(user_available_hook, Host,
|
||||
?MODULE, user_available, 50),
|
||||
ejabberd_hooks:delete(unset_presence_hook, Host,
|
||||
?MODULE, unset_presence, 50),
|
||||
ejabberd_hooks:delete(register_user, Host,
|
||||
?MODULE, register_user, 50),
|
||||
ejabberd_hooks:delete(remove_user, Host,
|
||||
@ -470,21 +480,38 @@ get_group_opt(Host, Group, Opt, Default) ->
|
||||
Default
|
||||
end.
|
||||
|
||||
get_online_users(Host) ->
|
||||
lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]).
|
||||
|
||||
get_group_users(Host, Group) ->
|
||||
case get_group_opt(Host, Group, all_users, false) of
|
||||
true ->
|
||||
ejabberd_auth:get_vh_registered_users(Host);
|
||||
false ->
|
||||
[]
|
||||
end ++ get_group_explicit_users(Host, Group).
|
||||
end ++
|
||||
case get_group_opt(Host, Group, online_users, false) of
|
||||
true ->
|
||||
get_online_users(Host);
|
||||
false ->
|
||||
[]
|
||||
end ++
|
||||
get_group_explicit_users(Host, Group).
|
||||
|
||||
get_group_users(_User, Host, Group, GroupOpts) ->
|
||||
get_group_users(Host, Group, GroupOpts) ->
|
||||
case proplists:get_value(all_users, GroupOpts, false) of
|
||||
true ->
|
||||
ejabberd_auth:get_vh_registered_users(Host);
|
||||
false ->
|
||||
[]
|
||||
end ++ get_group_explicit_users(Host, Group).
|
||||
end ++
|
||||
case proplists:get_value(online_users, GroupOpts, false) of
|
||||
true ->
|
||||
get_online_users(Host);
|
||||
false ->
|
||||
[]
|
||||
end ++
|
||||
get_group_explicit_users(Host, Group).
|
||||
|
||||
%% @spec (Host::string(), Group::string()) -> [{User::string(), Server::string()}]
|
||||
get_group_explicit_users(Host, Group) ->
|
||||
@ -502,11 +529,20 @@ get_group_explicit_users(Host, Group) ->
|
||||
get_group_name(Host, Group) ->
|
||||
get_group_opt(Host, Group, name, Group).
|
||||
|
||||
%% Get list of names of groups that have @all@ in the memberlist
|
||||
%% Get list of names of groups that have @all@/@online@/etc in the memberlist
|
||||
get_special_users_groups(Host) ->
|
||||
lists:filter(
|
||||
fun(Group) ->
|
||||
get_group_opt(Host, Group, all_users, false)
|
||||
orelse get_group_opt(Host, Group, online_users, false)
|
||||
end,
|
||||
list_groups(Host)).
|
||||
|
||||
%% Get list of names of groups that have @online@ in the memberlist
|
||||
get_special_users_groups_online(Host) ->
|
||||
lists:filter(
|
||||
fun(Group) ->
|
||||
get_group_opt(Host, Group, online_users, false)
|
||||
end,
|
||||
list_groups(Host)).
|
||||
|
||||
@ -661,7 +697,7 @@ push_user_to_members(User, Server, Subscription) ->
|
||||
lists:foreach(
|
||||
fun({U, S}) ->
|
||||
push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
|
||||
end, get_group_users(LUser, LServer, Group, GroupOpts))
|
||||
end, get_group_users(LServer, Group, GroupOpts))
|
||||
end, lists:usort(SpecialGroups++UserGroups)).
|
||||
|
||||
push_user_to_displayed(LUser, LServer, Group, Subscription) ->
|
||||
@ -673,7 +709,8 @@ push_user_to_displayed(LUser, LServer, Group, Subscription) ->
|
||||
|
||||
push_user_to_group(LUser, LServer, Group, GroupName, Subscription) ->
|
||||
lists:foreach(
|
||||
fun({U, S}) ->
|
||||
fun({U, S}) when (U == LUser) and (S == LServer) -> ok;
|
||||
({U, S}) ->
|
||||
push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
|
||||
end, get_group_users(LServer, Group)).
|
||||
|
||||
@ -757,6 +794,51 @@ ask_to_pending(subscribe) -> out;
|
||||
ask_to_pending(unsubscribe) -> none;
|
||||
ask_to_pending(Ask) -> Ask.
|
||||
|
||||
user_available(New) ->
|
||||
LUser = New#jid.luser,
|
||||
LServer = New#jid.lserver,
|
||||
Resources = ejabberd_sm:get_user_resources(LUser, LServer),
|
||||
?DEBUG("user_available for ~p @ ~p (~p resources)",
|
||||
[LUser, LServer, length(Resources)]),
|
||||
case length(Resources) of
|
||||
%% first session for this user
|
||||
1 ->
|
||||
%% This is a simplification - we ignore he 'display'
|
||||
%% property - @online@ is always reflective.
|
||||
OnlineGroups = get_special_users_groups_online(LServer),
|
||||
lists:foreach(
|
||||
fun(OG) ->
|
||||
?DEBUG("user_available: pushing ~p @ ~p grp ~p",
|
||||
[LUser, LServer, OG ]),
|
||||
push_user_to_displayed(LUser, LServer, OG, both)
|
||||
end, OnlineGroups);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
unset_presence(LUser, LServer, Resource, Status) ->
|
||||
Resources = ejabberd_sm:get_user_resources(LUser, LServer),
|
||||
?DEBUG("unset_presence for ~p @ ~p / ~p -> ~p (~p resources)",
|
||||
[LUser, LServer, Resource, Status, length(Resources)]),
|
||||
%% if user has no resources left...
|
||||
case length(Resources) of
|
||||
0 ->
|
||||
%% This is a simplification - we ignore he 'display'
|
||||
%% property - @online@ is always reflective.
|
||||
OnlineGroups = get_special_users_groups_online(LServer),
|
||||
%% for each of these groups...
|
||||
lists:foreach(
|
||||
fun(OG) ->
|
||||
%% Push removal of the old user to members of groups
|
||||
%% where the group that this uwas members was displayed
|
||||
push_user_to_displayed(LUser, LServer, OG, remove),
|
||||
%% Push removal of members of groups that where
|
||||
%% displayed to the group which thiuser has left
|
||||
push_displayed_to_user(LUser, LServer, OG, LServer,remove)
|
||||
end, OnlineGroups);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%%---------------------
|
||||
%% Web Admin
|
||||
@ -860,6 +942,7 @@ shared_roster_group(Host, Group, Query, Lang) ->
|
||||
Name = get_opt(GroupOpts, name, ""),
|
||||
Description = get_opt(GroupOpts, description, ""),
|
||||
AllUsers = get_opt(GroupOpts, all_users, false),
|
||||
OnlineUsers = get_opt(GroupOpts, online_users, false),
|
||||
%%Disabled = false,
|
||||
DisplayedGroups = get_opt(GroupOpts, displayed_groups, []),
|
||||
Members = mod_shared_roster:get_group_explicit_users(Host, Group),
|
||||
@ -869,7 +952,14 @@ shared_roster_group(Host, Group, Query, Lang) ->
|
||||
"@all@\n";
|
||||
true ->
|
||||
[]
|
||||
end ++ [[us_to_list(Member), $\n] || Member <- Members],
|
||||
end ++
|
||||
if
|
||||
OnlineUsers ->
|
||||
"@online@\n";
|
||||
true ->
|
||||
[]
|
||||
end ++
|
||||
[[us_to_list(Member), $\n] || Member <- Members],
|
||||
FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups],
|
||||
DescNL = length(element(2, regexp:split(Description, "\n"))),
|
||||
FGroup =
|
||||
@ -953,6 +1043,8 @@ shared_roster_group_parse_query(Host, Group, Query) ->
|
||||
case SJID of
|
||||
"@all@" ->
|
||||
USs;
|
||||
"@online@" ->
|
||||
USs;
|
||||
_ ->
|
||||
case jlib:string_to_jid(SJID) of
|
||||
JID when is_record(JID, jid) ->
|
||||
@ -967,10 +1059,15 @@ shared_roster_group_parse_query(Host, Group, Query) ->
|
||||
true -> [{all_users, true}];
|
||||
false -> []
|
||||
end,
|
||||
OnlineUsersOpt =
|
||||
case lists:member("@online@", SJIDs) of
|
||||
true -> [{online_users, true}];
|
||||
false -> []
|
||||
end,
|
||||
|
||||
mod_shared_roster:set_group_opts(
|
||||
Host, Group,
|
||||
NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt),
|
||||
NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt ++ OnlineUsersOpt),
|
||||
|
||||
if
|
||||
NewMembers == error -> error;
|
||||
|
Loading…
Reference in New Issue
Block a user