[ejabberd] Include OLPC's @online@ patch - EJAB-1391
Peter Lemenkov
peter at fedoraproject.org
Tue Jan 25 15:56:20 UTC 2011
commit 907904f9906facde52f617c8d4b7f2248a1c21c9
Author: Martin Langhoff <martin at laptop.org>
Date: Mon Jan 24 20:57:17 2011 -0500
Include OLPC's @online@ patch - EJAB-1391
ejabberd-0011-online-shared-roster-grp.patch | 322 ++++++++++++++++++++++++++
ejabberd.spec | 8 +-
2 files changed, 329 insertions(+), 1 deletions(-)
---
diff --git a/ejabberd-0011-online-shared-roster-grp.patch b/ejabberd-0011-online-shared-roster-grp.patch
new file mode 100644
index 0000000..5084f60
--- /dev/null
+++ b/ejabberd-0011-online-shared-roster-grp.patch
@@ -0,0 +1,322 @@
+From f98185d4da9ed34df7e5e3bf7f0b8e4b1b169e6c Mon Sep 17 00:00:00 2001
+From: Martin Langhoff <martin at laptop.org>
+Date: Mon, 24 Jan 2011 17:55:22 -0500
+Subject: [PATCH] New version of the @online@ patch originally by Collabora.
+
+Notes:
+
+ - fixed a typo in is_user_in_group
+ - simplified user_available and unset_presence hook handlers
+ - 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.
+---
+ src/mod_shared_roster.erl | 154 ++++++++++++++++++++++++++++++++++++++++-----
+ 1 files changed, 137 insertions(+), 17 deletions(-)
+
+diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
+index 64a8291..2f23201 100644
+--- a/src/mod_shared_roster.erl
++++ b/src/mod_shared_roster.erl
+@@ -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,
+@@ -45,7 +47,7 @@
+ delete_group/2,
+ get_group_opts/2,
+ set_group_opts/3,
+- get_group_users/2,
++ get_group_users/3,
+ get_group_explicit_users/2,
+ is_user_in_group/3,
+ add_user_to_group/3,
+@@ -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,
+@@ -132,7 +142,7 @@ get_user_roster(Items, US) ->
+ GroupName,
+ Acc2)
+ end
+- end, Acc1, get_group_users(S, Group))
++ end, Acc1, get_group_users(U, S, Group))
+ end, dict:new(), DisplayedGroups),
+
+ %% If partially subscribed users are also in shared roster, show them as
+@@ -310,7 +320,7 @@ get_subscription_lists({F, T}, User, Server) ->
+ lists:usort(
+ lists:flatmap(
+ fun(Group) ->
+- get_group_users(LServer, Group)
++ get_group_users(LUser, LServer, Group)
+ end, DisplayedGroups)),
+ SRJIDs = [{U1, S1, ""} || {U1, S1} <- SRUsers],
+ {lists:usort(SRJIDs ++ F), lists:usort(SRJIDs ++ T)}.
+@@ -329,7 +339,7 @@ get_jid_info({Subscription, Groups}, User, Server, JID) ->
+ fun(User1, Acc2) ->
+ dict:append(
+ User1, get_group_name(LServer, Group), Acc2)
+- end, Acc1, get_group_users(LServer, Group))
++ end, Acc1, get_group_users(LUser, LServer, Group))
+ end, dict:new(), DisplayedGroups),
+ case dict:find(US1, SRUsers) of
+ {ok, GroupNames} ->
+@@ -371,7 +381,7 @@ process_subscription(Direction, User, Server, JID, _Type, Acc) ->
+ lists:usort(
+ lists:flatmap(
+ fun(Group) ->
+- get_group_users(LServer, Group)
++ get_group_users(LUser, LServer, Group)
+ end, DisplayedGroups)),
+ case lists:member(US1, SRUsers) of
+ true ->
+@@ -470,21 +480,41 @@ get_group_opt(Host, Group, Opt, Default) ->
+ Default
+ end.
+
+-get_group_users(Host, Group) ->
++-record(last_activity, {us, timestamp, status}).
++-record(session, {sid, usr, us, priority, info}).
++
++get_online_users(Host) ->
++ lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]).
++
++get_group_users(User, 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).
+-
+-get_group_users(_User, Host, Group, GroupOpts) ->
++ 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) ->
+ 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 +532,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)
++ 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)).
+
+@@ -565,7 +604,7 @@ get_user_displayed_groups(US) ->
+ is_user_in_group({_U, S} = US, Group, Host) ->
+ case catch mnesia:dirty_match_object(
+ #sr_user{us=US, group_host={Group, Host}}) of
+- [] -> lists:member(US, get_group_users(S, Group));
++ [] -> lists:member(US, get_group_users(_U, S, Group));
+ _ -> true
+ end.
+
+@@ -632,7 +671,7 @@ push_members_to_user(LUser, LServer, Group, Host, Subscription) ->
+ GroupsOpts = groups_with_opts(LServer),
+ GroupOpts = proplists:get_value(Group, GroupsOpts, []),
+ GroupName = proplists:get_value(name, GroupOpts, Group),
+- Members = get_group_users(Host, Group),
++ Members = get_group_users(LUser, Host, Group),
+ lists:foreach(
+ fun({U, S}) ->
+ push_roster_item(LUser, LServer, U, S, GroupName, Subscription)
+@@ -675,7 +714,7 @@ push_user_to_group(LUser, LServer, Group, GroupName, Subscription) ->
+ lists:foreach(
+ fun({U, S}) ->
+ push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
+- end, get_group_users(LServer, Group)).
++ end, get_group_users(LUser, LServer, Group)).
+
+ %% Get list of groups to which this group is displayed
+ displayed_to_groups(GroupName, LServer) ->
+@@ -757,6 +796,72 @@ ask_to_pending(subscribe) -> out;
+ ask_to_pending(unsubscribe) -> none;
+ ask_to_pending(Ask) -> Ask.
+
++%% get a roster item for a contact from a particular user's
++%% perspective, considering both normal and shared roster items
++%% FIXME: is there a more efficient way to do this?
++get_user_roster_item(FromUS, ToUS) ->
++ {FUser, FServer} = FromUS,
++ case catch ejabberd_hooks:run_fold(roster_get, FServer, [], [ToUS]) of
++ Items when is_list(Items) ->
++ case [I || I <- Items, I#roster.jid == {FUser, FServer, []}] of
++ [Item | _ ] ->
++ Item;
++ [] ->
++ false
++ end;
++ _ ->
++ error
++ end.
++
++user_available(New) ->
++ LUser = New#jid.luser,
++ LServer = New#jid.lserver,
++ Resources = ejabberd_sm:get_user_resources(LUser, LServer),
++ ?INFO_MSG("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) ->
++ ?INFO_MSG("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),
++ ?INFO_MSG("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 user was members was displayed
++ push_user_to_displayed(LUser, LServer, OG, remove),
++ %% Push removal of members of groups that where displayed to the group which this user has left
++ push_displayed_to_user(LUser, LServer, OG, LServer, remove)
++ end, OnlineGroups);
++ _ ->
++ ok
++ end.
+
+ %%---------------------
+ %% Web Admin
+@@ -860,6 +965,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 +975,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 +1066,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 +1082,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;
+--
+1.7.3.4
+
diff --git a/ejabberd.spec b/ejabberd.spec
index b26a5b2..3966dd7 100644
--- a/ejabberd.spec
+++ b/ejabberd.spec
@@ -11,7 +11,7 @@
Name: ejabberd
Version: 2.1.6
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: A distributed, fault-tolerant Jabber/XMPP server
Group: Applications/Internet
@@ -47,6 +47,8 @@ Patch8: ejabberd-0008-Support-SASL-GSSAPI-authentication-thanks-to-Mikael-.patch
Patch9: ejabberd-0009-Added-old-modules-for-Active-Directory.patch
# Correct version in configure (DON'T FORGET TO REMOVE IN THE NEXT VERSION)
Patch10: ejabberd-0010-last-minute-fix-correct-version-in-configure.patch
+# OLPC's @online@ shared roster group patch - EJAB-1391
+Patch11: ejabberd-0011-online-shared-roster-grp.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -112,6 +114,7 @@ Documentation for ejabberd.
%patch8 -p1 -b .gssapi
%patch9 -p1 -b .ad_stuff
%patch10 -p1 -b .fix_version
+%patch11 -p1 -b .online_srg
touch -r src/configure.fix_version src/configure
@@ -338,6 +341,9 @@ rm -rf %{buildroot}
%doc %{_docdir}/%{name}-%{version}/*.txt
%changelog
+* Tue Jan 25 2011 Martin Langhoff <martin at laptop.org> 2.1.6-2
+- Apply rebased @online@ patch from OLPC - EJAB-1391
+
* Tue Dec 14 2010 Peter Lemenkov <lemenkov at gmail.com> 2.1.6-1
- Ver. 2.1.6 (Bugfix release)
More information about the scm-commits
mailing list