From 857d350a7119d63fc85555cc66df7ff923b91e39 Mon Sep 17 00:00:00 2001 From: Badlop Date: Mon, 19 Aug 2019 20:42:03 +0200 Subject: [PATCH] Update some modules to work with ejabberd 19.08 (#277) --- mod_cron/README.txt | 1 + mod_cron/src/mod_cron.erl | 29 ++++--- mod_log_chat/src/mod_log_chat.erl | 36 ++++----- mod_logsession/README.txt | 2 +- mod_logsession/src/mod_logsession.erl | 32 ++++---- mod_logxml/README.txt | 10 +-- mod_logxml/conf/mod_logxml.yml | 2 +- mod_logxml/src/mod_logxml.erl | 35 ++++----- mod_muc_log_http/README.txt | 1 + mod_muc_log_http/src/mod_muc_log_http.erl | 16 ++-- mod_pottymouth/src/mod_pottymouth.erl | 4 +- mod_rest/README.txt | 10 +-- mod_rest/src/mod_rest.erl | 45 ++++++----- mod_s2s_log/src/mod_s2s_log.erl | 2 +- mod_shcommands/README.txt | 1 + mod_shcommands/src/mod_shcommands.erl | 30 +++++--- mod_statsdx/README.txt | 1 + mod_statsdx/src/mod_stats2file.erl | 43 ++++++++--- mod_statsdx/src/mod_statsdx.erl | 65 +++++++++------- mod_webpresence/README.txt | 13 +--- mod_webpresence/src/mod_webpresence.erl | 94 +++++++++++------------ 21 files changed, 258 insertions(+), 214 deletions(-) diff --git a/mod_cron/README.txt b/mod_cron/README.txt index 15af70b..f24a04b 100644 --- a/mod_cron/README.txt +++ b/mod_cron/README.txt @@ -1,6 +1,7 @@ mod_cron - Execute scheduled commands + Requires: ejabberd 19.08 or higher http://www.ejabberd.im/mod_cron Author: Badlop diff --git a/mod_cron/src/mod_cron.erl b/mod_cron/src/mod_cron.erl index 777ef90..03c8be4 100644 --- a/mod_cron/src/mod_cron.erl +++ b/mod_cron/src/mod_cron.erl @@ -11,19 +11,18 @@ -behaviour(gen_mod). --export([ - cron_list/1, cron_del/1, +-export([start/2, stop/1, depends/2, mod_options/1, mod_opt_type/1]). +-export([cron_list/1, cron_del/1, run_task/3, web_menu_host/3, web_page_host/3, - start/2, apply_interval/3, - apply_interval1/3, - stop/1]). + apply_interval1/3]). -include("ejabberd_commands.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). -include("logger.hrl"). +-include("translate.hrl"). -include("xmpp.hrl"). -record(task, {taskid, timerref, host, task}). @@ -36,7 +35,7 @@ start(Host, Opts) -> ejabberd_commands:register_commands(commands()), ejabberd_hooks:add(webadmin_menu_host, Host, ?MODULE, web_menu_host, 50), ejabberd_hooks:add(webadmin_page_host, Host, ?MODULE, web_page_host, 50), - Tasks = gen_mod:get_opt(tasks, Opts, []), + Tasks = gen_mod:get_opt(tasks, Opts), catch ets:new(cron_tasks, [ordered_set, named_table, public, {keypos, 2}]), [add_task(Host, Task) || Task <- Tasks], ok. @@ -49,6 +48,14 @@ stop(Host) -> [delete_task(Task) || Task <- get_tasks(Host)], ok. +depends(_Host, _Opts) -> + []. + +mod_opt_type(tasks) -> + econf:list(econf:any()). + +mod_options(_Host) -> + [{tasks, []}]. %% --------------------- %% Task management @@ -231,7 +238,7 @@ cron_del(TaskId) -> %% --------------------- web_menu_host(Acc, _Host, Lang) -> - [{<<"cron">>, ?T(<<"Cron Tasks">>)} | Acc]. + [{<<"cron">>, translate:translate(Lang, ?T("Cron Tasks"))} | Acc]. web_page_host(_, Host, #request{path = [<<"cron">>], @@ -245,9 +252,13 @@ web_page_host(Acc, _, _) -> Acc. make_tasks_table(Tasks, Lang) -> TList = lists:map( fun(T) -> - {Time_num, Time_unit, Mod, Fun, Args} = T#task.task, + [TimeNum, TimeUnit, Mod, Fun, Args, InTimerType] = + [proplists:get_value(Key, T#task.task) + || Key <- [time, units, module, function, arguments, timer_type]], ?XE(<<"tr">>, - [?XC(<<"td">>, list_to_binary(integer_to_list(Time_num) ++" " ++ atom_to_list(Time_unit))), + [?XC(<<"td">>, list_to_binary(integer_to_list(TimeNum)++" " + ++atom_to_list(TimeUnit)++" " + ++atom_to_list(InTimerType))), ?XC(<<"td">>, list_to_binary(atom_to_list(Mod))), ?XC(<<"td">>, list_to_binary(atom_to_list(Fun))), ?XC(<<"td">>, list_to_binary(io_lib:format("~p", [Args])))]) diff --git a/mod_log_chat/src/mod_log_chat.erl b/mod_log_chat/src/mod_log_chat.erl index bab27aa..39a1689 100644 --- a/mod_log_chat/src/mod_log_chat.erl +++ b/mod_log_chat/src/mod_log_chat.erl @@ -10,13 +10,10 @@ -behaviour(gen_mod). --export([start/2, - init/1, - stop/1, - depends/2, +-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]). +-export([init/1, log_packet_send/1, - log_packet_receive/1, - mod_opt_type/1]). + log_packet_receive/1]). -ifndef(LAGER). -define(LAGER, 1). @@ -33,7 +30,7 @@ start(Host, Opts) -> ?DEBUG(" ~p ~p~n", [Host, Opts]), - case gen_mod:get_opt(host_config, Opts, []) of + case gen_mod:get_opt(host_config, Opts) of [] -> start_vh(Host, Opts); HostConfig -> @@ -51,8 +48,8 @@ start_vhs(Host, [{_VHost, _Opts}| Tail]) -> ?DEBUG("start_vhs ~p ~p~n", [Host, [{_VHost, _Opts}| Tail]]), start_vhs(Host, Tail). start_vh(Host, Opts) -> - Path = gen_mod:get_opt(path, Opts, ?DEFAULT_PATH), - Format = gen_mod:get_opt(format, Opts, ?DEFAULT_FORMAT), + Path = gen_mod:get_opt(path, Opts), + Format = gen_mod:get_opt(format, Opts), ejabberd_hooks:add(user_send_packet, Host, ?MODULE, log_packet_send, 55), ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, log_packet_receive, 55), register(gen_mod:get_module_proc(Host, ?PROCNAME), @@ -79,10 +76,6 @@ stop(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME) ! stop, ok. --spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}]. -depends(_Host, _Opts) -> - []. - log_packet_send({Packet, C2SState}) -> From = xmpp:get_from(Packet), To = xmpp:get_to(Packet), @@ -103,10 +96,10 @@ log_packet_receive({Packet, C2SState}) -> log_packet(From, To, #message{type = Type} = Packet, Host) -> case Type of - <<"groupchat">> -> %% mod_muc_log already does it + groupchat -> %% mod_muc_log already does it ?DEBUG("dropping groupchat: ~s", [fxml:element_to_binary(Packet)]), ok; - <<"error">> -> %% we don't log errors + error -> %% we don't log errors ?DEBUG("dropping error: ~s", [fxml:element_to_binary(Packet)]), ok; _ -> @@ -286,8 +279,15 @@ css() -> ".messagetext {color: black; margin: 0.2em; clear: both; display: block;}~n"++ "//-->~n~n". +depends(_Host, _Opts) -> + []. + +mod_opt_type(host_config) -> econf:list(econf:any()); mod_opt_type(path) -> fun iolist_to_binary/1; mod_opt_type(format) -> - fun (A) when is_atom(A) -> A end; -mod_opt_type(_) -> - [path, format]. + fun (A) when is_atom(A) -> A end. + +mod_options(_Host) -> + [{host_config, []}, + {path, ?DEFAULT_PATH}, + {format, ?DEFAULT_FORMAT}]. diff --git a/mod_logsession/README.txt b/mod_logsession/README.txt index 4ab2808..b96fc98 100644 --- a/mod_logsession/README.txt +++ b/mod_logsession/README.txt @@ -1,9 +1,9 @@ mod_logsession - Log session connections to file + Requirements: ejabberd 19.08 or higher Homepage: http://www.ejabberd.im/mod_logsession Author: Badlop - Requirements: ejabberd 17.01 or newer DESCRIPTION diff --git a/mod_logsession/src/mod_logsession.erl b/mod_logsession/src/mod_logsession.erl index 4bc1dad..d4b5cb5 100644 --- a/mod_logsession/src/mod_logsession.erl +++ b/mod_logsession/src/mod_logsession.erl @@ -29,14 +29,11 @@ -behaviour(gen_mod). --export([ - start/2, - stop/1, - loop/3, +-export([start/2, stop/1, depends/2, mod_options/1, mod_opt_type/1]). +-export([loop/3, reopen_log/1, failed_auth/3, - forbidden/1 - ]). + forbidden/1]). -include("xmpp.hrl"). -include("ejabberd_commands.hrl"). @@ -54,9 +51,7 @@ start(Host, Opts) -> ejabberd_commands:register_commands(commands()), Filename1 = gen_mod:get_opt( sessionlog, - Opts, - fun(S) -> S end, - "/tmp/ejabberd_logsession_@HOST@.log"), + Opts), Filename = replace_host(Host, Filename1), File = open_file(Filename), register(get_process_name(Host), spawn(?MODULE, loop, [Filename, File, Host])), @@ -70,6 +65,15 @@ stop(Host) -> exit(whereis(Proc), stop), {wait, Proc}. +depends(_Host, _Opts) -> + []. + +mod_opt_type(sessionlog) -> + econf:string(). + +mod_options(_Host) -> + [{sessionlog, "/tmp/ejabberd_logsession_@HOST@.log"}]. + %%%---------------------------------------------------------------------- %%% REQUEST HANDLERS %%%---------------------------------------------------------------------- @@ -83,8 +87,8 @@ forbidden(JID) -> failed_auth(State, true, _) -> State; -failed_auth(#{lserver := Host, ip := IPPT} = State, false, U) -> - get_process_name(Host) ! {log, {failed_auth, U, IPPT}}, +failed_auth(#{lserver := Host, ip := IPPT} = State, {false, Reason}, U) -> + get_process_name(Host) ! {log, {failed_auth, U, IPPT, Reason}}, State. commands() -> @@ -144,10 +148,10 @@ make_date(Date) -> io_lib:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w", [Y, Mo, D, H, Mi, S]). -make_message(Host, {failed_auth, Username, {IPTuple, IPPort}}) -> +make_message(Host, {failed_auth, Username, {IPTuple, IPPort}, Reason}) -> IPString = inet_parse:ntoa(IPTuple), - io_lib:format("Failed authentication for ~s@~s from ~s port ~p", - [Username, Host, IPString, IPPort]); + io_lib:format("Failed authentication for ~s@~s from ~s port ~p: ~s", + [Username, Host, IPString, IPPort, Reason]); make_message(_Host, {forbidden, JID}) -> io_lib:format("Forbidden session for ~s", [jlib:jid_to_string(JID)]). diff --git a/mod_logxml/README.txt b/mod_logxml/README.txt index 045f4c6..65adee3 100644 --- a/mod_logxml/README.txt +++ b/mod_logxml/README.txt @@ -3,7 +3,7 @@ Homepage: http://www.ejabberd.im/mod_logxml Author: Badlop - Module for ejabberd git master + Requires: ejabberd 19.08 or higher DESCRIPTION @@ -38,15 +38,15 @@ show_ip: Default value: false rotate_days: Rotate logs every X days - Put 'no' to disable this limit. + Put 0 to disable this limit. Default value: 1 rotate_megs: Rotate when the logfile size is higher than this, in megabytes. - Put 'no' to disable this limit. + Put 0 to disable this limit. Default value: 10 rotate_kpackets: Rotate every *1000 XMPP packets logged - Put 'no' to disable this limit. + Put 0 to disable this limit. Default value: 10 check_rotate_kpackets: Check rotation every *1000 packets @@ -72,7 +72,7 @@ modules: show_ip: false rotate_days: 1 rotate_megs: 100 - rotate_kpackets: no + rotate_kpackets: 0 check_rotate_kpackets: 1 diff --git a/mod_logxml/conf/mod_logxml.yml b/mod_logxml/conf/mod_logxml.yml index d60aa69..1220334 100644 --- a/mod_logxml/conf/mod_logxml.yml +++ b/mod_logxml/conf/mod_logxml.yml @@ -12,5 +12,5 @@ modules: show_ip: false rotate_days: 1 rotate_megs: 100 - rotate_kpackets: no + rotate_kpackets: 0 check_rotate_kpackets: 1 diff --git a/mod_logxml/src/mod_logxml.erl b/mod_logxml/src/mod_logxml.erl index 41446aa..f309e47 100644 --- a/mod_logxml/src/mod_logxml.erl +++ b/mod_logxml/src/mod_logxml.erl @@ -26,13 +26,16 @@ start(Host, Opts) -> Logdir = gen_mod:get_opt(logdir, Opts), - Rd = gen_mod:get_opt(rotate_days, Opts), + Rd = case gen_mod:get_opt(rotate_days, Opts) of + 0 -> no; + Rd1 -> Rd1 + end, Rf = case gen_mod:get_opt(rotate_megs, Opts) of - no -> no; + 0 -> no; Rf1 -> Rf1*1024*1024 end, Rp = case gen_mod:get_opt(rotate_kpackets, Opts) of - no -> no; + 0 -> no; Rp1 -> Rp1*1000 end, RotateO = {Rd, Rf, Rp}, @@ -111,7 +114,7 @@ filter(FilterO, E) -> FilterO, {Orientation, From, To, Packet} = E, Stanza = element(1, Packet), - Hosts_all = ejabberd_config:get_global_option(hosts, fun(A) -> A end), + Hosts_all = ejabberd_config:get_option(hosts), {Host_local, Host_remote} = case Orientation of send -> {From#jid.lserver, To#jid.lserver}; recv -> {To#jid.lserver, From#jid.lserver} @@ -267,29 +270,23 @@ calc_div(_A, _B) -> 0.5. %% This ensures that no rotation is performed mod_opt_type(stanza) -> - fun (L) when is_list(L) -> [] = L -- [iq, message, presence, other], L end; + econf:list(econf:enum([iq, message, presence, other])); mod_opt_type(direction) -> - fun (L) when is_list(L) -> [] = L -- [internal, vhosts, external], L end; + econf:list(econf:enum([internal, vhosts, external])); mod_opt_type(orientation) -> - fun (L) when is_list(L) -> [] = L -- [send, recv], L end; + econf:list(econf:enum([send, recv])); mod_opt_type(logdir) -> - fun iolist_to_binary/1; + econf:directory(); mod_opt_type(show_ip) -> - fun (A) when is_boolean(A) -> A end; + econf:bool(); mod_opt_type(rotate_days) -> - fun (I) when is_integer(I), I > 0 -> I; - (no) -> no - end; + econf:non_neg_int(); mod_opt_type(rotate_megs) -> - fun (I) when is_integer(I), I > 0 -> I; - (no) -> no - end; + econf:non_neg_int(); mod_opt_type(rotate_kpackets) -> - fun (I) when is_integer(I), I > 0 -> I; - (no) -> no - end; + econf:non_neg_int(); mod_opt_type(check_rotate_kpackets) -> - fun (I) when is_integer(I), I > 0 -> I end. + econf:non_neg_int(). mod_options(_Host) -> [{stanza, [iq, message, presence, other]}, diff --git a/mod_muc_log_http/README.txt b/mod_muc_log_http/README.txt index 4bec37f..d8b4c47 100644 --- a/mod_muc_log_http/README.txt +++ b/mod_muc_log_http/README.txt @@ -2,6 +2,7 @@ mod_muc_log_http - Serve MUC logs on the web + Requires: ejabberd 19.08 or higher Homepage: http://ejabberd.im/mod_muc_log_http Author: Badlop diff --git a/mod_muc_log_http/src/mod_muc_log_http.erl b/mod_muc_log_http/src/mod_muc_log_http.erl index 92f4f67..88c1795 100644 --- a/mod_muc_log_http/src/mod_muc_log_http.erl +++ b/mod_muc_log_http/src/mod_muc_log_http.erl @@ -10,11 +10,9 @@ -behaviour(gen_mod). --export([ - start/2, - stop/1, - process/2 - ]). +-export([start/2, stop/1, depends/2, mod_options/1]). + +-export([process/2]). -include("xmpp.hrl"). -include("ejabberd_http.hrl"). @@ -38,7 +36,7 @@ process(LocalPath, Request) -> serve(LocalPath, Request). serve(LocalPathBin, #request{host = Host} = Request) -> - DocRoot = binary_to_list(gen_mod:get_module_opt(Host, mod_muc_log, outdir, <<"www/muc">>)), + DocRoot = binary_to_list(gen_mod:get_module_opt(Host, mod_muc_log, outdir)), LocalPath = [binary_to_list(LPB) || LPB <- LocalPathBin], FileName = filename:join(filename:split(DocRoot) ++ LocalPath), case file:read_file(FileName) of @@ -230,3 +228,9 @@ start(_Host, _Opts) -> stop(_Host) -> ok. + +depends(_Host, _Opts) -> + [{mod_muc_log, hard}]. + +mod_options(_Host) -> + []. diff --git a/mod_pottymouth/src/mod_pottymouth.erl b/mod_pottymouth/src/mod_pottymouth.erl index cadd8e5..620cde5 100644 --- a/mod_pottymouth/src/mod_pottymouth.erl +++ b/mod_pottymouth/src/mod_pottymouth.erl @@ -60,9 +60,9 @@ filterMessageText2(Lang, MessageText) -> string:join(filterWords(MessageTerms), " "). start(_Host, Opts) -> - Blacklists = gen_mod:get_opt(blacklists, Opts, fun(A) -> A end, []), + Blacklists = gen_mod:get_opt(blacklists, Opts), lists:map(fun bloom_gen_server:start/1, Blacklists), - CharMaps = gen_mod:get_opt(charmaps, Opts, fun(A) -> A end, []), + CharMaps = gen_mod:get_opt(charmaps, Opts), lists:map(fun normalize_leet_gen_server:start/1, CharMaps), ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0), ok. diff --git a/mod_rest/README.txt b/mod_rest/README.txt index e3e4796..cdc56c0 100644 --- a/mod_rest/README.txt +++ b/mod_rest/README.txt @@ -1,6 +1,7 @@ mod_rest - HTTP interface to POST stanzas into ejabberd + Requires: ejabberd 19.08 or higher Author: Nolan Eakins Copyright (C) 2008 Nolan Eakins @@ -40,8 +41,6 @@ With that configuration, you can send HTTP POST requests to the URL: Configurable options: allowed_ips: IP addresses that can use the rest service. - Allowed values: 'all' or a list of Erlang strings. - Default value: all Notice that the IP address is checked after the connection is established. If you want to restrict the IP address that listens connections, and only allow a certain IP to be able to connect to the port, then the @@ -49,18 +48,13 @@ Configurable options: listening IP address in the ejabberd listeners (see the ejabberd Guide). allowed_destinations: Allowed destination Jabber ID addresses in the stanza. - Allowed values: 'all' or a list of strings. - Default value: all allowed_stanza_types: Allowed stanza types of the posted stanza. - Allowed values: 'all' or a list of strings. - Default value: all access_commands: Access restrictions to execute ejabberd commands. This option is similar to the option ejabberdctl_access_commands that is documented in the ejabberd Guide. There is more information about AccessCommands in the ejabberd Guide. - Default value: [] Complex example configuration: @@ -88,7 +82,7 @@ modules: - "presence" - "iq" access_commands: - restaccess: + - restaccess: - registered_users - connected_users diff --git a/mod_rest/src/mod_rest.erl b/mod_rest/src/mod_rest.erl index a1df437..493a70c 100644 --- a/mod_rest/src/mod_rest.erl +++ b/mod_rest/src/mod_rest.erl @@ -70,19 +70,19 @@ maybe_post_request(<<$<,_/binary>> = Data, Host, ClientIp) -> Stanza = {xmlel, _, _, _} = fxml_stream:parse_element(Data), Pkt = xmpp:decode(Stanza), allowed = check_stanza(Pkt, Host), - ?INFO_MSG("Got valid request with IP ~p:~n~p", + ?DEBUG("Got valid request with IP ~p:~n~p", [ClientIp, Pkt]), post_request(Pkt) catch error:{badmatch, _} = Error -> - ?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), + ?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), {406, [], "Error: REST request is rejected by service."}; error:{Reason, _} = Error -> - ?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), + ?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), {500, [], "Error: " ++ atom_to_list(Reason)}; Error -> - ?DEBUG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), + ?INFO_MSG("Error when processing REST request: ~nData: ~p~nError: ~p", [Data, Error]), {500, [], "Error"} end; maybe_post_request(Data, Host, _ClientIp) -> @@ -107,39 +107,38 @@ ensure_auth_is_provided(Args) -> ["--auth", "", "", "" | Args]. %% This function throws an error if the module is not started in that VHost. -try_get_option(Host, OptionName, DefaultValue) -> +try_get_option(Host, OptionName) -> case gen_mod:is_loaded(Host, ?MODULE) of true -> ok; _ -> throw({module_must_be_started_in_vhost, ?MODULE, Host}) end, - gen_mod:get_module_opt(Host, ?MODULE, OptionName, fun(I) -> I end, DefaultValue). + gen_mod:get_module_opt(Host, ?MODULE, OptionName). get_option_access(Host) -> - try_get_option(Host, access_commands, []). + try_get_option(Host, access_commands). %% This function crashes if the stanza does not satisfy configured restrictions check_stanza(Pkt, Host) -> To = xmpp:get_to(Pkt), - check_member_option(Host, jid:encode(To), allowed_destinations), - %%+++ {xmlel, StanzaType, _Attrs, _Kids} = Stanza, - %%+++ check_member_option(Host, StanzaType, allowed_stanza_types), + check_member_option(Host, To, allowed_destinations), + Name = xmpp:get_name(Pkt), + check_member_option(Host, Name, allowed_stanza_types), allowed. check_member_option(Host, ClientIp, allowed_ips) -> - true = case try_get_option(Host, allowed_ips, all) of - all -> true; + true = case try_get_option(Host, allowed_ips) of + [] -> true; AllowedValues -> ip_matches(ClientIp, AllowedValues) end; check_member_option(Host, Element, Option) -> - true = case try_get_option(Host, Option, all) of - all -> true; + true = case try_get_option(Host, Option) of + [] -> true; AllowedValues -> lists:member(Element, AllowedValues) end. ip_matches(ClientIp, AllowedValues) -> - lists:any(fun(El) -> - {ok, Net, Mask} = acl:parse_ip_netmask(El), - acl:acl_rule_matches({ip,{Net,Mask}}, #{ip => {ClientIp,port}}, host) + lists:any(fun({Net, Mask}) -> + acl:match_acl(useless_host, {ip,{Net,Mask}}, #{ip => {ClientIp,useless_port}}) end, AllowedValues). @@ -178,16 +177,16 @@ splitend([92, 34, 32 | Line], Res) -> {Line, Res}; splitend([Char | Line], Res) -> splitend(Line, [Char | Res]). mod_opt_type(allowed_ips) -> - fun (all) -> all; (A) when is_list(A) -> A end; + econf:list(econf:ip_mask()); mod_opt_type(allowed_destinations) -> - fun (all) -> all; (A) when is_list(A) -> A end; + econf:list(econf:jid()); mod_opt_type(allowed_stanza_types) -> - fun (all) -> all; (A) when is_list(A) -> A end; + econf:list(econf:enum([<<"iq">>, <<"message">>, <<"presence">>])); mod_opt_type(access_commands) -> fun (A) when is_list(A) -> A end. mod_options(_Host) -> - [{allowed_ips, all}, - {allowed_destinations, all}, - {allowed_stanza_types, all}, + [{allowed_ips, []}, + {allowed_destinations, []}, + {allowed_stanza_types, []}, {access_commands, []}]. diff --git a/mod_s2s_log/src/mod_s2s_log.erl b/mod_s2s_log/src/mod_s2s_log.erl index e81d63e..4f9037b 100644 --- a/mod_s2s_log/src/mod_s2s_log.erl +++ b/mod_s2s_log/src/mod_s2s_log.erl @@ -51,7 +51,7 @@ start(Host, Opts) -> case whereis(?PROCNAME) of undefined -> - Filename = gen_mod:get_opt(filename, Opts, ?DEFAULT_FILENAME), + Filename = gen_mod:get_opt(filename, Opts), case filelib:ensure_dir(Filename) of ok -> register(?PROCNAME, diff --git a/mod_shcommands/README.txt b/mod_shcommands/README.txt index b2acf3e..c1589d1 100644 --- a/mod_shcommands/README.txt +++ b/mod_shcommands/README.txt @@ -1,6 +1,7 @@ mod_shcommands - Execute shell commands + Requires: ejabberd 19.08 or higher Author: Badlop http://ejabberd.im/mod_shcommands diff --git a/mod_shcommands/src/mod_shcommands.erl b/mod_shcommands/src/mod_shcommands.erl index 03524cd..ad9abba 100644 --- a/mod_shcommands/src/mod_shcommands.erl +++ b/mod_shcommands/src/mod_shcommands.erl @@ -11,12 +11,13 @@ -behaviour(gen_mod). --export([web_menu_node/3, web_page_node/5, - start/2, stop/1]). +-export([start/2, stop/1, depends/2, mod_options/1]). +-export([web_menu_node/3, web_page_node/5]). -include("xmpp.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). +-include("translate.hrl"). %%------------------- %% gen_mod functions @@ -32,19 +33,25 @@ stop(_Host) -> ejabberd_hooks:delete(webadmin_page_node, ?MODULE, web_page_node, 50), ok. +depends(_Host, _Opts) -> + []. + +mod_options(_Host) -> + []. + %%------------------- %% Web Admin Menu %%------------------- web_menu_node(Acc, _Node, Lang) -> - Acc ++ [{<<"shcommands">>, ?T(<<"Shell Commands">>)}]. + Acc ++ [{<<"shcommands">>, translate:translate(Lang, ?T("Shell Commands"))}]. %%------------------- %% Web Admin Page %%------------------- web_page_node(_, Node, [<<"shcommands">>], Query, Lang) -> - Res = [?XC(<<"h1">>, <<"Shell Commands">>) | get_content(Node, Query, Lang)], + Res = [?XC(<<"h1">>, translate:translate(Lang, ?T("Shell Commands"))) | get_content(Node, Query, Lang)], {stop, Res}; web_page_node(Acc, _, _, _, _) -> Acc. @@ -53,14 +60,15 @@ web_page_node(Acc, _, _, _, _) -> Acc. %%------------------- get_content(Node, Query, Lang) -> - Instruct = ?T("Type a command in a textbox and click Execute."), + Instruct = translate:translate(Lang, ?T("Type a command in a textbox and click Execute.")), {{CommandCtl, CommandErl, CommandShell}, Res} = case catch parse_and_execute(Query, Node) of {'EXIT', _} -> {{"", "", ""}, Instruct}; Result_tuple -> Result_tuple end, TitleHTML = [ - ?XC(<<"p">>, ?T(<<"Type a command in a textbox and click Execute. Use only commands which immediately return a result.">>)), - ?XC(<<"p">>, ?T(<<"WARNING: Use this only if you know what you are doing.">>)) + ?XC(<<"p">>, translate:translate(Lang, ?T("Type a command in a textbox and click Execute."))), + ?XC(<<"p">>, translate:translate(Lang, ?T("Use only commands which immediately return a result."))), + ?XC(<<"p">>, translate:translate(Lang, ?T("WARNING: Use this only if you know what you are doing."))) ], CommandHTML = [?XAE(<<"form">>, [{<<"method">>, <<"post">>}], @@ -70,21 +78,21 @@ get_content(Node, Query, Lang) -> [?X(<<"td">>), ?XCT(<<"td">>, <<"ejabberd_ctl">>), ?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commandctl">>, list_to_binary(CommandCtl), <<"70">>), - ?INPUTT(<<"submit">>, <<"executectl">>, <<"Execute">>)]) + ?INPUTT(<<"submit">>, <<"executectl">>, translate:translate(Lang, ?T("Execute")))]) ] ), ?XE(<<"tr">>, [?X(<<"td">>), ?XCT(<<"td">>, <<"erlang shell">>), ?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commanderl">>, list_to_binary(CommandErl), <<"70">>), - ?INPUTT(<<"submit">>, <<"executeerl">>, <<"Execute">>)]) + ?INPUTT(<<"submit">>, <<"executeerl">>, translate:translate(Lang, ?T("Execute")))]) ] ), ?XE(<<"tr">>, [?X(<<"td">>), ?XCT(<<"td">>, <<"system shell">>), ?XE(<<"td">>, [?INPUTS(<<"text">>, <<"commandshe">>, list_to_binary(CommandShell), <<"70">>), - ?INPUTT(<<"submit">>, <<"executeshe">>, <<"Execute">>)]) + ?INPUTT(<<"submit">>, <<"executeshe">>, translate:translate(Lang, ?T("Execute")))]) ] ) ] @@ -93,7 +101,7 @@ get_content(Node, Query, Lang) -> ResHTML = [?XAC(<<"textarea">>, [{<<"wrap">>, <<"off">>}, {<<"style">>, <<"font-family:monospace;">>}, {<<"name">>, <<"result">>}, {<<"rows">>, <<"30">>}, {<<"cols">>, <<"80">>}], - list_to_binary(Res)) + Res) ], TitleHTML ++ CommandHTML ++ ResHTML. diff --git a/mod_statsdx/README.txt b/mod_statsdx/README.txt index 6111b56..9f5aa4e 100644 --- a/mod_statsdx/README.txt +++ b/mod_statsdx/README.txt @@ -1,6 +1,7 @@ mod_statsdx - Calculates and gathers statistics actively + Requires: ejabberd 19.08 or higher Homepage: http://www.ejabberd.im/mod_statsdx Author: Badlop diff --git a/mod_statsdx/src/mod_stats2file.erl b/mod_statsdx/src/mod_stats2file.erl index 4582930..f121ddd 100644 --- a/mod_statsdx/src/mod_stats2file.erl +++ b/mod_statsdx/src/mod_stats2file.erl @@ -11,7 +11,9 @@ -behaviour(gen_mod). --export([start/2, loop/5, stop/1]). + +-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]). +-export([loop/5]). -include("xmpp.hrl"). -include("mod_roster.hrl"). @@ -26,19 +28,17 @@ start(_Host, Opts) -> case whereis(?PROCNAME) of undefined -> - Interval = gen_mod:get_opt(interval, Opts, fun(O) -> O end, 5), + Interval = gen_mod:get_opt(interval, Opts), I = Interval*60*1000, %I = 9000, %+++ - Type = gen_mod:get_opt(type, Opts, fun(O) -> O end, html), + Type = gen_mod:get_opt(type, Opts), - Split = gen_mod:get_opt(split, Opts, fun(O) -> O end, false), + Split = gen_mod:get_opt(split, Opts), - BaseFilename = binary_to_list(gen_mod:get_opt(basefilename, Opts, fun(O) -> O end, "/tmp/ejasta")), + BaseFilename = gen_mod:get_opt(basefilename, Opts), - Hosts_all = ejabberd_config:get_global_option(hosts, fun(O) -> O end), - Hosts1 = gen_mod:get_opt(hosts, Opts, fun(O) -> O end, Hosts_all), - Hosts = [binary_to_list(H) || H <- Hosts1], + Hosts = gen_mod:get_opt(hosts, Opts), register(?PROCNAME, spawn(?MODULE, loop, [I, Hosts, BaseFilename, Type, Split])); _ -> @@ -61,6 +61,26 @@ stop(_Host) -> ?PROCNAME ! stop end. +depends(_Host, _Opts) -> + [{mod_statsdx, hard}]. + +mod_opt_type(interval) -> + econf:pos_int(); +mod_opt_type(type) -> + econf:enum([html, txt, dat]); +mod_opt_type(split) -> + econf:bool(); +mod_opt_type(basefilename) -> + econf:string(); +mod_opt_type(hosts) -> + econf:list(econf:domain()). + +mod_options(_Host) -> + [{interval, 5}, + {type, html}, + {split, false}, + {basefilename, "/tmp/ejasta"}, + {hosts, ejabberd_config:get_option(hosts)}]. %% ------------------- %% write_stat* @@ -96,13 +116,18 @@ write_statsfiles(true, I, Hs, O, T) -> Hs). write_statsfile(I, Class, Name, O, T) -> - Fn = filename:flatten([O, "-", Class, "-", Name, ".", T]), + Fn = filename:flatten([O, "-", Class, "-", to_string(Name), ".", T]), {ok, F} = file:open(Fn, [write]), fwini(F, T), write_stats(I, Class, Name, F, T), fwend(F, T), file:close(F). +to_string(B) when is_binary(B) -> + binary_to_list(B); +to_string(S) -> + S. + write_stats(I, server, _Name, F, T) -> fwh(F, "Server statistics", 1, T), fwbl1(F, T), diff --git a/mod_statsdx/src/mod_statsdx.erl b/mod_statsdx/src/mod_statsdx.erl index 26f0e98..5e5fcde 100644 --- a/mod_statsdx/src/mod_statsdx.erl +++ b/mod_statsdx/src/mod_statsdx.erl @@ -13,7 +13,8 @@ -behaviour(gen_mod). --export([start/2, loop/1, stop/1, mod_opt_type/1, get_statistic/2, +-export([start/2, stop/1, depends/2, mod_opt_type/1, mod_options/1]). +-export([loop/1, get_statistic/2, received_response/3, %% Commands getstatsdx/1, getstatsdx/2, @@ -34,22 +35,21 @@ -include("mod_roster.hrl"). -include("ejabberd_http.hrl"). -include("ejabberd_web_admin.hrl"). +-include("translate.hrl"). -define(XCTB(Name, Text), ?XCT(list_to_binary(Name), list_to_binary(Text))). -define(PROCNAME, ejabberd_mod_statsdx). %% Copied from ejabberd_s2s.erl Used in function get_s2sconnections/1 --record(s2s, {fromto, pid, key}). +-record(s2s, {fromto :: {binary(), binary()}, + pid :: pid()}). %%%================================== %%%% Module control start(Host, Opts) -> - Hooks = gen_mod:get_opt(hooks, Opts, - fun(O) when is_boolean(O) -> O; - (traffic) -> traffic - end, false), + Hooks = gen_mod:get_opt(hooks, Opts), %% Default value for the counters CD = case Hooks of true -> 0; @@ -79,8 +79,17 @@ stop(Host) -> _ -> ?PROCNAME ! {stop, Host} end. -mod_opt_type(hooks) -> fun (B) when is_boolean(B) or (B==traffic) -> B end; -mod_opt_type(_) -> [hooks]. +depends(_Host, _Opts) -> + []. + +mod_opt_type(hooks) -> + econf:enum([false, true, traffic]); +mod_opt_type(sessionlog) -> + econf:string(). + +mod_options(_Host) -> + [{hooks, false}, + {sessionlog, "/tmp/ejabberd_logsession_@HOST@.log"}]. %%%================================== %%%% Stats Server @@ -764,7 +773,7 @@ user_logout(User, Host, Resource, _Status) -> ets:update_counter(TableServer, {user_logout, server}, 1), ets:update_counter(TableHost, {user_logout, Host}, 1), - JID = jlib:make_jid(User, Host, Resource), + JID = jid:make(User, Host, Resource), case ets:lookup(TableHost, {session, JID}) of [{_, Client_id, OS_id, Lang, ConnType, _Client, _Version, _OS}] -> ets:delete(TableHost, {session, JID}), @@ -791,7 +800,7 @@ request_iqversion(User, Host, Resource) -> IQ = #iq{type = get, from = From, to = To, - id = randoms:get_string(), + id = p1_rand:get_string(), sub_els = [Query]}, HandleResponse = fun(#iq{type = result} = IQr) -> spawn(?MODULE, received_response, @@ -848,7 +857,7 @@ received_response(From, #iq{type = Type, lang = Lang1, sub_els = Elc}) -> update_counter_create(TableHost, {client_conntype, Host, Client_id, ConnType}, 1), update_counter_create(TableServer, {client_conntype, server, Client_id, ConnType}, 1), - JID = jlib:make_jid(User, Host, Resource), + JID = jid:make(User, Host, Resource), ets:insert(TableHost, {{session, JID}, Client_id, OS_id, Lang, ConnType, Client, Version, OS}). get_connection_type(User, Host, Resource) -> @@ -1004,19 +1013,19 @@ localtime_to_string({{Y, Mo, D},{H, Mi, S}}) -> %%%% Web Admin Menu web_menu_main(Acc, Lang) -> - Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}]. + Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}]. web_menu_node(Acc, _Node, Lang) -> - Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}]. + Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}]. web_menu_host(Acc, _Host, Lang) -> - Acc ++ [{<<"statsdx">>, <<(?T(<<"Statistics">>))/binary, " Dx">>}]. + Acc ++ [{<<"statsdx">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>}]. %%%================================== %%%% Web Admin Page web_page_main(_, #request{path=[<<"statsdx">>], lang = Lang} = _Request) -> - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), ?XC(<<"h3">>, <<"Accounts">>), ?XAE(<<"table">>, [], [?XE(<<"tbody">>, [ @@ -1124,7 +1133,7 @@ web_page_main(_, #request{path=[<<"statsdx">>], lang = Lang} = _Request) -> ], {stop, Res}; web_page_main(_, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) -> - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), case Topic of <<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>); <<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>); @@ -1144,7 +1153,7 @@ web_page_main(_, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang} Filter = parse_url_filter(FilterURL), Sort_query = get_sort_query(Q), FilterS = io_lib:format("~p", [Filter]), - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), ?XC(<<"h2">>, list_to_binary("Sessions with: " ++ FilterS)), ?XE(<<"table">>, [ @@ -1156,7 +1165,7 @@ web_page_main(_, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang} web_page_main(Acc, _) -> Acc. do_top_table(_Node, Lang, Topic, TopnumberBin, Host) -> - List = get_top_users(Host, jlib:binary_to_integer(TopnumberBin), Topic), + List = get_top_users(Host, binary_to_integer(TopnumberBin), Topic), %% get_top_users(Topnumber, "roster") {List2, _} = lists:mapfoldl( fun({Value, UserB, ServerB}, Counter) -> @@ -1238,7 +1247,7 @@ web_page_node(_, Node, [<<"statsdx">>], _Query, Lang) -> rpc:call(Node, mnesia, system_info, [transaction_log_writes]), Res = - [?XC(<<"h1">>, list_to_binary(io_lib:format(?T("~p statistics"), [Node]))), + [?XC(<<"h1">>, list_to_binary(io_lib:format(translate:translate(Lang, ?T("~p statistics")), [Node]))), ?XC(<<"h3">>, <<"Connections">>), ?XAE(<<"table">>, [], [?XE(<<"tbody">>, [ @@ -1335,7 +1344,7 @@ web_page_node(Acc, _, _, _, _) -> Acc. web_page_host(_, Host, #request{path = [<<"statsdx">>], lang = Lang} = _Request) -> - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), ?XC(<<"h2">>, Host), ?XC(<<"h3">>, <<"Accounts">>), ?XAE(<<"table">>, [], @@ -1466,7 +1475,7 @@ web_page_host(_, Host, ], {stop, Res}; web_page_host(_, Host, #request{path=[<<"statsdx">>, <<"top">>, Topic, Topnumber], q = _Q, lang = Lang} = _Request) -> - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), case Topic of <<"offlinemsg">> -> ?XCT(<<"h2">>, <<"Top offline message queues">>); <<"vcard">> -> ?XCT(<<"h2">>, <<"Top vCard sizes">>); @@ -1486,7 +1495,7 @@ web_page_host(_, Host, #request{path=[<<"statsdx">> | FilterURL], q = Q, lang = Lang} = _Request) -> Filter = parse_url_filter(FilterURL), Sort_query = get_sort_query(Q), - Res = [?XC(<<"h1">>, <<(?T(<<"Statistics">>))/binary, " Dx">>), + Res = [?XC(<<"h1">>, <<(translate:translate(Lang, ?T("Statistics")))/binary, " Dx">>), ?XC(<<"h2">>, list_to_binary("Sessions with: "++io_lib:format("~p", [Filter]))), ?XAE(<<"table">>, [], [?XE(<<"tbody">>, @@ -1550,7 +1559,7 @@ do_sessions_table(_Node, _Lang, Filter, {Sort_direction, Sort_column}, Host) -> Server = binary_to_list(JID#jid.lserver), UserURL = "/admin/server/" ++ Server ++ "/user/" ++ User ++ "/", ?XE(<<"tr">>, [ - ?XE(<<"td">>, [?AC(list_to_binary(UserURL), jlib:jid_to_string(JID))]), + ?XE(<<"td">>, [?AC(list_to_binary(UserURL), jid:encode(JID))]), ?XCTB("td", atom_to_list(Client_id)), ?XCTB("td", atom_to_list(OS_id)), ?XCTB("td", LangS), @@ -1584,12 +1593,12 @@ get_sessions_filtered(Filter, server) -> ejabberd_config:get_myhosts()); get_sessions_filtered(Filter, Host) -> Match = case Filter of - [{<<"client">>, Client}] -> {{session, '$1'}, jlib:binary_to_atom(Client), '$2', '$3', '$4', '$5', '$6', '$7'}; - [{<<"os">>, OS}] -> {{session, '$1'}, '$2', jlib:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'}; - [{<<"conntype">>, ConnType}] -> {{session, '$1'}, '$2', '$3', '$4', jlib:binary_to_atom(ConnType), '$5', '$6', '$7'}; + [{<<"client">>, Client}] -> {{session, '$1'}, misc:binary_to_atom(Client), '$2', '$3', '$4', '$5', '$6', '$7'}; + [{<<"os">>, OS}] -> {{session, '$1'}, '$2', misc:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'}; + [{<<"conntype">>, ConnType}] -> {{session, '$1'}, '$2', '$3', '$4', misc:binary_to_atom(ConnType), '$5', '$6', '$7'}; [{<<"languages">>, Lang}] -> {{session, '$1'}, '$2', '$3', binary_to_list(Lang), '$4', '$5', '$6', '$7'}; - [{<<"client">>, Client}, {<<"os">>, OS}] -> {{session, '$1'}, jlib:binary_to_atom(Client), jlib:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'}; - [{<<"client">>, Client}, {<<"conntype">>, ConnType}] -> {{session, '$1'}, jlib:binary_to_atom(Client), '$2', '$3', jlib:binary_to_atom(ConnType), '$5', '$6', '$7'}; + [{<<"client">>, Client}, {<<"os">>, OS}] -> {{session, '$1'}, misc:binary_to_atom(Client), misc:binary_to_atom(OS), '$3', '$4', '$5', '$6', '$7'}; + [{<<"client">>, Client}, {<<"conntype">>, ConnType}] -> {{session, '$1'}, misc:binary_to_atom(Client), '$2', '$3', misc:binary_to_atom(ConnType), '$5', '$6', '$7'}; _ -> {{session, '$1'}, '$2', '$3', '$4', '$5'} end, ets:match_object(table_name(Host), Match). diff --git a/mod_webpresence/README.txt b/mod_webpresence/README.txt index 9f9f11d..cb259a7 100644 --- a/mod_webpresence/README.txt +++ b/mod_webpresence/README.txt @@ -1,5 +1,6 @@ mod_webpresence - Presence on the Web + Requires: ejabberd 19.08 or higher Authors: Igor Goryachev, Badlop, runcom http://www.ejabberd.im/mod_webpresence @@ -69,20 +70,12 @@ pixmaps_path: Remember to put the correct path to the pixmaps directory, and make sure the user than runs ejabberd has read access to that directory. Default value: "./pixmaps" -port: - This informational option is used only when sending a message to the user. - If you set a different port in the 'listen' section, set this option too. - Default value: 5280 -path: - This informational option is used only when sending a message to the user. - If you set a different path in the 'listen' section, set this option too. - Default value: "presence" baseurl: This informational option is used only when sending a message to the user and when building the JavaScript code. It is the base part of the URL of the webpresence HTTP content. You can use the keyword @HOST@. - If the option is not specified, it takes as default value: http://host:port/path/ + If the option is not specified, it takes as default value: http://host:52080/presence/ AUTOMATIC ENABLE @@ -144,8 +137,6 @@ modules: host: "webstatus.@HOST@" access: local pixmaps_path: "/path/to/pixmaps" - port: 80 - path: "status" baseurl: "http://www.example.org/status/" diff --git a/mod_webpresence/src/mod_webpresence.erl b/mod_webpresence/src/mod_webpresence.erl index abd366a..effbcf0 100644 --- a/mod_webpresence/src/mod_webpresence.erl +++ b/mod_webpresence/src/mod_webpresence.erl @@ -33,6 +33,7 @@ -include("xmpp.hrl"). -include("logger.hrl"). +-include("translate.hrl"). -include("ejabberd_web_admin.hrl"). -include("ejabberd_http.hrl"). @@ -53,11 +54,7 @@ start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). start(Host, Opts) -> - Default_dir = case code:priv_dir(ejabberd) of - {error, _} -> ?PIXMAPS_DIR; - Path -> filename:join([Path, ?PIXMAPS_DIR]) - end, - Dir = gen_mod:get_opt(pixmaps_path, Opts, fun(D) -> D end, Default_dir), + Dir = gen_mod:get_opt(pixmaps_path, Opts), catch ets:new(pixmaps_dirs, [named_table, public]), ets:insert(pixmaps_dirs, {directory, Dir}), case gen_mod:start_child(?MODULE, Host, Opts) of @@ -75,19 +72,23 @@ stop(Host) -> gen_mod:stop_child(?MODULE, Host), ok. --spec mod_opt_type(atom()) -> fun((term()) -> term()). -mod_opt_type(host) -> fun iolist_to_binary/1; -mod_opt_type(access) -> fun acl:access_rules_validator/1; -mod_opt_type(pixmaps_path) -> fun iolist_to_binary/1; +mod_opt_type(host) -> + econf:host(); +mod_opt_type(access) -> + econf:acl(); +mod_opt_type(pixmaps_path) -> + econf:directory(); mod_opt_type(port) -> - fun(I) when is_integer(I), I>0, I<65536 -> I end; -mod_opt_type(path) -> fun iolist_to_binary/1; -mod_opt_type(baseurl) -> fun iolist_to_binary/1. + econf:pos_int(); +mod_opt_type(path) -> + econf:binary(); +mod_opt_type(baseurl) -> + econf:binary(). -spec mod_options(binary()) -> [{atom(), any()}]. mod_options(Host) -> - [{host, <<"webpresence.@HOST@">>}, - {access, none}, + [{host, <<"webpresence.", Host/binary>>}, + {access, local}, {pixmaps_path, ?PIXMAPS_DIR}, {port, 5280}, {path, <<"presence">>}, @@ -114,12 +115,9 @@ init([Host, Opts]) -> {attributes, record_info(fields, webpresence)}]), mnesia:add_table_index(webpresence, ridurl), update_table(), - MyHost = gen_mod:get_opt_host(Host, Opts, <<"webpresence.@HOST@">>), - Access = gen_mod:get_opt(access, Opts, fun(O) -> O end, local), - Port = gen_mod:get_opt(port, Opts, fun(O) -> O end, 5280), - Path = gen_mod:get_opt(path, Opts, fun(O) -> O end, <<"presence">>), - BaseURL1 = gen_mod:get_opt(baseurl, Opts, fun(O) -> O end, - iolist_to_binary(io_lib:format(<<"http://~s:~p/~s/">>, [Host, Port, Path]))), + MyHost = gen_mod:get_opt(host, Opts), + Access = gen_mod:get_opt(access, Opts), + BaseURL1 = gen_mod:get_opt(baseurl, Opts), BaseURL2 = ejabberd_regexp:greplace(BaseURL1, <<"@HOST@">>, Host), register_iq_handlers(MyHost), ejabberd_router:register_route(MyHost, Host), @@ -304,7 +302,7 @@ process_disco_items(#iq{lang = Lang} = IQ) -> name = <<"field">>, attrs = [ {<<"type">>, Type}, - {<<"label">>, ?T(Label)}, + {<<"label">>, translate:translate(Lang, ?T(Label))}, {<<"var">>, Var} ], children = Vals @@ -445,7 +443,7 @@ send_message_registered(WP, To, Host, BaseURL, Lang) -> false -> <<"">>; true -> ?BC([ <<" text\n" - " text/res/<">>, ?T(<<"Resource">>), <<">\n">> + " text/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n">> ]) end, Oimage = case WP#webpresence.icon of @@ -455,9 +453,9 @@ send_message_registered(WP, To, Host, BaseURL, Lang) -> <<" image\n" " image/example.php\n" " image/mypresence.png\n" - " image/res/<">>, ?T(<<"Resource">>), <<">\n" - " image/theme/<">>, ?T(<<"Icon Theme">>), <<">\n" - " image/theme/<">>, ?T(<<"Icon Theme">>), <<">/res/<">>, ?T(<<"Resource">>), <<">\n">> + " image/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n" + " image/theme/<">>, translate:translate(Lang, ?T("Icon Theme")), <<">\n" + " image/theme/<">>, translate:translate(Lang, ?T("Icon Theme")), <<">/res/<">>, translate:translate(Lang, ?T("Resource")), <<">\n">> ]) end, Oxml = case WP#webpresence.xml of @@ -484,24 +482,24 @@ send_message_registered(WP, To, Host, BaseURL, Lang) -> RIDT = ?BC([<<"rid/">>, RID]), {?BC([<<" ">>, RIDT, <<"\n">>]), ?BC([<<" ">>, BaseURL, RIDT, <<"/">>, Allowed_type, <<"/\n">>]), - ?BC([?T(<<"If you forget your RandomID, register again to receive this message.">>), <<"\n">>, - ?T(<<"To get a new RandomID, disable the option and register again.">>), <<"\n">>]) + ?BC([translate:translate(Lang, ?T("If you forget your RandomID, register again to receive this message.")), <<"\n">>, + translate:translate(Lang, ?T("To get a new RandomID, disable the option and register again.")), <<"\n">>]) } end, - Subject = ?BC([?T(<<"Web Presence">>), <<": ">>, ?T(<<"registered">>)]), - Body = ?BC([?T(<<"You have registered:">>), <<" ">>, JIDS, <<"\n\n">>, - ?T(<<"Use URLs like:">>), <<"\n">>, + Subject = ?BC([translate:translate(Lang, ?T("Web Presence")), <<": ">>, translate:translate(Lang, ?T("registered"))]), + Body = ?BC([translate:translate(Lang, ?T("You have registered:")), <<" ">>, JIDS, <<"\n\n">>, + translate:translate(Lang, ?T("Use URLs like:")), <<"\n">>, <<" ">>, BaseURL, <<"USERID/OUTPUT/\n">>, <<"\n">>, <<"USERID:\n">>, USERID_jid, USERID_rid, <<"\n">>, <<"OUTPUT:\n">>, Oimage, Oxml, Ojs, Otext, Oavatar, <<"\n">>, - ?T(<<"Example:">>), <<"\n">>, Example_jid, Example_rid, <<"\n">>, + translate:translate(Lang, ?T("Example:")), <<"\n">>, Example_jid, Example_rid, <<"\n">>, Text_rid]), send_headline(Host, To, Subject, Body). send_message_unregistered(To, Host, Lang) -> - Subject = ?BC([?T(<<"Web Presence">>), <<": ">>, ?T(<<"unregistered">>)]), - Body = ?BC([?T(<<"You have unregistered.">>), <<"\n\n">>]), + Subject = ?BC([translate:translate(Lang, ?T("Web Presence")), <<": ">>, translate:translate(Lang, ?T("unregistered"))]), + Body = ?BC([translate:translate(Lang, ?T("You have unregistered.")), <<"\n\n">>]), send_headline(Host, To, Subject, Body). send_headline(Host, To, Subject, Body) -> @@ -704,12 +702,12 @@ make_js(WP, Prs, Show_us, Lang, Q) -> end, ?BC([US_string, <<"var jabber_resources=[\n">>, R_string, <<"];">>, CB_string]). -long_show(<<"available">>, Lang) -> ?T(<<"available">>); -long_show(<<"chat">>, Lang) -> ?T(<<"free for chat">>); -long_show(<<"away">>, Lang) -> ?T(<<"away">>); -long_show(<<"xa">>, Lang) -> ?T(<<"extended away">>); -long_show(<<"dnd">>, Lang) -> ?T(<<"do not disturb">>); -long_show(_, Lang) -> ?T(<<"unavailable">>). +long_show(<<"available">>, Lang) -> translate:translate(Lang, ?T("available")); +long_show(<<"chat">>, Lang) -> translate:translate(Lang, ?T("free for chat")); +long_show(<<"away">>, Lang) -> translate:translate(Lang, ?T("away")); +long_show(<<"xa">>, Lang) -> translate:translate(Lang, ?T("extended away")); +long_show(<<"dnd">>, Lang) -> translate:translate(Lang, ?T("do not disturb")); +long_show(_, Lang) -> translate:translate(Lang, ?T("unavailable")). intund2string(undefined) -> intund2string(0); intund2string(Int) when is_integer(Int) -> list_to_binary(integer_to_list(Int)). @@ -887,20 +885,20 @@ process(LocalPath, Request) -> process2([], #request{lang = Lang1}) -> Lang = parse_lang(Lang1), - Title = [?XC(<<"title">>, ?T(<<"Web Presence">>))], - Desc = [?XC(<<"p">>, ?BC([ ?T(<<"To publish your presence using this system you need a Jabber account in this Jabber server.">>), <<" ">>, - ?T(<<"Login with a Jabber client, open the Service Discovery and register in Web Presence.">>), - ?T(<<"You will receive a message with further instructions.">>)]))], - Link_themes = [?AC(<<"themes">>, ?T(<<"Icon Theme">>))], - Body = [?XC(<<"h1">>, ?T(<<"Web Presence">>))] ++ Desc ++ Link_themes, + Title = [?XC(<<"title">>, translate:translate(Lang, ?T("Web Presence")))], + Desc = [?XC(<<"p">>, ?BC([ translate:translate(Lang, ?T("To publish your presence using this system you need a Jabber account in this Jabber server.")), <<" ">>, + translate:translate(Lang, ?T("Login with a Jabber client, open the Service Discovery and register in Web Presence.")), + translate:translate(Lang, ?T("You will receive a message with further instructions."))]))], + Link_themes = [?AC(<<"themes">>, translate:translate(Lang, ?T("Icon Theme")))], + Body = [?XC(<<"h1">>, translate:translate(Lang, ?T("Web Presence")))] ++ Desc ++ Link_themes, make_xhtml(Title, Body); process2([<<"themes">>], #request{lang = Lang1}) -> Lang = parse_lang(Lang1), - Title = [?XC(<<"title">>, ?BC([?T(<<"Web Presence">>), <<" - ">>, ?T("Icon Theme")]))], + Title = [?XC(<<"title">>, ?BC([translate:translate(Lang, ?T("Web Presence")), <<" - ">>, translate:translate(Lang, ?T("Icon Theme"))]))], Themes = available_themes(list), Icon_themes = themes_to_xhtml(Themes), - Body = [?XC(<<"h1">>, ?T(<<"Icon Theme">>))] ++ Icon_themes, + Body = [?XC(<<"h1">>, translate:translate(Lang, ?T("Icon Theme")))] ++ Icon_themes, make_xhtml(Title, Body); process2([<<"image">>, Theme, Show], #request{} = _Request) -> @@ -958,7 +956,7 @@ serve_web_presence(TypeURL, User, Server, Tail, #request{lang = Lang1, q = Q}) - %%%% --------------------- web_menu_host(Acc, _Host, Lang) -> - [{<<"webpresence">>, ?T(<<"Web Presence">>)} | Acc]. + [{<<"webpresence">>, translate:translate(Lang, ?T("Web Presence"))} | Acc]. web_page_host(_, _Host, #request{path = [<<"webpresence">>],