]> granicus.if.org Git - ejabberd/commitdiff
List in Service Disco non-empty rooms and provide Node for empty (EJAB-343)
authorBadlop <badlop@process-one.net>
Wed, 2 Dec 2015 00:50:30 +0000 (01:50 +0100)
committerBadlop <badlop@process-one.net>
Wed, 2 Dec 2015 00:51:39 +0000 (01:51 +0100)
src/mod_muc.erl
src/mod_muc_room.erl

index 13e074994988b7147215fc13ac85a7b3f277088f..b4038dbc8d856bdc433efd6463feaa88f32da01f 100644 (file)
@@ -232,11 +232,12 @@ remove_room_mam(LServer, Host, Name) ->
 process_iq_disco_items(Host, From, To,
                       #iq{lang = Lang} = IQ) ->
     Rsm = jlib:rsm_decode(IQ),
+    DiscoNode = xml:get_tag_attr_s(<<"node">>, IQ#iq.sub_el),
     Res = IQ#iq{type = result,
                sub_el =
                    [#xmlel{name = <<"query">>,
                            attrs = [{<<"xmlns">>, ?NS_DISCO_ITEMS}],
-                           children = iq_disco_items(Host, From, Lang, Rsm)}]},
+                           children = iq_disco_items(Host, From, Lang, DiscoNode, Rsm)}]},
     ejabberd_router:route(To, From, jlib:iq_to_xml(Res)).
 
 can_use_nick(_ServerHost, _Host, _JID, <<"">>) -> false;
@@ -752,37 +753,28 @@ iq_disco_info(ServerHost, Lang) ->
                []
        end.
 
-iq_disco_items(Host, From, Lang, none) ->
-    lists:zf(fun (#muc_online_room{name_host =
-                                      {Name, _Host},
-                                  pid = Pid}) ->
-                    case catch gen_fsm:sync_send_all_state_event(Pid,
-                                                                 {get_disco_item,
-                                                                  From, Lang},
-                                                                 100)
-                        of
-                      {item, Desc} ->
-                          flush(),
-                          {true,
-                           #xmlel{name = <<"item">>,
+iq_disco_items(Host, From, Lang, <<>>, none) ->
+    XmlEmpty = #xmlel{name = <<"item">>,
                                   attrs =
-                                      [{<<"jid">>,
-                                        jid:to_string({Name, Host,
-                                                            <<"">>})},
-                                       {<<"name">>, Desc}],
-                                  children = []}};
-                      _ -> false
-                    end
-            end, get_vh_rooms(Host));
-iq_disco_items(Host, From, Lang, Rsm) ->
+                                      [{<<"jid">>, <<"conference.localhost">>},
+                                       {<<"node">>, <<"emptyrooms">>},
+                                       {<<"name">>, translate:translate(Lang, <<"Empty Rooms">>)}],
+                                  children = []},
+    Query = {get_disco_item, only_non_empty, From, Lang},
+    [XmlEmpty | iq_disco_items_list(Host, get_vh_rooms(Host), Query)];
+iq_disco_items(Host, From, Lang, <<"emptyrooms">>, none) ->
+    iq_disco_items_list(Host, get_vh_rooms(Host), {get_disco_item, 0, From, Lang});
+iq_disco_items(Host, From, Lang, _DiscoNode, Rsm) ->
     {Rooms, RsmO} = get_vh_rooms(Host, Rsm),
     RsmOut = jlib:rsm_encode(RsmO),
+    iq_disco_items_list(Host, Rooms, {get_disco_item, all, From, Lang}) ++ RsmOut.
+
+iq_disco_items_list(Host, Rooms, Query) ->
     lists:zf(fun (#muc_online_room{name_host =
                                       {Name, _Host},
                                   pid = Pid}) ->
                     case catch gen_fsm:sync_send_all_state_event(Pid,
-                                                                 {get_disco_item,
-                                                                  From, Lang},
+                                                                 Query,
                                                                  100)
                         of
                       {item, Desc} ->
@@ -797,9 +789,7 @@ iq_disco_items(Host, From, Lang, Rsm) ->
                                   children = []}};
                       _ -> false
                     end
-            end,
-            Rooms)
-      ++ RsmOut.
+            end, Rooms).
 
 get_vh_rooms(Host, #rsm_in{max=M, direction=Direction, id=I, index=Index})->
     AllRooms = lists:sort(get_vh_rooms(Host)),
index bc712b359afa15827aba5b0e5249789beeab880c..9f31907c3da3344c73f56d74e158f792d3b344cc 100644 (file)
@@ -712,10 +712,20 @@ handle_event({set_affiliations, Affiliations},
 handle_event(_Event, StateName, StateData) ->
     {next_state, StateName, StateData}.
 
-handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) ->
-    Reply = get_roomdesc_reply(JID, StateData,
-                              get_roomdesc_tail(StateData, Lang)),
+handle_sync_event({get_disco_item, Filter, JID, Lang}, _From, StateName, StateData) ->
+    Len = ?DICT:fold(fun(_, _, Acc) -> Acc + 1 end, 0,
+                    StateData#state.users),
+    Reply = case (Filter == all) or (Filter == Len) or ((Filter /= 0) and (Len /= 0)) of
+       true ->
+           get_roomdesc_reply(JID, StateData,
+                              get_roomdesc_tail(StateData, Lang));
+       false ->
+           false
+    end,
     {reply, Reply, StateName, StateData};
+%% This clause is only for backwards compatibility
+handle_sync_event({get_disco_item, JID, Lang}, From, StateName, StateData) ->
+    handle_sync_event({get_disco_item, any, JID, Lang}, From, StateName, StateData);
 handle_sync_event(get_config, _From, StateName,
                  StateData) ->
     {reply, {ok, StateData#state.config}, StateName,