diff --git a/ChangeLog b/ChangeLog index f20eeaef0..6ee8c5d9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-09-05 Mickael Remond + + * src/mod_muc/mod_muc.erl: It is now possible to configure the MUC room + history feature. A new option has been added in ejabberd muc module + configuration (history_size) to define the size of the history. 0 is + used to disable the feature. + * src/mod_muc/mod_muc_room.erl: Likewise. + * doc/guide.tex: Likewise. + 2006-09-05 Alexey Shchepin * src/mod_shared_roster.erl: Bugfix diff --git a/doc/guide.html b/doc/guide.html index 554201a54..5c9558f34 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -1980,7 +1980,14 @@ Options: value is none, which means that only the room creator can administer his room). By sending a message to the service JID, administrators can send service messages that will be displayed in every - active room. + active room.
+
+
history_size
a small history of the + current discussion is send to users when they enter the room. This option make + it possible to define the number of history messages to keep and send to the + user joining the room. The value is a integer. Setting the value to 0 + disable the history feature and nothing is kept in memory. The default value + is 20. This value is global and affects all MUC rooms on the server. Examples:
  • @@ -1991,7 +1998,8 @@ In the first example everyone is allowed to use the Multi-User Chat sends a message such as “Tomorrow, the Jabber server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.” to conference.example.org, - it will be displayed in all active rooms. + it will be displayed in all active rooms. In this example the history + feature is disabled.
       {acl, admins, {user, "admin", "example.org"}}.
       ...
    @@ -2002,7 +2010,8 @@ In the first example everyone is allowed to use the Multi-User Chat
         ...
         {mod_muc, [{access, all},
                    {access_create, all},
    -               {access_admin, muc_admins}]},
    +               {access_admin, muc_admins},
    +               {history_size, 0}]},
         ...
        ]}.
     
  • In the second example the Multi-User Chat service is only accessible by @@ -2012,7 +2021,9 @@ In the first example everyone is allowed to use the Multi-User Chat admin@example.org sends a message such as “Tomorrow, the Jabber server will be moved to new hardware. This will involve service breakdowns around 23:00 UMT. We apologise for this inconvenience.” to - conference.example.org, it will be displayed in all active rooms. + conference.example.org, it will be displayed in all active rooms. No + history_size option is used, this means that the feature is enabled + and the default value of 20 history messages will be send to the users.
       {acl, paying_customers, {user, "customer1", "example.net"}}.
       {acl, paying_customers, {user, "customer2", "example.com"}}.
    diff --git a/doc/guide.tex b/doc/guide.tex
    index 0a757ca58..53a07c585 100644
    --- a/doc/guide.tex
    +++ b/doc/guide.tex
    @@ -1710,6 +1710,13 @@ Options:
       administer his room). By sending a message to the service JID,
       administrators can send service messages that will be displayed in every
       active room.
    +
    +  \titem{history\_size} \ind{options!history\_size}a small history of the
    +  current discussion is send to users when they enter the room. This option make
    +  it possible to define the number of history messages to keep and send to the
    +  user joining the room. The value is a integer. Setting the value to \term{0}
    +  disable the history feature and nothing is kept in memory. The default value
    +  is \term{20}. This value is global and affects all MUC rooms on the server.
     \end{description}
     
     Examples:
    @@ -1721,7 +1728,8 @@ Examples:
       sends a message such as ``Tomorrow, the \Jabber{} server will be moved
       to new hardware. This will involve service breakdowns around 23:00 UMT.
       We apologise for this inconvenience.'' to \jid{conference.example.org},
    -  it will be displayed in all active rooms.
    +  it will be displayed in all active rooms. In this example the history
    +  feature is disabled.
       \begin{verbatim}
       {acl, admins, {user, "admin", "example.org"}}.
       ...
    @@ -1732,7 +1740,8 @@ Examples:
         ...
         {mod_muc, [{access, all},
                    {access_create, all},
    -               {access_admin, muc_admins}]},
    +               {access_admin, muc_admins},
    +               {history_size, 0}]},
         ...
        ]}.
     \end{verbatim}
    @@ -1743,7 +1752,9 @@ Examples:
       \jid{admin@example.org} sends a message such as ``Tomorrow, the \Jabber{}
       server will be moved to new hardware. This will involve service breakdowns
       around 23:00 UMT. We apologise for this inconvenience.'' to
    -  \jid{conference.example.org}, it will be displayed in all active rooms.
    +  \jid{conference.example.org}, it will be displayed in all active rooms. No
    +  \term{history\_size} option is used, this means that the feature is enabled
    +  and the default value of 20 history messages will be send to the users.
       \begin{verbatim}
       {acl, paying_customers, {user, "customer1", "example.net"}}.
       {acl, paying_customers, {user, "customer2", "example.com"}}.
    diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl
    index 6e40d0bdf..196181f3f 100644
    --- a/src/mod_muc/mod_muc.erl
    +++ b/src/mod_muc/mod_muc.erl
    @@ -36,7 +36,7 @@
     -record(muc_online_room, {name_host, pid}).
     -record(muc_registered, {us_host, nick}).
     
    --record(state, {host, server_host, access}).
    +-record(state, {host, server_host, access, history_size}).
     
     -define(PROCNAME, ejabberd_mod_muc).
     
    @@ -148,14 +148,17 @@ init([Host, Opts]) ->
         Access = gen_mod:get_opt(access, Opts, all),
         AccessCreate = gen_mod:get_opt(access_create, Opts, all),
         AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
    +    HistorySize = gen_mod:get_opt(history_size, Opts, 20),
         catch ets:new(muc_online_room, [named_table,
     				    public,
     				    {keypos, #muc_online_room.name_host}]),
         ejabberd_router:register_route(MyHost),
    -    load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin}),
    +    load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin},
    +			 HistorySize),
         {ok, #state{host = MyHost,
     		server_host = Host,
    -		access = {Access, AccessCreate, AccessAdmin}}}.
    +		access = {Access, AccessCreate, AccessAdmin},
    +		history_size = HistorySize}}.
     
     %%--------------------------------------------------------------------
     %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
    @@ -187,8 +190,9 @@ handle_cast(_Msg, State) ->
     handle_info({route, From, To, Packet},
     	    #state{host = Host,
     		   server_host = ServerHost,
    -		   access = Access} = State) ->
    -    case catch do_route(Host, ServerHost, Access, From, To, Packet) of
    +		   access = Access,
    +		   history_size = HistorySize} = State) ->
    +    case catch do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) of
     	{'EXIT', Reason} ->
     	    ?ERROR_MSG("~p", [Reason]);
     	_ ->
    @@ -239,11 +243,11 @@ stop_supervisor(Host) ->
         supervisor:terminate_child(ejabberd_sup, Proc),
         supervisor:delete_child(ejabberd_sup, Proc).
     
    -do_route(Host, ServerHost, Access, From, To, Packet) ->
    +do_route(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
         {AccessRoute, _AccessCreate, _AccessAdmin} = Access,
         case acl:match_rule(ServerHost, AccessRoute, From) of
     	allow ->
    -	    do_route1(Host, ServerHost, Access, From, To, Packet);
    +	    do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet);
     	_ ->
     	    {xmlelement, _Name, Attrs, _Els} = Packet,
     	    Lang = xml:get_attr_s("xml:lang", Attrs),
    @@ -254,7 +258,7 @@ do_route(Host, ServerHost, Access, From, To, Packet) ->
         end.
     
     
    -do_route1(Host, ServerHost, Access, From, To, Packet) ->
    +do_route1(Host, ServerHost, Access, HistorySize, From, To, Packet) ->
         {_AccessRoute, AccessCreate, AccessAdmin} = Access,
         {Room, _, Nick} = jlib:jid_tolower(To),
         {xmlelement, Name, Attrs, _Els} = Packet,
    @@ -379,7 +383,8 @@ do_route1(Host, ServerHost, Access, From, To, Packet) ->
     				    ?DEBUG("MUC: open new room '~s'~n", [Room]),
     				    {ok, Pid} = mod_muc_room:start(
     						  Host, ServerHost, Access,
    -						  Room, From, Nick),
    +						  Room, HistorySize, From,
    +						  Nick),
     				    ets:insert(
     				      muc_online_room,
     				      #muc_online_room{name_host = {Room, Host},
    @@ -411,7 +416,7 @@ do_route1(Host, ServerHost, Access, From, To, Packet) ->
     
     
     
    -load_permanent_rooms(Host, ServerHost, Access) ->
    +load_permanent_rooms(Host, ServerHost, Access, HistorySize) ->
         case catch mnesia:dirty_select(
     		 muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
     			     [],
    @@ -427,6 +432,7 @@ load_permanent_rooms(Host, ServerHost, Access) ->
     						ServerHost,
     						Access,
     						Room,
    +						HistorySize,
     						R#muc_room.opts),
     				  ets:insert(
     				    muc_online_room,
    diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl
    index 3ae1934ac..44eceb476 100644
    --- a/src/mod_muc/mod_muc_room.erl
    +++ b/src/mod_muc/mod_muc_room.erl
    @@ -14,10 +14,10 @@
     
     
     %% External exports
    --export([start_link/6,
    -	 start_link/5,
    +-export([start_link/7,
    +	 start_link/6,
    +	 start/7,
     	 start/6,
    -	 start/5,
     	 route/4]).
     
     %% gen_fsm callbacks
    @@ -85,22 +85,22 @@
     %%%----------------------------------------------------------------------
     %%% API
     %%%----------------------------------------------------------------------
    -start(Host, ServerHost, Access, Room, Creator, Nick) ->
    +start(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
         Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
         supervisor:start_child(
    -      Supervisor, [Host, ServerHost, Access, Room, Creator, Nick]).
    +      Supervisor, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick]).
     
    -start(Host, ServerHost, Access, Room, Opts) ->
    +start(Host, ServerHost, Access, Room, HistorySize, Opts) ->
         Supervisor = gen_mod:get_module_proc(ServerHost, ejabberd_mod_muc_sup),
         supervisor:start_child(
    -      Supervisor, [Host, ServerHost, Access, Room, Opts]).
    +      Supervisor, [Host, ServerHost, Access, Room, HistorySize, Opts]).
     
    -start_link(Host, ServerHost, Access, Room, Creator, Nick) ->
    -    gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Creator, Nick],
    +start_link(Host, ServerHost, Access, Room, HistorySize, Creator, Nick) ->
    +    gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Creator, Nick],
     		       ?FSMOPTS).
     
    -start_link(Host, ServerHost, Access, Room, Opts) ->
    -    gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, Opts],
    +start_link(Host, ServerHost, Access, Room, HistorySize, Opts) ->
    +    gen_fsm:start_link(?MODULE, [Host, ServerHost, Access, Room, HistorySize, Opts],
     		       ?FSMOPTS).
     
     %%%----------------------------------------------------------------------
    @@ -114,20 +114,22 @@ start_link(Host, ServerHost, Access, Room, Opts) ->
     %%          ignore                              |
     %%          {stop, StopReason}                   
     %%----------------------------------------------------------------------
    -init([Host, ServerHost, Access, Room, Creator, _Nick]) ->
    +init([Host, ServerHost, Access, Room, HistorySize, Creator, _Nick]) ->
         State = set_affiliation(Creator, owner,
     			    #state{host = Host,
     				   server_host = ServerHost,
     				   access = Access,
     				   room = Room,
    +				   history = lqueue_new(HistorySize),
     				   jid = jlib:make_jid(Room, Host, ""),
     				   just_created = true}),
         {ok, normal_state, State};
    -init([Host, ServerHost, Access, Room, Opts]) ->
    +init([Host, ServerHost, Access, Room, HistorySize, Opts]) ->
         State = set_opts(Opts, #state{host = Host,
     				  server_host = ServerHost,
     				  access = Access,
     				  room = Room,
    +				  history = lqueue_new(HistorySize),
     				  jid = jlib:make_jid(Room, Host, "")}),
         {ok, normal_state, State}.
     
    @@ -1372,7 +1374,11 @@ lqueue_new(Max) ->
     	    len = 0,
     	    max = Max}.
     
    -lqueue_in(Item, #lqueue{queue = Q1, len = Len, max = Max}) ->
    +%% If the message queue limit is set to 0, do not store messages.
    +lqueue_in(Item, LQ = #lqueue{max = 0}) ->
    +    LQ;
    +%% Otherwise, rotate messages in the queue store.
    +lqueue_in(Item, LQ = #lqueue{queue = Q1, len = Len, max = Max}) ->
         Q2 = queue:in(Item, Q1),
         if
     	Len >= Max ->