* src/mod_irc/mod_irc_connection.erl: Added /msg and /ctcp

commands, improved handling of channel topic and kick, mirc colors
now filtered, other minor improvements (thanks to Oleg
V. Motienko)

* src/mod_configure.erl: Improved strings (thanks to Sander
Devrieze)
* src/mod_vcard.erl: Likewise
* src/mod_vcard_ldap.erl: Likewise
* src/mod_vcard_odbc.erl: Likewise
* src/web/ejabberd_web_admin.erl: Likewise

SVN Revision: 508
This commit is contained in:
Alexey Shchepin 2006-02-18 19:56:16 +00:00
parent 0234b83be4
commit 44fdd72041
7 changed files with 289 additions and 174 deletions

View File

@ -1,3 +1,17 @@
2006-02-18 Alexey Shchepin <alexey@sevcom.net>
* src/mod_irc/mod_irc_connection.erl: Added /msg and /ctcp
commands, improved handling of channel topic and kick, mirc colors
now filtered, other minor improvements (thanks to Oleg
V. Motienko)
* src/mod_configure.erl: Improved strings (thanks to Sander
Devrieze)
* src/mod_vcard.erl: Likewise
* src/mod_vcard_ldap.erl: Likewise
* src/mod_vcard_odbc.erl: Likewise
* src/web/ejabberd_web_admin.erl: Likewise
2006-02-15 Alexey Shchepin <alexey@sevcom.net>
* src/mod_service_log.erl: Bugfix (thanks to Badlop)

View File

@ -385,7 +385,7 @@ get_local_items(_Host, [], Server, Lang) ->
[?NODE("Configuration", "config"),
?NODE("Online Users", "online users"),
?NODE("All Users", "all users"),
?NODE("Outgoing S2S connections", "outgoing s2s"),
?NODE("Outgoing s2s Connections", "outgoing s2s"),
?NODE("Running Nodes", "running nodes"),
?NODE("Stopped Nodes", "stopped nodes")
]};
@ -446,10 +446,10 @@ get_local_items(_Host, ["stopped nodes"], _Server, Lang) ->
get_local_items(_Host, ["running nodes", ENode], Server, Lang) ->
{result,
[?NODE("DB", "running nodes/" ++ ENode ++ "/DB"),
[?NODE("Database", "running nodes/" ++ ENode ++ "/DB"),
?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"),
?NODE("Backup Management", "running nodes/" ++ ENode ++ "/backup"),
?NODE("Import users from jabberd1.4 spool files",
?NODE("Import Users From jabberd 1.4 Spool Files",
"running nodes/" ++ ENode ++ "/import")
]};
@ -744,7 +744,7 @@ get_form(_Host, ["running nodes", ENode, "DB"], Lang) ->
[{xmlelement, "title", [],
[{xmlcdata,
translate:translate(
Lang, "DB Tables Configuration at ") ++
Lang, "Database Tables Configuration at ") ++
ENode}]},
{xmlelement, "instructions", [],
[{xmlcdata,

View File

@ -115,7 +115,7 @@ open_socket(init, StateData) ->
wait_for_registration(closed, StateData) ->
{stop, normal, StateData}.
stream_established({xmlstreamend, Name}, StateData) ->
stream_established({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
stream_established(timeout, StateData) ->
@ -145,7 +145,7 @@ stream_established(closed, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_event(Event, StateName, StateData) ->
handle_event(_Event, StateName, StateData) ->
{next_state, StateName, StateData}.
%%----------------------------------------------------------------------
@ -157,11 +157,11 @@ handle_event(Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData}
%%----------------------------------------------------------------------
handle_sync_event(Event, From, StateName, StateData) ->
handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok,
{reply, Reply, StateName, StateData}.
code_change(OldVsn, StateName, StateData, Extra) ->
code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}.
-define(SEND(S),
@ -243,15 +243,36 @@ handle_info({route_chan, Channel, Resource,
case Body of
"/quote " ++ Rest ->
?SEND(Rest ++ "\r\n");
"/msg " ++ Rest ->
?SEND("PRIVMSG " ++ Rest ++ "\r\n");
"/me " ++ Rest ->
Strings = string:tokens(Rest, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
io_lib:format(
"PRIVMSG #~s :\001ACTION ~s\001\r\n",
[Channel, S])
end, Strings)),
?SEND(Res);
"/ctcp " ++ Rest ->
Words = string:tokens(Rest, " "),
case Words of
[CtcpDest | _] ->
CtcpCmd =
toupper(
string:substr(
Rest,
string:str(Rest, " ") + 1)),
Res = io_lib:format(
"PRIVMSG ~s :\001~s\001\r\n",
[CtcpDest, CtcpCmd]),
?SEND(Res);
_ ->
ok
end;
_ ->
Body1 =
case Body of
[$/, $m, $e, $ | Rest] ->
"\001ACTION " ++ Rest ++ "\001";
_ ->
Body
end,
Strings = string:tokens(Body1, "\n"),
Strings = string:tokens(Body, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
@ -271,19 +292,40 @@ handle_info({route_chan, Channel, Resource,
end, Strings)),
?SEND(Res)
end;
"chat" ->
Type when Type == "chat"; Type == ""; Type == "normal" ->
Body = xml:get_path_s(El, [{elem, "body"}, cdata]),
case Body of
"/quote " ++ Rest ->
?SEND(Rest ++ "\r\n");
"/msg " ++ Rest ->
?SEND("PRIVMSG " ++ Rest ++ "\r\n");
"/me " ++ Rest ->
Strings = string:tokens(Rest, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
io_lib:format(
"PRIVMSG ~s :\001ACTION ~s\001\r\n",
[Resource, S])
end, Strings)),
?SEND(Res);
"/ctcp " ++ Rest ->
Words = string:tokens(Rest, " "),
case Words of
[CtcpDest | _ ] ->
CtcpCmd =
toupper(
string:substr(
Rest, string:str(Rest, " ") + 1)),
Res = io_lib:format(
"PRIVMSG ~s :~s\r\n",
[CtcpDest, "\001" ++ CtcpCmd ++ "\001"]),
?SEND(Res);
_ ->
ok
end;
_ ->
Body1 = case Body of
[$/, $m, $e, $ | Rest] ->
"\001ACTION " ++ Rest ++ "\001";
_ ->
Body
end,
Strings = string:tokens(Body1, "\n"),
Strings = string:tokens(Body, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
@ -358,14 +400,32 @@ handle_info({route_nick, Nick,
case Body of
"/quote " ++ Rest ->
?SEND(Rest ++ "\r\n");
"/msg " ++ Rest ->
?SEND("PRIVMSG " ++ Rest ++ "\r\n");
"/me " ++ Rest ->
Strings = string:tokens(Rest, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
io_lib:format(
"PRIVMSG ~s :\001ACTION ~s\001\r\n",
[Nick, S])
end, Strings)),
?SEND(Res);
"/ctcp " ++ Rest ->
Words = string:tokens(Rest, " "),
case Words of
[CtcpDest | _ ] ->
CtcpCmd = toupper(string:substr(Rest, string:str(Rest, " ")+1 )),
Res = io_lib:format(
"PRIVMSG ~s :~s\r\n",
[CtcpDest, "\001" ++ CtcpCmd ++ "\001"]),
?SEND(Res);
_ ->
ok
end;
_ ->
Body1 = case Body of
[$/, $m, $e, $ | Rest] ->
"\001ACTION " ++ Rest ++ "\001";
_ ->
Body
end,
Strings = string:tokens(Body1, "\n"),
Strings = string:tokens(Body, "\n"),
Res = lists:concat(
lists:map(
fun(S) ->
@ -403,6 +463,9 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
[_, "332", Nick, [$# | Chan] | _] ->
process_channel_topic(StateData, Chan, String),
StateData;
[_, "333", Nick, [$# | Chan] | _] ->
process_channel_topic_who(StateData, Chan, String),
StateData;
[_, "318", _, Nick | _] ->
process_endofwhois(StateData, String, Nick),
StateData;
@ -451,7 +514,7 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
"member", "participant"),
StateData;
[From, "KICK", [$# | Chan], Nick | _] ->
process_kick(StateData, Chan, From, Nick),
process_kick(StateData, Chan, From, Nick, String),
StateData;
[From, "NICK", Nick | _] ->
process_nick(StateData, From, Nick);
@ -626,16 +689,43 @@ process_channel_list_user(StateData, Chan, User) ->
process_channel_topic(StateData, Chan, String) ->
FromUser = "someone",
{ok, Msg, _} = regexp:sub(String, ".*332[^:]*:", ""),
Msg1 = filter_message(Msg),
ejabberd_router:route(
jlib:make_jid(
lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, FromUser),
StateData#state.host, ""),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "subject", [], [{xmlcdata, Msg1}]}]}).
[{xmlelement, "subject", [], [{xmlcdata, Msg1}]},
{xmlelement, "body", [], [{xmlcdata, "Topic for #" ++ Chan ++ ": " ++ Msg1}]}
]}).
process_channel_topic_who(StateData, Chan, String) ->
Words = string:tokens(String, " "),
Msg1 = case Words of
[_, "333", _, _Chan, Whoset , Timeset] ->
case string:to_integer(Timeset) of
{Unixtimeset, Rest} ->
"Topic for #" ++ Chan ++ " set by " ++ Whoset ++
" at " ++ unixtime2string(Unixtimeset);
_->
"Topic for #" ++ Chan ++ " set by " ++ Whoset
end;
[_, "333", _, _Chan, Whoset | _] ->
"Topic for #" ++ Chan ++ " set by " ++ Whoset;
_ ->
String
end,
Msg2 = filter_message(Msg1),
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, ""),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}).
process_endofwhois(StateData, String, Nick) ->
@ -708,7 +798,7 @@ process_channotice(StateData, Chan, From, String) ->
[1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
"/me " ++ Rest;
_ ->
Msg
"/me NOTICE: " ++ Msg
end,
Msg2 = filter_message(Msg1),
ejabberd_router:route(
@ -716,7 +806,7 @@ process_channotice(StateData, Chan, From, String) ->
StateData#state.host, FromUser),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [], [{xmlcdata, "NOTICE: " ++ Msg2}]}]}).
[{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}).
@ -746,7 +836,7 @@ process_notice(StateData, Nick, From, String) ->
[1, $A, $C, $T, $I, $O, $N, $ | Rest] ->
"/me " ++ Rest;
_ ->
Msg
"/me NOTICE: " ++ Msg
end,
Msg2 = filter_message(Msg1),
ejabberd_router:route(
@ -754,7 +844,7 @@ process_notice(StateData, Nick, From, String) ->
StateData#state.host, ""),
StateData#state.user,
{xmlelement, "message", [{"type", "chat"}],
[{xmlelement, "body", [], [{xmlcdata, "NOTICE: " ++ Msg2}]}]}).
[{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}).
process_version(StateData, Nick, From) ->
@ -776,7 +866,7 @@ process_userinfo(StateData, Nick, From) ->
send_text(
StateData,
io_lib:format("NOTICE ~s :\001USERINFO "
"This user uses xmpp:~s"
"xmpp:~s"
"\001\r\n",
[FromUser,
jlib:jid_to_string(StateData#state.user)])).
@ -798,17 +888,8 @@ process_topic(StateData, Chan, From, String) ->
process_part(StateData, Chan, From, String) ->
[FromUser | FromIdent] = string:tokens(From, "!"),
{ok, Msg, _} = regexp:sub(String, ".*PART[^:]*", ""),
{ok, Msg, _} = regexp:sub(String, ".*PART[^:]*:", ""),
Msg1 = filter_message(Msg),
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, FromUser),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [],
[{xmlcdata, "/me has part: " ++
Msg1 ++ "(" ++ FromIdent ++ ")" }]}]}),
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, FromUser),
@ -820,7 +901,7 @@ process_part(StateData, Chan, From, String) ->
{"role", "none"}],
[]}]},
{xmlelement, "status", [],
[{xmlcdata, Msg1 ++ "(" ++ FromIdent ++ ")"}]}]
[{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]}]
}),
case catch dict:update(Chan,
fun(Ps) ->
@ -843,16 +924,6 @@ process_quit(StateData, From, String) ->
fun(Chan, Ps) ->
case ?SETS:is_member(FromUser, Ps) of
true ->
ejabberd_router:route(
jlib:make_jid(
lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, FromUser),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [],
[{xmlcdata, "/me has quit: " ++
Msg1 ++ "(" ++ FromIdent ++ ")" }]}]}),
ejabberd_router:route(
jlib:make_jid(
lists:concat([Chan, "%", StateData#state.server]),
@ -865,7 +936,7 @@ process_quit(StateData, From, String) ->
{"role", "none"}],
[]}]},
{xmlelement, "status", [],
[{xmlcdata, Msg1 ++ "(" ++ FromIdent ++ ")"}]}
[{xmlcdata, Msg1 ++ " (" ++ FromIdent ++ ")"}]}
]}),
remove_element(FromUser, Ps);
_ ->
@ -890,16 +961,6 @@ process_join(StateData, Channel, From, String) ->
[]}]},
{xmlelement, "status", [],
[{xmlcdata, FromIdent}]}]}),
{ok, Msg, _} = regexp:sub(String, ".*JOIN[^:]*:", ""),
Msg1 = filter_message(Msg),
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, FromUser),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [],
[{xmlcdata, "/me has joined " ++
Msg1 ++ "(" ++ FromIdent ++ ")" }]}]}),
case catch dict:update(Chan,
fun(Ps) ->
@ -926,8 +987,15 @@ process_mode_o(StateData, Chan, From, Nick, Affiliation, Role) ->
{"role", Role}],
[]}]}]}).
process_kick(StateData, Chan, From, Nick) ->
%Msg = lists:last(string:tokens(String, ":")),
process_kick(StateData, Chan, From, Nick, String) ->
Msg = lists:last(string:tokens(String, ":")),
Msg2 = Nick ++ " kicked by " ++ From ++ " (" ++ filter_message(Msg) ++ ")",
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, ""),
StateData#state.user,
{xmlelement, "message", [{"type", "groupchat"}],
[{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}),
ejabberd_router:route(
jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, Nick),
@ -1086,4 +1154,36 @@ filter_message(Msg) ->
false;
true -> true
end
end, Msg).
end, filter_mirc_colors(Msg)).
filter_mirc_colors(Msg) ->
case regexp:gsub(Msg, "(\\003[0-9]+)(,[0-9]+)?", "") of
{ok, Msg2, _} ->
Msg2;
_ ->
Msg
end.
unixtime2string(Unixtime) ->
Secs = Unixtime + calendar:datetime_to_gregorian_seconds(
{{1970, 1, 1}, {0,0,0}}),
case calendar:universal_time_to_local_time(
calendar:gregorian_seconds_to_datetime(Secs)) of
{{Year, Month, Day}, {Hour, Minute, Second}} ->
lists:flatten(
io_lib:format("~4..0w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
[Year, Month, Day, Hour, Minute, Second]));
_->
"0000-00-00 00:00:00"
end.
toupper([C | Cs]) ->
if
C >= $a, C =< $z ->
[C - 32 | toupper(Cs)];
true ->
[C | toupper(Cs)]
end;
toupper([]) ->
[].

View File

@ -281,7 +281,7 @@ set_vcard(User, LServer, VCARD) ->
?TLFIELD("text-single", "Birthday", "bday"),
?TLFIELD("text-single", "Country", "ctry"),
?TLFIELD("text-single", "City", "locality"),
?TLFIELD("text-single", "email", "email"),
?TLFIELD("text-single", "Email", "email"),
?TLFIELD("text-single", "Organization Name", "orgname"),
?TLFIELD("text-single", "Organization Unit", "orgunit")
]}]).
@ -439,10 +439,10 @@ find_xdata_el1([_ | Els]) ->
search_result(Lang, JID, ServerHost, Data) ->
[{xmlelement, "title", [],
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
[{xmlcdata, translate:translate(Lang, "Search Results for ") ++
jlib:jid_to_string(JID)}]},
{xmlelement, "reported", [],
[?LFIELD("JID", "jid"),
[?LFIELD("Jabber ID", "jid"),
?LFIELD("Full Name", "fn"),
?LFIELD("Name", "given"),
?LFIELD("Middle Name", "middle"),
@ -451,7 +451,7 @@ search_result(Lang, JID, ServerHost, Data) ->
?LFIELD("Birthday", "bday"),
?LFIELD("Country", "ctry"),
?LFIELD("City", "locality"),
?LFIELD("email", "email"),
?LFIELD("Email", "email"),
?LFIELD("Organization Name", "orgname"),
?LFIELD("Organization Unit", "orgunit")
]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)).

View File

@ -239,7 +239,7 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
?TLFIELD("text-single", "Birthday", "bday"),
?TLFIELD("text-single", "Country", "ctry"),
?TLFIELD("text-single", "City", "locality"),
?TLFIELD("text-single", "email", "email"),
?TLFIELD("text-single", "Email", "email"),
?TLFIELD("text-single", "Organization Name", "orgname"),
?TLFIELD("text-single", "Organization Unit", "orgunit")
]}]).
@ -397,10 +397,10 @@ find_xdata_el1([_ | Els]) ->
search_result(Lang, JID, ServerHost, Data) ->
[{xmlelement, "title", [],
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
[{xmlcdata, translate:translate(Lang, "Search Results for ") ++
jlib:jid_to_string(JID)}]},
{xmlelement, "reported", [],
[?LFIELD("JID", "jid"),
[?LFIELD("Jabber ID", "jid"),
?LFIELD("Full Name", "fn"),
?LFIELD("Given Name", "given"),
?LFIELD("Middle Name", "middle"),
@ -409,7 +409,7 @@ search_result(Lang, JID, ServerHost, Data) ->
?LFIELD("Birthday", "bday"),
?LFIELD("Country", "ctry"),
?LFIELD("City", "locality"),
?LFIELD("email", "email"),
?LFIELD("Email", "email"),
?LFIELD("Organization Name", "orgname"),
?LFIELD("Organization Unit", "orgunit")
]}] ++ lists:map(fun(E) ->

View File

@ -281,7 +281,7 @@ set_vcard(User, LServer, VCARD) ->
?TLFIELD("text-single", "Birthday", "bday"),
?TLFIELD("text-single", "Country", "ctry"),
?TLFIELD("text-single", "City", "locality"),
?TLFIELD("text-single", "email", "email"),
?TLFIELD("text-single", "Email", "email"),
?TLFIELD("text-single", "Organization Name", "orgname"),
?TLFIELD("text-single", "Organization Unit", "orgunit")
]}]).
@ -436,10 +436,10 @@ find_xdata_el1([_ | Els]) ->
search_result(Lang, JID, ServerHost, Data) ->
[{xmlelement, "title", [],
[{xmlcdata, translate:translate(Lang, "Results of search in ") ++
[{xmlcdata, translate:translate(Lang, "Search Results for ") ++
jlib:jid_to_string(JID)}]},
{xmlelement, "reported", [],
[?LFIELD("JID", "jid"),
[?LFIELD("Jabber ID", "jid"),
?LFIELD("Full Name", "fn"),
?LFIELD("Name", "given"),
?LFIELD("Middle Name", "middle"),
@ -448,7 +448,7 @@ search_result(Lang, JID, ServerHost, Data) ->
?LFIELD("Birthday", "bday"),
?LFIELD("Country", "ctry"),
?LFIELD("City", "locality"),
?LFIELD("email", "email"),
?LFIELD("Email", "email"),
?LFIELD("Organization Name", "orgname"),
?LFIELD("Organization Unit", "orgunit")
]}] ++ lists:map(fun(R) -> record_to_item(ServerHost, R) end,

View File

@ -72,7 +72,7 @@ make_xhtml(Els, global, Lang) ->
[?XAE("div",
[{"id", "header"}],
[?XE("h1",
[?ACT("/admin/", "ejabberd administration")]
[?ACT("/admin/", "Administration")]
)]),
?XAE("div",
[{"id", "navigation"}],
@ -118,7 +118,7 @@ make_xhtml(Els, Host, Lang) ->
[?XAE("div",
[{"id", "header"}],
[?XE("h1",
[?ACT(Base, "ejabberd administration")]
[?ACT(Base, "Administration")]
)]),
?XAE("div",
[{"id", "navigation"}],
@ -527,12 +527,12 @@ process_admin(global,
path = [],
q = Query,
lang = Lang} = Request) ->
make_xhtml([?XCT("h1", "ejabberd administration"),
make_xhtml([?XCT("h1", "Administration"),
?XE("ul",
[?LI([?ACT("/admin/acls/", "Access Control Lists"), ?C(" "),
?ACT("/admin/acls-raw/", "(raw)")]),
?ACT("/admin/acls-raw/", "(Raw)")]),
?LI([?ACT("/admin/access/", "Access Rules"), ?C(" "),
?ACT("/admin/access-raw/", "(raw)")]),
?ACT("/admin/access-raw/", "(Raw)")]),
?LI([?ACT("/admin/vhosts/", "Virtual Hosts")]),
?LI([?ACT("/admin/nodes/", "Nodes")]),
?LI([?ACT("/admin/stats/", "Statistics")])
@ -546,12 +546,12 @@ process_admin(Host,
q = Query,
lang = Lang} = Request) ->
Base = "/admin/server/" ++ Host ++ "/",
make_xhtml([?XCT("h1", "ejabberd administration"),
make_xhtml([?XCT("h1", "Administration"),
?XE("ul",
[?LI([?ACT(Base ++ "acls/", "Access Control Lists"), ?C(" "),
?ACT(Base ++ "acls-raw/", "(raw)")]),
?ACT(Base ++ "acls-raw/", "(Raw)")]),
?LI([?ACT(Base ++ "access/", "Access Rules"), ?C(" "),
?ACT(Base ++ "access-raw/", "(raw)")]),
?ACT(Base ++ "access-raw/", "(Raw)")]),
?LI([?ACT(Base ++ "users/", "Users")]),
?LI([?ACT(Base ++ "online-users/", "Online Users")]),
?LI([?ACT(Base ++ "last-activity/", "Last Activity")]),
@ -620,10 +620,10 @@ process_admin(Host,
"~p.", [lists:keysort(
2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
[], [{{acl, '$1', '$2'}}]}]))])),
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
make_xhtml([?XCT("h1", "Access Control Lists")] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -664,13 +664,13 @@ process_admin(Host,
ACLs = lists:keysort(
2, ets:select(acl, [{{acl, {'$1', Host}, '$2'},
[], [{{acl, '$1', '$2'}}]}])),
make_xhtml([?XCT("h1", "ejabberd access control lists configuration")] ++
make_xhtml([?XCT("h1", "Access Control Lists")] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XE("p", [?ACT("../acls-raw/", "raw")])] ++
[?XE("p", [?ACT("../acls-raw/", "Raw")])] ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[acls_to_xhtml(ACLs),
?BR,
@ -733,10 +733,10 @@ process_admin(Host,
[{{config, {access, '$1', Host}, '$2'},
[],
[{{access, '$1', '$2'}}]}])])),
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
make_xhtml([?XCT("h1", "Access Rules")] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -772,10 +772,10 @@ process_admin(Host,
[{{config, {access, '$1', Host}, '$2'},
[],
[{{access, '$1', '$2'}}]}]),
make_xhtml([?XCT("h1", "ejabberd access rules configuration")] ++
make_xhtml([?XCT("h1", "Access Rules")] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XE("p", [?ACT("../access-raw/", "raw")])] ++
@ -816,8 +816,8 @@ process_admin(Host,
make_xhtml([?XC("h1",
io_lib:format(?T("~s access rule configuration"), [SName]))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -841,7 +841,7 @@ process_admin(Host,
q = Query,
lang = Lang} = Request) when is_list(Host) ->
Res = list_users(Host, Query, Lang, fun url_func/1),
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang);
process_admin(Host,
#request{us = US,
@ -849,7 +849,7 @@ process_admin(Host,
q = Query,
lang = Lang} = Request) when is_list(Host) ->
Res = list_users_in_diapason(Host, Diap, Lang, fun url_func/1),
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
make_xhtml([?XCT("h1", "Users")] ++ Res, Host, Lang);
process_admin(Host,
#request{us = US,
@ -857,7 +857,7 @@ process_admin(Host,
q = Query,
lang = Lang} = Request) when is_list(Host) ->
Res = list_online_users(Host, Lang),
make_xhtml([?XCT("h1", "ejabberd users")] ++ Res, Host, Lang);
make_xhtml([?XCT("h1", "Online Users")] ++ Res, Host, Lang);
process_admin(Host,
#request{method = Method,
@ -878,7 +878,7 @@ process_admin(Host,
_ ->
list_last_activity(Host, Lang, true, Month)
end,
make_xhtml([?XCT("h1", "Users last activity")] ++
make_xhtml([?XCT("h1", "Users Last Activity")] ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[?CT("Period: "),
?XAE("select", [{"name", "period"}],
@ -906,7 +906,7 @@ process_admin(Host,
q = Query,
lang = Lang} = Request) ->
Res = get_stats(Host, Lang),
make_xhtml([?XCT("h1", "ejabberd stats")] ++ Res, Host, Lang);
make_xhtml([?XCT("h1", "Statistics")] ++ Res, Host, Lang);
process_admin(Host,
#request{us = US,
@ -971,7 +971,7 @@ process_admin(Host,
process_admin(Host,
#request{lang = Lang}) ->
setelement(1, make_xhtml([?XC("h1", "Not found")], Host, Lang), 404).
setelement(1, make_xhtml([?XC("h1", "Not Found")], Host, Lang), 404).
@ -1209,8 +1209,8 @@ list_vhosts(Lang) ->
[?XE("thead",
[?XE("tr",
[?XCT("td", "Host"),
?XCT("td", "Registered users"),
?XCT("td", "Online users")
?XCT("td", "Registered Users"),
?XCT("td", "Online Users")
])]),
?XE("tbody",
lists:map(
@ -1254,8 +1254,8 @@ list_users(Host, Query, Lang, URLFunc) ->
end, lists:seq(1, N, M))
end,
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -1313,7 +1313,7 @@ list_given_users(Users, Prefix, Lang, URLFunc) ->
[?XE("thead",
[?XE("tr",
[?XCT("td", "User"),
?XCT("td", "Offline messages"),
?XCT("td", "Offline Messages"),
?XCT("td", "Last Activity")])]),
?XE("tbody",
lists:map(
@ -1371,15 +1371,15 @@ get_stats(global, Lang) ->
S2SServers = length(lists:usort([element(2, C) || C <- S2SConns])),
[?XAE("table", [],
[?XE("tbody",
[?XE("tr", [?XCT("td", "Registered users"),
[?XE("tr", [?XCT("td", "Registered Users:"),
?XC("td", integer_to_list(RegisteredUsers))]),
?XE("tr", [?XCT("td", "Authenticated users"),
?XE("tr", [?XCT("td", "Authenticated Users:"),
?XC("td", integer_to_list(AuthUsers))]),
?XE("tr", [?XCT("td", "Online users"),
?XE("tr", [?XCT("td", "Online Users:"),
?XC("td", integer_to_list(OnlineUsers))]),
?XE("tr", [?XCT("td", "Outgoing S2S connections"),
?XE("tr", [?XCT("td", "Outgoing s2s Connections:"),
?XC("td", integer_to_list(S2SConnections))]),
?XE("tr", [?XCT("td", "Outgoing S2S servers"),
?XE("tr", [?XCT("td", "Outgoing s2s Servers:"),
?XC("td", integer_to_list(S2SServers))])
])
])];
@ -1389,9 +1389,9 @@ get_stats(Host, Lang) ->
RegisteredUsers = length(ejabberd_auth:get_vh_registered_users(Host)),
[?XAE("table", [],
[?XE("tbody",
[?XE("tr", [?XCT("td", "Registered users"),
[?XE("tr", [?XCT("td", "Registered Users:"),
?XC("td", integer_to_list(RegisteredUsers))]),
?XE("tr", [?XCT("td", "Online users"),
?XE("tr", [?XCT("td", "Online Users:"),
?XC("td", integer_to_list(OnlineUsers))])
])
])].
@ -1429,14 +1429,14 @@ user_info(User, Server, Query, Lang) ->
integer_to_list(QueueLen))],
[?XC("h1", ?T("User ") ++ us_to_list(US))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[?XCT("h3", "Connected Resources:")] ++ FResources ++
[?XCT("h3", "Password:")] ++ FPassword ++
[?XCT("h3", "Offline messages:")] ++ FQueueLen ++
[?XCT("h3", "Offline Messages:")] ++ FQueueLen ++
[?XE("h3", [?ACT("roster/", "Roster")])] ++
[?BR, ?INPUTT("submit", "removeuser", "Remove User")])].
@ -1493,11 +1493,11 @@ user_queue(User, Server, Query, Lang) ->
?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])]
)
end, Msgs),
[?XC("h1", io_lib:format(?T("~s offline messages queue"),
[?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"),
[us_to_list(US)]))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -1578,7 +1578,7 @@ user_roster(User, Server, Query, Lang, Admin) ->
[?XE("table",
[?XE("thead",
[?XE("tr",
[?XCT("td", "JID"),
[?XCT("td", "Jabber ID"),
?XCT("td", "Nickname"),
?XCT("td", "Subscription"),
?XCT("td", "Pending"),
@ -1622,15 +1622,15 @@ user_roster(User, Server, Query, Lang, Admin) ->
end,
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
FItems ++
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add JID")
?INPUTT("submit", "addjid", "Add Jabber ID")
])].
user_roster_parse_query(User, Server, Items, Query, Admin) ->
@ -1734,7 +1734,7 @@ list_last_activity(Host, Lang, Integral, Period) ->
Hist = histogram(Vals, Integral),
if
Hist == [] ->
[?CT("No data")];
[?CT("No Data")];
true ->
Left = if
Days == infinity ->
@ -1833,14 +1833,14 @@ get_node(global, Node, [], Query, Lang) ->
Res = node_parse_query(Node, Query),
[?XC("h1", ?T("Node ") ++ atom_to_list(Node))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XE("ul",
[?LI([?ACT("db/", "DB Management")]),
?LI([?ACT("backup/", "Backup Management")]),
?LI([?ACT("ports/", "Listened Ports Management")]),
[?LI([?ACT("db/", "Database")]),
?LI([?ACT("backup/", "Backup")]),
?LI([?ACT("ports/", "Listened Ports")]),
?LI([?ACT("stats/", "Statistics")])
]),
?XAE("form", [{"action", ""}, {"method", "post"}],
@ -1852,13 +1852,13 @@ get_node(global, Node, [], Query, Lang) ->
get_node(Host, Node, [], Query, Lang) ->
[?XC("h1", ?T("Node ") ++ atom_to_list(Node)),
?XE("ul",
[?LI([?ACT("modules/", "Modules Management")])])
[?LI([?ACT("modules/", "Modules")])])
];
get_node(global, Node, ["db"], Query, Lang) ->
case rpc:call(Node, mnesia, system_info, [tables]) of
{badrpc, _Reason} ->
[?XCT("h1", "RPC call error")];
[?XCT("h1", "RPC Call Error")];
Tables ->
Res = node_db_parse_query(Node, Tables, Query),
STables = lists:sort(Tables),
@ -1896,10 +1896,10 @@ get_node(global, Node, ["db"], Query, Lang) ->
integer_to_list(Memory))
])
end, STables),
[?XC("h1", ?T("DB Tables at ") ++ atom_to_list(Node))] ++
[?XC("h1", ?T("Database Tables at ") ++ atom_to_list(Node))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -1924,19 +1924,20 @@ get_node(global, Node, ["db"], Query, Lang) ->
get_node(global, Node, ["backup"], Query, Lang) ->
Res = node_backup_parse_query(Node, Query),
[?XC("h1", ?T("Backup Management at ") ++ atom_to_list(Node)),
[?XC("h1", ?T("Backup of ") ++ atom_to_list(Node)),
?XCT("p", "Remark that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately."),
?XAE("form", [{"action", ""}, {"method", "post"}],
[?XAE("table", [],
[?XE("tbody",
[?XE("tr",
[?XCT("td", "Store a backup in a file"),
[?XCT("td", "Store binary backup:"),
?XE("td", [?INPUT("text", "storepath",
"ejabberd.backup")]),
?XE("td", [?INPUTT("submit", "store",
"OK")])
]),
?XE("tr",
[?XCT("td", "Restore a backup from a file"),
[?XCT("td", "Restore binary backup immediately:"),
?XE("td", [?INPUT("text", "restorepath",
"ejabberd.backup")]),
?XE("td", [?INPUTT("submit", "restore",
@ -1944,21 +1945,21 @@ get_node(global, Node, ["backup"], Query, Lang) ->
]),
?XE("tr",
[?XCT("td",
"Install a database fallback from a file"),
"Restore binary backup after next ejabberd restart (requires less memory):"),
?XE("td", [?INPUT("text", "fallbackpath",
"ejabberd.backup")]),
?XE("td", [?INPUTT("submit", "fallback",
"OK")])
]),
?XE("tr",
[?XCT("td", "Dump a database in a text file"),
[?XCT("td", "Store plain text backup:"),
?XE("td", [?INPUT("text", "dumppath",
"ejabberd.dump")]),
?XE("td", [?INPUTT("submit", "dump",
"OK")])
]),
?XE("tr",
[?XCT("td", "Restore a database from a text file"),
[?XCT("td", "Restore plain text backup immediately:"),
?XE("td", [?INPUT("text", "loadpath",
"ejabberd.dump")]),
?XE("td", [?INPUTT("submit", "load",
@ -1981,8 +1982,8 @@ get_node(global, Node, ["ports"], Query, Lang) ->
rpc:call(Node, ejabberd_config, get_local_option, [listen])),
[?XC("h1", ?T("Listened Ports at ") ++ atom_to_list(Node))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -2004,8 +2005,8 @@ get_node(Host, Node, ["modules"], Query, Lang) when is_list(Host) ->
rpc:call(Node, gen_mod, loaded_modules_with_opts, [Host])),
[?XC("h1", ?T("Modules at ") ++ atom_to_list(Node))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -2028,35 +2029,35 @@ get_node(global, Node, ["stats"], Query, Lang) ->
TransactionsLogged =
rpc:call(Node, mnesia, system_info, [transaction_log_writes]),
[?XC("h1", io_lib:format(?T("~p statistics"), [Node])),
[?XC("h1", io_lib:format(?T("Statistics of ~p"), [Node])),
?XAE("table", [],
[?XE("tbody",
[?XE("tr", [?XCT("td", "Uptime"),
[?XE("tr", [?XCT("td", "Uptime:"),
?XAC("td", [{"class", "alignright"}],
UpTimeS)]),
?XE("tr", [?XCT("td", "CPU Time"),
?XE("tr", [?XCT("td", "CPU Time:"),
?XAC("td", [{"class", "alignright"}],
CPUTimeS)]),
?XE("tr", [?XCT("td", "Authenticated users"),
?XE("tr", [?XCT("td", "Authenticated Users:"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(Users))]),
?XE("tr", [?XCT("td", "Transactions commited"),
?XE("tr", [?XCT("td", "Transactions Commited:"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsCommited))]),
?XE("tr", [?XCT("td", "Transactions aborted"),
?XE("tr", [?XCT("td", "Transactions Aborted:"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsAborted))]),
?XE("tr", [?XCT("td", "Transactions restarted"),
?XE("tr", [?XCT("td", "Transactions Restarted:"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsRestarted))]),
?XE("tr", [?XCT("td", "Transactions logged"),
?XE("tr", [?XCT("td", "Transactions Logged:"),
?XAC("td", [{"class", "alignright"}],
integer_to_list(TransactionsLogged))])
])
])];
get_node(Host, Node, NPath, Query, Lang) ->
[?XCT("h1", "Not found")].
[?XCT("h1", "Not Found")].
node_parse_query(Node, Query) ->
@ -2395,10 +2396,10 @@ list_shared_roster_groups(Host, Query, Lang) ->
]
)]
)]),
[?XC("h1", ?T("Shared roster groups"))] ++
[?XC("h1", ?T("Shared Roster Groups"))] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
@ -2494,11 +2495,11 @@ shared_roster_group(Host, Group, Query, Lang) ->
]
)]
)]),
[?XC("h1", ?T("Shared roster groups"))] ++
[?XC("h1", ?T("Shared Roster Groups"))] ++
[?XC("h2", ?T("Group ") ++ Group)] ++
case Res of
ok -> [?CT("submitted"), ?P];
error -> [?CT("bad format"), ?P];
ok -> [?CT("Submitted"), ?P];
error -> [?CT("Bad format"), ?P];
nothing -> []
end ++
[?XAE("form", [{"action", ""}, {"method", "post"}],