Hi Peter! Any chance for merging the EJAB-1391 patch? I've prepared a patch for your fedpkg checkout (attached ;-) ).
cheers, m -- [email protected] -- School Server Architect - ask interesting questions - don't get distracted with shiny stuff - working code first - http://wiki.laptop.org/go/User:Martinlanghoff
From acddd725429f27278bd1007c5ac4d9eef0f55144 Mon Sep 17 00:00:00 2001 From: Martin Langhoff <[email protected]> Date: Mon, 24 Jan 2011 20:57:17 -0500 Subject: [PATCH] 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(-) create mode 100644 ejabberd-0011-online-shared-roster-grp.patch 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 <[email protected]> +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 <[email protected]> 2.1.6-2 +- Apply rebased @online@ patch from OLPC - EJAB-1391 + * Tue Dec 14 2010 Peter Lemenkov <[email protected]> 2.1.6-1 - Ver. 2.1.6 (Bugfix release) -- 1.7.3.4
_______________________________________________ Server-devel mailing list [email protected] http://lists.laptop.org/listinfo/server-devel
