From 3ae4797848e0846291b11f286a6b8747a308164f Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Mon, 19 Sep 2011 15:43:20 -0300 Subject: [PATCH] Command to moderate short term muc history (part of EJABS-1733) ejabberdctl moderate_room_history test@conference.domain.com nick removes from short term storage all messages on room test@conference.domain.com from nick "nick", so new user joining the room don't get these ones. Return the number of messages removed. --- src/ejabberd_admin.erl | 7 ++++++- src/mod_muc/mod_muc.erl | 16 +++++++++++++++- src/mod_muc/mod_muc_room.erl | 16 +++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index fd4a3d149..cd8da85d4 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -203,7 +203,12 @@ commands() -> #ejabberd_commands{name = install_fallback, tags = [mnesia], desc = "Install the database from a fallback file", module = ?MODULE, function = install_fallback_mnesia, - args = [{file, string}], result = {res, restuple}} + args = [{file, string}], result = {res, restuple}}, + #ejabberd_commands{name = moderate_room_history, tags = [server], + desc = "Clean messages from the short-term MUC storage", + module = mod_muc, function = moderate_room_history, + args = [{room, string}, {nick, string}], + result = {res, restuple}} ]. diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index 13eba7615..d8116dc3c 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -47,7 +47,8 @@ migrate/3, get_vh_rooms/1, is_broadcasted/1, - can_use_nick/3]). + can_use_nick/3, + moderate_room_history/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -99,6 +100,19 @@ stop(Host) -> gen_server:call(Proc, stop), supervisor:delete_child(ejabberd_sup, Proc). + +moderate_room_history(RoomStr, Nick) -> + Room = jlib:string_to_jid(RoomStr), + Name = Room#jid.luser, + Host = Room#jid.lserver, + case mnesia:dirty_read(muc_online_room, {Name, Host}) of + [] -> + {error, not_found}; + [R] -> + Pid = R#muc_online_room.pid, + mod_muc_room:moderate_room_history(Pid, Nick) + end. + %% This function is called by a room in three situations: %% A) The owner of the room destroyed it %% B) The only participant of a temporary room leaves it diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 87c29667b..ef20792bf 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -40,7 +40,8 @@ start/7, start/2, migrate/3, - route/4]). + route/4, + moderate_room_history/2]). %% gen_fsm callbacks -export([init/1, @@ -112,6 +113,9 @@ start_link(StateName, StateData) -> migrate(FsmRef, Node, After) -> erlang:send_after(After, FsmRef, {migrate, Node}). +moderate_room_history(FsmRef, Nick) -> + ?GEN_FSM:sync_send_all_state_event(FsmRef, {moderate_room_history, Nick}). + %%%---------------------------------------------------------------------- %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- @@ -623,6 +627,13 @@ handle_event(_Event, StateName, StateData) -> %% {stop, Reason, NewStateData} | %% {stop, Reason, Reply, NewStateData} %%---------------------------------------------------------------------- +handle_sync_event({moderate_room_history, Nick}, _From, StateName, #state{history = History} = StateData) -> + NewHistory = lqueue_filter(fun({FromNick, _TSPacket, _HaveSubject, _Timestamp, _Size}) -> + FromNick /= Nick + end, History), + Moderated = History#lqueue.len - NewHistory#lqueue.len, + {reply, {ok, integer_to_list(Moderated)}, StateName, StateData#state{history = NewHistory}}; + handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) -> Reply = get_roomdesc_reply(JID, StateData, get_roomdesc_tail(StateData, Lang)), @@ -2260,6 +2271,9 @@ lqueue_cut(Q, N) -> lqueue_to_list(#lqueue{queue = Q1}) -> queue:to_list(Q1). +lqueue_filter(F, #lqueue{queue = Q1} = LQ) -> + Q2 = queue:filter(F, Q1), + LQ#lqueue{queue = Q2, len = queue:len(Q2)}. add_message_to_history(FromNick, FromJID, Packet, StateData) -> HaveSubject = case xml:get_subtag(Packet, "subject") of