* src/web/ejabberd_http.erl: 'Accept-Language' header support

* src/web/ejabberd_web_admin.erl: Likewise
* src/msgs/ru.msg: Updated

* src/mod_muc/mod_muc_room.erl: Send status code "201" on room
creation

SVN Revision: 227
This commit is contained in:
Alexey Shchepin 2004-05-01 20:10:25 +00:00
parent 13f650037e
commit 4760ff3201
5 changed files with 104 additions and 51 deletions

View File

@ -1,3 +1,12 @@
2004-05-01 Alexey Shchepin <alexey@sevcom.net>
* src/web/ejabberd_http.erl: 'Accept-Language' header support
* src/web/ejabberd_web_admin.erl: Likewise
* src/msgs/ru.msg: Updated
* src/mod_muc/mod_muc_room.erl: Send status code "201" on room
creation
2004-04-27 Alexey Shchepin <alexey@sevcom.net> 2004-04-27 Alexey Shchepin <alexey@sevcom.net>
* src/translate.erl: Search translations directory in priv_dir * src/translate.erl: Search translations directory in priv_dir

View File

@ -65,7 +65,8 @@
affiliations = ?DICT:new(), affiliations = ?DICT:new(),
history = lqueue_new(20), history = lqueue_new(20),
subject = "", subject = "",
subject_author = ""}). subject_author = "",
just_created = false}).
%-define(DBGFSM, true). %-define(DBGFSM, true).
@ -102,7 +103,8 @@ init([Host, Room, Creator, Nick]) ->
State = set_affiliation(Creator, owner, State = set_affiliation(Creator, owner,
#state{host = Host, #state{host = Host,
room = Room, room = Room,
jid = jlib:make_jid(Room, Host, "")}), jid = jlib:make_jid(Room, Host, ""),
just_created = true}),
{ok, normal_state, State}; {ok, normal_state, State};
init([Host, Room, Opts]) -> init([Host, Room, Opts]) ->
State = set_opts(Opts, #state{host = Host, State = set_opts(Opts, #state{host = Host,
@ -919,7 +921,12 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
_ -> _ ->
send_subject(From, Lang, StateData) send_subject(From, Lang, StateData)
end, end,
NewState; case NewState#state.just_created of
true ->
NewState#state{just_created = false};
false ->
NewState
end;
nopass -> nopass ->
ErrText = "Password required to enter this room", ErrText = "Password required to enter this room",
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
@ -1216,10 +1223,16 @@ send_new_presence(NJID, StateData) ->
[{"affiliation", SAffiliation}, [{"affiliation", SAffiliation},
{"role", SRole}] {"role", SRole}]
end, end,
Status = case StateData#state.just_created of
true ->
[{xmlelement, "status", [{"code", "201"}], []}];
false ->
[]
end,
Packet = append_subtags( Packet = append_subtags(
Presence, Presence,
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item", ItemAttrs, []}]}]), [{xmlelement, "item", ItemAttrs, []} | Status]}]),
ejabberd_router:route( ejabberd_router:route(
jlib:jid_replace_resource(StateData#state.jid, Nick), jlib:jid_replace_resource(StateData#state.jid, Nick),
Info#user.jid, Info#user.jid,

View File

@ -182,6 +182,13 @@
{"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Примеры: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}. {"Example: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}].", "Примеры: [{\"irc.lucky.net\", \"koi8-r\"}, {\"vendetta.fef.net\", \"iso8859-1\"}]."}.
{"Encodings", "Кодировки"}. {"Encodings", "Кодировки"}.
% web/ejabberd_web_admin.erl
{"Users", "Пользователи"}.
{"Nodes", "Узлы"}.
{"Statistics", "Статистика"}.
{"", ""}.
{"", ""}.
% Local Variables: % Local Variables:
% mode: erlang % mode: erlang
% End: % End:

View File

@ -24,7 +24,8 @@
request_method, request_method,
request_path, request_path,
request_auth, request_auth,
request_content_length request_content_length,
request_lang = "en"
}). }).
@ -74,6 +75,8 @@ receive_headers(State) ->
_ -> _ ->
receive_headers(State) receive_headers(State)
end; end;
{ok, {http_header, _, 'Accept-Language', _, Langs}} ->
receive_headers(State#state{request_lang = parse_lang(Langs)});
{ok, {http_header, _, _, _, _}} -> {ok, {http_header, _, _, _, _}} ->
receive_headers(State); receive_headers(State);
{ok, http_eoh} -> {ok, http_eoh} ->
@ -100,7 +103,8 @@ receive_headers(State) ->
process_request(#state{request_method = 'GET', process_request(#state{request_method = 'GET',
request_path = {abs_path, Path}, request_path = {abs_path, Path},
request_auth = Auth}) -> request_auth = Auth,
request_lang = Lang}) ->
User = case Auth of User = case Auth of
{U, P} -> {U, P} ->
case ejabberd_auth:check_password(U, P) of case ejabberd_auth:check_password(U, P) of
@ -129,7 +133,8 @@ process_request(#state{request_method = 'GET',
Request = #request{method = 'GET', Request = #request{method = 'GET',
path = LPath, path = LPath,
q = LQuery, q = LQuery,
user = User}, user = User,
lang = Lang},
case ejabberd_web:process_get(Request) of case ejabberd_web:process_get(Request) of
El when element(1, El) == xmlelement -> El when element(1, El) == xmlelement ->
make_xhtml_output(200, [], El); make_xhtml_output(200, [], El);
@ -149,6 +154,7 @@ process_request(#state{request_method = 'POST',
request_path = {abs_path, Path}, request_path = {abs_path, Path},
request_auth = Auth, request_auth = Auth,
request_content_length = Len, request_content_length = Len,
request_lang = Lang,
sockmod = SockMod, sockmod = SockMod,
socket = Socket} = State) when is_integer(Len) -> socket = Socket} = State) when is_integer(Len) ->
User = case Auth of User = case Auth of
@ -188,7 +194,8 @@ process_request(#state{request_method = 'POST',
path = LPath, path = LPath,
q = LQuery, q = LQuery,
user = User, user = User,
data = Data}, data = Data,
lang = Lang},
case ejabberd_web:process_get(Request) of case ejabberd_web:process_get(Request) of
El when element(1, El) == xmlelement -> El when element(1, El) == xmlelement ->
make_xhtml_output(200, [], El); make_xhtml_output(200, [], El);
@ -272,6 +279,15 @@ make_text_output(Status, Headers, Text) ->
[SL, H, "\r\n", Data]. [SL, H, "\r\n", Data].
parse_lang(Langs) ->
case string:tokens(Langs, ",; ") of
[First | _] ->
First;
[] ->
"en"
end.
% Code below is taken (with some modifications) from the yaws webserver, which % Code below is taken (with some modifications) from the yaws webserver, which
% is distributed under the folowing license: % is distributed under the folowing license:

View File

@ -25,17 +25,25 @@
-define(XC(Name, Text), ?XE(Name, [?C(Text)])). -define(XC(Name, Text), ?XE(Name, [?C(Text)])).
-define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])). -define(XAC(Name, Attrs, Text), ?XAE(Name, Attrs, [?C(Text)])).
-define(T(Text), translate:translate(Lang, Text)).
-define(CT(Text), ?C(?T(Text))).
-define(XCT(Name, Text), ?XC(Name, ?T(Text))).
-define(XACT(Name, Attrs, Text), ?XAC(Name, Attrs, ?T(Text))).
-define(LI(Els), ?XE("li", Els)). -define(LI(Els), ?XE("li", Els)).
-define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)). -define(A(URL, Els), ?XAE("a", [{"href", URL}], Els)).
-define(AC(URL, Text), ?A(URL, [?C(Text)])). -define(AC(URL, Text), ?A(URL, [?C(Text)])).
-define(ACT(URL, Text), ?AC(URL, ?T(Text))).
-define(P, ?X("p")). -define(P, ?X("p")).
-define(BR, ?X("br")). -define(BR, ?X("br")).
-define(INPUT(Type, Name, Value), -define(INPUT(Type, Name, Value),
?XA("input", [{"type", Type}, ?XA("input", [{"type", Type},
{"name", Name}, {"name", Name},
{"value", Value}])). {"value", Value}])).
-define(INPUTT(Type, Name, Value), ?INPUT(Type, Name, ?T(Value))).
make_xhtml(Els) -> make_xhtml(Els, Lang) ->
{200, [html], {200, [html],
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}, {xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"},
{"xml:lang", "en"}, {"xml:lang", "en"},
@ -104,11 +112,11 @@ make_xhtml(Els) ->
{"valign", "top"}], {"valign", "top"}],
[?XAE("ul", [?XAE("ul",
[{"id", "navlist"}], [{"id", "navlist"}],
[?LI([?AC("/admin/acls/", "Access Control Lists")]), [?LI([?ACT("/admin/acls/", "Access Control Lists")]),
?LI([?AC("/admin/access/", "Access Rules")]), ?LI([?ACT("/admin/access/", "Access Rules")]),
?LI([?AC("/admin/users/", "Users")]), ?LI([?ACT("/admin/users/", "Users")]),
?LI([?AC("/admin/nodes/", "Nodes")]), ?LI([?ACT("/admin/nodes/", "Nodes")]),
?LI([?AC("/admin/stats/", "Statistics")]) ?LI([?ACT("/admin/stats/", "Statistics")])
])]), ])]),
?XAE("td", ?XAE("td",
[{"height", "100%"}, [{"height", "100%"},
@ -401,15 +409,15 @@ process_admin(#request{user = User,
lang = Lang} = Request) -> lang = Lang} = Request) ->
make_xhtml([?XC("h1", "ejabberd administration"), make_xhtml([?XC("h1", "ejabberd administration"),
?XE("ul", ?XE("ul",
[?LI([?AC("acls/", "Access Control Lists"), ?C(" "), [?LI([?ACT("acls/", "Access Control Lists"), ?C(" "),
?AC("acls-raw/", "(raw)")]), ?ACT("acls-raw/", "(raw)")]),
?LI([?AC("access/", "Access Rules"), ?C(" "), ?LI([?ACT("access/", "Access Rules"), ?C(" "),
?AC("access-raw/", "(raw)")]), ?ACT("access-raw/", "(raw)")]),
?LI([?AC("users/", "Users")]), ?LI([?ACT("users/", "Users")]),
?LI([?AC("nodes/", "Nodes")]), ?LI([?ACT("nodes/", "Nodes")]),
?LI([?AC("stats/", "Statistics")]) ?LI([?ACT("stats/", "Statistics")])
]) ])
]); ], Lang);
process_admin(#request{user = User, process_admin(#request{user = User,
path = ["style.css"], path = ["style.css"],
@ -461,10 +469,10 @@ process_admin(#request{user = User,
nothing nothing
end, end,
ACLs = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])), ACLs = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])),
make_xhtml([?XC("h1", "ejabberd ACLs configuration")] ++ make_xhtml([?XCT("h1", "ejabberd ACLs configuration")] ++
case Res of case Res of
ok -> [?C("submited"), ?P]; ok -> [?CT("submited"), ?P];
error -> [?C("bad format"), ?P]; error -> [?CT("bad format"), ?P];
nothing -> [] nothing -> []
end ++ end ++
[?XAE("form", [{"method", "post"}], [?XAE("form", [{"method", "post"}],
@ -475,7 +483,7 @@ process_admin(#request{user = User,
?BR, ?BR,
?INPUT("submit", "", "") ?INPUT("submit", "", "")
]) ])
]); ], Lang);
process_admin(#request{method = Method, process_admin(#request{method = Method,
user = User, user = User,
@ -502,20 +510,20 @@ process_admin(#request{method = Method,
nothing nothing
end, end,
ACLs = lists:keysort(2, ets:tab2list(acl)), ACLs = lists:keysort(2, ets:tab2list(acl)),
make_xhtml([?XC("h1", "ejabberd ACLs configuration")] ++ make_xhtml([?XCT("h1", "ejabberd ACLs configuration")] ++
case Res of case Res of
ok -> [?C("submited"), ?P]; ok -> [?CT("submited"), ?P];
error -> [?C("bad format"), ?P]; error -> [?CT("bad format"), ?P];
nothing -> [] nothing -> []
end ++ end ++
[?XAE("form", [{"method", "post"}], [?XAE("form", [{"method", "post"}],
[acls_to_xhtml(ACLs), [acls_to_xhtml(ACLs),
?BR, ?BR,
?INPUT("submit", "delete", "Delete Selected"), ?INPUTT("submit", "delete", "Delete Selected"),
?C(" "), ?C(" "),
?INPUT("submit", "submit", "Submit") ?INPUTT("submit", "submit", "Submit")
]) ])
]); ], Lang);
process_admin(#request{user = User, process_admin(#request{user = User,
path = ["access-raw"], path = ["access-raw"],
@ -582,7 +590,7 @@ process_admin(#request{user = User,
?BR, ?BR,
?INPUT("submit", "", "") ?INPUT("submit", "", "")
]) ])
]); ], Lang);
process_admin(#request{method = Method, process_admin(#request{method = Method,
user = User, user = User,
@ -613,11 +621,11 @@ process_admin(#request{method = Method,
nothing -> [] nothing -> []
end ++ end ++
[?XAE("form", [{"method", "post"}], [?XAE("form", [{"method", "post"}],
[access_rules_to_xhtml(AccessRules), [access_rules_to_xhtml(AccessRules, Lang),
?BR, ?BR,
?INPUT("submit", "delete", "Delete Selected") ?INPUTT("submit", "delete", "Delete Selected")
]) ])
]); ], Lang);
process_admin(#request{method = Method, process_admin(#request{method = Method,
user = User, user = User,
@ -657,31 +665,31 @@ process_admin(#request{method = Method,
?BR, ?BR,
?INPUT("submit", "submit", "") ?INPUT("submit", "submit", "")
]) ])
]); ], Lang);
process_admin(#request{user = User, process_admin(#request{user = User,
path = ["users"], path = ["users"],
q = Query, q = Query,
lang = Lang} = Request) -> lang = Lang} = Request) ->
Res = list_users(), Res = list_users(),
make_xhtml([?XC("h1", "ejabberd users")] ++ Res); make_xhtml([?XC("h1", "ejabberd users")] ++ Res, Lang);
process_admin(#request{user = User, process_admin(#request{user = User,
path = ["users", Diap], path = ["users", Diap],
q = Query, q = Query,
lang = Lang} = Request) -> lang = Lang} = Request) ->
Res = list_users_in_diapason(Diap), Res = list_users_in_diapason(Diap),
make_xhtml([?XC("h1", "ejabberd users")] ++ Res); make_xhtml([?XC("h1", "ejabberd users")] ++ Res, Lang);
process_admin(#request{user = User, process_admin(#request{user = User,
path = ["stats"], path = ["stats"],
q = Query, q = Query,
lang = Lang} = Request) -> lang = Lang} = Request) ->
Res = get_stats(), Res = get_stats(Lang),
make_xhtml([?XC("h1", "ejabberd stats")] ++ Res); make_xhtml([?XC("h1", "ejabberd stats")] ++ Res, Lang);
process_admin(_Request) -> process_admin(#request{lang = Lang}) ->
setelement(1, make_xhtml([?XC("h1", "Not found")]), 404). setelement(1, make_xhtml([?XC("h1", "Not found")], Lang), 404).
@ -816,7 +824,7 @@ acl_parse_delete(ACLs, Query) ->
NewACLs. NewACLs.
access_rules_to_xhtml(AccessRules) -> access_rules_to_xhtml(AccessRules, Lang) ->
?XAE("table", [], ?XAE("table", [],
[?XE("tbody", [?XE("tbody",
lists:map( lists:map(
@ -833,7 +841,7 @@ access_rules_to_xhtml(AccessRules) ->
[?XE("tr", [?XE("tr",
[?X("td"), [?X("td"),
?XE("td", [?INPUT("text", "namenew", "")]), ?XE("td", [?INPUT("text", "namenew", "")]),
?XE("td", [?INPUT("submit", "addnew", "Add New")]) ?XE("td", [?INPUTT("submit", "addnew", "Add New")])
] ]
)] )]
)]). )]).
@ -953,7 +961,7 @@ list_users_in_diapason(Diap) ->
get_stats() -> get_stats(Lang) ->
OnlineUsers = mnesia:table_info(presence, size), OnlineUsers = mnesia:table_info(presence, size),
AuthUsers = mnesia:table_info(session, size), AuthUsers = mnesia:table_info(session, size),
RegisteredUsers = mnesia:table_info(passwd, size), RegisteredUsers = mnesia:table_info(passwd, size),
@ -963,15 +971,15 @@ get_stats() ->
[?XAE("table", [], [?XAE("table", [],
[?XE("tbody", [?XE("tbody",
[?XE("tr", [?XC("td", "Registered users"), [?XE("tr", [?XCT("td", "Registered users"),
?XC("td", integer_to_list(RegisteredUsers))]), ?XC("td", integer_to_list(RegisteredUsers))]),
?XE("tr", [?XC("td", "Authentificated users"), ?XE("tr", [?XCT("td", "Authentificated users"),
?XC("td", integer_to_list(AuthUsers))]), ?XC("td", integer_to_list(AuthUsers))]),
?XE("tr", [?XC("td", "Online users"), ?XE("tr", [?XCT("td", "Online users"),
?XC("td", integer_to_list(OnlineUsers))]), ?XC("td", integer_to_list(OnlineUsers))]),
?XE("tr", [?XC("td", "Outgoing S2S connections"), ?XE("tr", [?XCT("td", "Outgoing S2S connections"),
?XC("td", integer_to_list(S2SConnections))]), ?XC("td", integer_to_list(S2SConnections))]),
?XE("tr", [?XC("td", "Outgoing S2S servers"), ?XE("tr", [?XCT("td", "Outgoing S2S servers"),
?XC("td", integer_to_list(S2SServers))]) ?XC("td", integer_to_list(S2SServers))])
]) ])
])]. ])].