Update some modules to work with ejabberd 19.08 (#277)

This commit is contained in:
Badlop 2019-08-19 20:42:03 +02:00
parent 4753268b5f
commit 857d350a71
21 changed files with 258 additions and 214 deletions

View File

@ -1,6 +1,7 @@
mod_cron - Execute scheduled commands
Requires: ejabberd 19.08 or higher
http://www.ejabberd.im/mod_cron
Author: Badlop

View File

@ -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])))])

View File

@ -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</style>~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}].

View File

@ -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

View File

@ -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)]).

View File

@ -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

View File

@ -12,5 +12,5 @@ modules:
show_ip: false
rotate_days: 1
rotate_megs: 100
rotate_kpackets: no
rotate_kpackets: 0
check_rotate_kpackets: 1

View File

@ -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]},

View File

@ -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

View File

@ -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) ->
[].

View File

@ -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.

View File

@ -1,6 +1,7 @@
mod_rest - HTTP interface to POST stanzas into ejabberd
Requires: ejabberd 19.08 or higher
Author: Nolan Eakins <sneakin@semanticgap.com>
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

View File

@ -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, []}].

View File

@ -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,

View File

@ -1,6 +1,7 @@
mod_shcommands - Execute shell commands
Requires: ejabberd 19.08 or higher
Author: Badlop
http://ejabberd.im/mod_shcommands

View File

@ -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.

View File

@ -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

View File

@ -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),

View File

@ -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).

View File

@ -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/"

View File

@ -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">>],