diff options
Diffstat (limited to 'src/mod_muc_log.erl')
-rw-r--r-- | src/mod_muc_log.erl | 180 |
1 files changed, 89 insertions, 91 deletions
diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index d94151418..1f32f6f9b 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -5,7 +5,7 @@ %%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2015 ProcessOne +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -25,6 +25,10 @@ -module(mod_muc_log). +-protocol({xep, 334, '0.2'}). + +-behaviour(ejabberd_config). + -author('badlop@process-one.net'). -behaviour(gen_server). @@ -35,21 +39,17 @@ -export([start_link/2, start/2, stop/1, transform_module_options/1, check_access_log/2, add_to_log/5]). -%% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, - handle_info/2, terminate/2, code_change/3]). + handle_info/2, terminate/2, code_change/3, + mod_opt_type/1, opt_type/1]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("jlib.hrl"). - +-include("mod_muc.hrl"). -include("mod_muc_room.hrl"). -%% Copied from mod_muc/mod_muc.erl --record(muc_online_room, {name_host = {<<>>, <<>>} :: {binary(), binary()}, - pid = self() :: pid()}). - -define(T(Text), translate:translate(Lang, Text)). -define(PROCNAME, ejabberd_mod_muc_log). -record(room, {jid, title, subject, subject_author, config}). @@ -74,23 +74,14 @@ %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - ChildSpec = - {Proc, - {?MODULE, start_link, [Host, Opts]}, - temporary, - 1000, - worker, - [?MODULE]}, + ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, + temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> @@ -121,19 +112,11 @@ transform_module_options(Opts) -> %%==================================================================== %% gen_server callbacks %%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Host, Opts]) -> OutDir = gen_mod:get_opt(outdir, Opts, fun iolist_to_binary/1, <<"www/muc">>), - DirType = gen_mod:get_opt(dirtype, Opts, + DirType = gen_mod:get_opt(dirtype, Opts, fun(subdirs) -> subdirs; (plain) -> plain end, subdirs), @@ -179,31 +162,17 @@ init([Host, Opts]) -> {ok, #logstate{host = Host, out_dir = OutDir, dir_type = DirType, dir_name = DirName, - file_format = FileFormat, file_permissions = FilePermissions, css_file = CSSFile, + file_format = FileFormat, css_file = CSSFile, + file_permissions = FilePermissions, access = AccessLog, lang = Lang, timezone = Timezone, spam_prevention = NoFollow, top_link = Top_link}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call({check_access_log, ServerHost, FromJID}, _From, State) -> Reply = acl:match_rule(ServerHost, State#logstate.access, FromJID), {reply, Reply, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast({add_to_log, Type, Data, Room, Opts}, State) -> case catch add_to_log2(Type, Data, Room, Opts, State) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); @@ -212,49 +181,30 @@ handle_cast({add_to_log, Type, Data, Room, Opts}, State) -> {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- add_to_log2(text, {Nick, Packet}, Room, Opts, State) -> - case {xml:get_subtag(Packet, <<"no-store">>), - xml:get_subtag(Packet, <<"no-permanent-store">>)} - of - {false, false} -> - case {xml:get_subtag(Packet, <<"subject">>), - xml:get_subtag(Packet, <<"body">>)} - of - {false, false} -> ok; - {false, SubEl} -> - Message = {body, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State); - {SubEl, _} -> - Message = {subject, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State) - end; - {_, _} -> ok + case has_no_permanent_store_hint(Packet) of + false -> + case {fxml:get_subtag(Packet, <<"subject">>), + fxml:get_subtag(Packet, <<"body">>)} + of + {false, false} -> ok; + {false, SubEl} -> + Message = {body, fxml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State); + {SubEl, _} -> + Message = {subject, fxml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State) + end; + true -> ok end; add_to_log2(roomconfig_change, _Occupants, Room, Opts, State) -> @@ -327,7 +277,7 @@ build_filename_string(TimeStamp, OutDir, RoomJID, {Fd, Fn, Fnrel}. get_room_name(RoomJID) -> - JID = jlib:string_to_jid(RoomJID), JID#jid.user. + JID = jid:from_string(RoomJID), JID#jid.user. %% calculate day before get_timestamp_daydiff(TimeStamp, Daydiff) -> @@ -349,12 +299,11 @@ close_previous_log(Fn, Images_dir, FileFormat) -> write_last_lines(_, _, plaintext) -> ok; write_last_lines(F, Images_dir, _FileFormat) -> -%% list_to_integer/2 was introduced in OTP R14 fw(F, <<"<div class=\"legend\">">>), fw(F, <<" <a href=\"http://www.ejabberd.im\"><img " "style=\"border:0\" src=\"~s/powered-by-ejabbe" - "rd.png\" alt=\"Powered by ejabberd\"/></a>">>, + "rd.png\" alt=\"Powered by ejabberd - robust, scalable and extensible XMPP server\"/></a>">>, [Images_dir]), fw(F, <<" <a href=\"http://www.erlang.org/\"><img " @@ -378,7 +327,7 @@ write_last_lines(F, Images_dir, _FileFormat) -> fw(F, <<"</span></div></body></html>">>). set_filemode(Fn, {FileMode, FileGroup}) -> - ok = file:change_mode(Fn, list_to_integer(integer_to_list(FileMode), 8)), + ok = file:change_mode(Fn, list_to_integer(integer_to_list(FileMode), 8)), ok = file:change_group(Fn, FileGroup). htmlize_nick(Nick1, html) -> @@ -397,7 +346,7 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, Room = get_room_info(RoomJID, Opts), Nick = htmlize(Nick1, FileFormat), Nick2 = htmlize_nick(Nick1, FileFormat), - Now = now(), + Now = p1_time_compat:timestamp(), TimeStamp = case Timezone of local -> calendar:now_to_local_time(Now); universal -> calendar:now_to_universal_time(Now) @@ -951,7 +900,7 @@ put_header_script(F) -> put_room_config(_F, _RoomConfig, _Lang, plaintext) -> ok; put_room_config(F, RoomConfig, Lang, _FileFormat) -> - {_, Now2, _} = now(), + {_, Now2, _} = p1_time_compat:timestamp(), fw(F, <<"<div class=\"rc\">">>), fw(F, <<"<div class=\"rct\" onclick=\"sh('a~p');return " @@ -968,7 +917,7 @@ put_room_occupants(_F, _RoomOccupants, _Lang, ok; put_room_occupants(F, RoomOccupants, Lang, _FileFormat) -> - {_, Now2, _} = now(), + {_, Now2, _} = p1_time_compat:timestamp(), %% htmlize %% The default behaviour is to ignore the nofollow spam prevention on links %% (NoFollow=false) @@ -1048,7 +997,7 @@ get_room_info(RoomJID, Opts) -> {value, {_, SA}} -> SA; false -> <<"">> end, - #room{jid = jlib:jid_to_string(RoomJID), title = Title, + #room{jid = jid:to_string(RoomJID), title = Title, subject = Subject, subject_author = SubjectAuthor, config = Opts}. @@ -1163,10 +1112,7 @@ roomoccupants_to_string(Users, _FileFormat) -> Users1 /= []], iolist_to_binary([<<"<div class=\"rcot\">">>, Res, <<"</div>">>]). -%% Users = [{JID, Nick, Role}] group_by_role(Users) -> -%% Role = atom() -%% Users = [{JID, Nick}] {Ms, Ps, Vs, Ns} = lists:foldl(fun ({JID, Nick, moderator}, {Mod, Par, Vis, Non}) -> @@ -1212,7 +1158,7 @@ role_users_to_string(RoleS, Users) -> <<RoleS/binary, ": ", UsersString/binary>>. get_room_occupants(RoomJIDString) -> - RoomJID = jlib:string_to_jid(RoomJIDString), + RoomJID = jid:from_string(RoomJIDString), RoomName = RoomJID#jid.luser, MucService = RoomJID#jid.lserver, StateData = get_room_state(RoomName, MucService), @@ -1238,10 +1184,11 @@ get_room_state(RoomPid) -> get_state), R. -get_proc_name(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME). +get_proc_name(Host) -> + gen_mod:get_module_proc(Host, ?PROCNAME). calc_hour_offset(TimeHere) -> - TimeZero = calendar:now_to_universal_time(now()), + TimeZero = calendar:universal_time(), TimeHereHour = calendar:datetime_to_gregorian_seconds(TimeHere) div 3600, @@ -1252,3 +1199,54 @@ calc_hour_offset(TimeHere) -> fjoin(FileList) -> list_to_binary(filename:join([binary_to_list(File) || File <- FileList])). + +has_no_permanent_store_hint(Packet) -> + fxml:get_subtag_with_xmlns(Packet, <<"no-store">>, ?NS_HINTS) + =/= false orelse + fxml:get_subtag_with_xmlns(Packet, <<"no-storage">>, ?NS_HINTS) + =/= false orelse + fxml:get_subtag_with_xmlns(Packet, <<"no-permanent-store">>, ?NS_HINTS) + =/= false orelse + fxml:get_subtag_with_xmlns(Packet, <<"no-permanent-storage">>, ?NS_HINTS) + =/= false. + +mod_opt_type(access_log) -> + fun (A) when is_atom(A) -> A end; +mod_opt_type(cssfile) -> fun iolist_to_binary/1; +mod_opt_type(dirname) -> + fun (room_jid) -> room_jid; + (room_name) -> room_name + end; +mod_opt_type(dirtype) -> + fun (subdirs) -> subdirs; + (plain) -> plain + end; +mod_opt_type(file_format) -> + fun (html) -> html; + (plaintext) -> plaintext + end; +mod_opt_type(file_permissions) -> + fun (SubOpts) -> + F = fun ({mode, Mode}, {_M, G}) -> {Mode, G}; + ({group, Group}, {M, _G}) -> {M, Group} + end, + lists:foldl(F, {644, 33}, SubOpts) + end; +mod_opt_type(outdir) -> fun iolist_to_binary/1; +mod_opt_type(spam_prevention) -> + fun (B) when is_boolean(B) -> B end; +mod_opt_type(timezone) -> + fun (local) -> local; + (universal) -> universal + end; +mod_opt_type(top_link) -> + fun ([{S1, S2}]) -> + {iolist_to_binary(S1), iolist_to_binary(S2)} + end; +mod_opt_type(_) -> + [access_log, cssfile, dirname, dirtype, file_format, + file_permissions, outdir, spam_prevention, timezone, + top_link]. + +opt_type(language) -> fun iolist_to_binary/1; +opt_type(_) -> [language]. |