diff --git a/ChangeLog b/ChangeLog index edc7d8eb4..94a915ca3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-02-18 Alexey Shchepin + + * 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 * src/mod_service_log.erl: Bugfix (thanks to Badlop) diff --git a/src/mod_configure.erl b/src/mod_configure.erl index fe8bfd657..ab18f380c 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -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, diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index 869b2e864..d503d17a2 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -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([]) -> + []. + diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index b1b46e3ca..2115d7783 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -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)). diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 332c36cff..68e1fc8a2 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -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) -> diff --git a/src/mod_vcard_odbc.erl b/src/mod_vcard_odbc.erl index 521adf18c..3f03d6532 100644 --- a/src/mod_vcard_odbc.erl +++ b/src/mod_vcard_odbc.erl @@ -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, diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl index c625e4a35..61f7739c5 100644 --- a/src/web/ejabberd_web_admin.erl +++ b/src/web/ejabberd_web_admin.erl @@ -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"}],