25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-30 16:36:29 +01:00

o Remove compatibility code. Use the atom 'undefined' in JIDs (normal

and short).
o  Add try/catch blocks where Exmpp can raise exceptions.
o  Remove some unused code.
o  Convert on-disk Mnesia database: JIDs, extra XML elements and
askmessage are concerned.
o  By default, 'askmessage' is now an empty binary instead of an empty
string, for consistency's sake.
o  Fix some bugs.

SVN Revision: 1547
This commit is contained in:
Jean-Sébastien Pédron 2008-08-26 13:59:04 +00:00
parent 9f0d79da9a
commit 4e39f4cab1
3 changed files with 322 additions and 236 deletions

View File

@ -17,6 +17,14 @@
where. Also, in JIDs (normal and short), the atom "undefined' is where. Also, in JIDs (normal and short), the atom "undefined' is
expected, not the empty string anymore! expected, not the empty string anymore!
* src/mod_roster.hrl, src/mod_roster.erl: Remove compatibility code.
Use the atom 'undefined' in JIDs (normal and short). Add try/catch
blocks where Exmpp can raise exceptions. Remove some unused code.
Convert on-disk Mnesia database: JIDs, extra XML elements and
askmessage are concerned. By default, 'askmessage' is now an empty
binary instead of an empty string, for consistency's sake. Fix some
bugs.
2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* translate.erl (ascii_tolower): Accept 'undefined' as a language and * translate.erl (ascii_tolower): Accept 'undefined' as a language and

View File

@ -123,9 +123,7 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
process_iq_get(From, To, IQ_Rec) -> process_iq_get(From, To, IQ_Rec) ->
LUser = From#jid.lnode, US = {From#jid.lnode, From#jid.ldomain},
LServer = From#jid.ldomain,
US = {LUser, LServer},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
Items when is_list(Items) -> Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items), XItems = lists:map(fun item_to_xml/1, Items),
@ -188,14 +186,12 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
end, end,
exmpp_iq:result(IQ_Rec). exmpp_iq:result(IQ_Rec).
process_item_set(From, To, #xmlel{} = Item) -> process_item_set(From, To, #xmlel{} = El) ->
try try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")), JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
% XXX OLD FORMAT: old JID (with empty strings). #jid{node = User, lnode = LUser, ldomain = LServer} = From,
#jid{node = User, lnode = LUser, ldomain = LServer} = JID = jlib:short_jid(JID1),
jlib:to_old_jid(From), LJID = jlib:short_prepd_jid(JID1),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
LJID = jlib:short_jid(JID1),
F = fun() -> F = fun() ->
Res = mnesia:read({roster, {LUser, LServer, LJID}}), Res = mnesia:read({roster, {LUser, LServer, LJID}}),
Item = case Res of Item = case Res of
@ -209,8 +205,8 @@ process_item_set(From, To, #xmlel{} = Item) ->
groups = [], groups = [],
xs = []} xs = []}
end, end,
Item1 = process_item_attrs(Item, Item#xmlel.attrs), Item1 = process_item_attrs(Item, El#xmlel.attrs),
Item2 = process_item_els(Item1, Item#xmlel.children), Item2 = process_item_els(Item1, El#xmlel.children),
case Item2#roster.subscription of case Item2#roster.subscription of
remove -> remove ->
mnesia:delete({roster, {LUser, LServer, LJID}}); mnesia:delete({roster, {LUser, LServer, LJID}});
@ -270,15 +266,6 @@ process_item_set(_From, _To, _) ->
process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) -> process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of case Attr of
'jid' ->
try
JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs(Item#roster{jid = JID}, Attrs)
catch
_ ->
process_item_attrs(Item, Attrs)
end;
'name' -> 'name' ->
process_item_attrs(Item#roster{name = Val}, Attrs); process_item_attrs(Item#roster{name = Val}, Attrs);
'subscription' -> 'subscription' ->
@ -319,7 +306,7 @@ process_item_els(Item, []) ->
push_item(User, Server, From, Item) -> push_item(User, Server, From, Item) ->
ejabberd_sm:route(exmpp_jid:make_bare_jid(""), ejabberd_sm:route(#jid{},
exmpp_jid:make_bare_jid(User, Server), exmpp_jid:make_bare_jid(User, Server),
#xmlel{name = 'broadcast', children = #xmlel{name = 'broadcast', children =
[{item, [{item,
@ -340,12 +327,17 @@ push_item(User, Server, Resource, From, Item) ->
ResIQ). ResIQ).
get_subscription_lists(_, User, Server) -> get_subscription_lists(_, User, Server) ->
LUser = exmpp_stringprep:nodeprep(User), try
LServer = exmpp_stringprep:nameprep(Server), LUser = exmpp_stringprep:nodeprep(User),
US = {LUser, LServer}, LServer = exmpp_stringprep:nameprep(Server),
case mnesia:dirty_index_read(roster, US, #roster.us) of US = {LUser, LServer},
Items when is_list(Items) -> case mnesia:dirty_index_read(roster, US, #roster.us) of
fill_subscription_lists(Items, [], []); Items when is_list(Items) ->
fill_subscription_lists(Items, [], []);
_ ->
{[], []}
end
catch
_ -> _ ->
{[], []} {[], []}
end. end.
@ -378,84 +370,87 @@ out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, []). process_subscription(out, User, Server, JID, Type, []).
process_subscription(Direction, User, Server, JID1, Type, Reason) -> process_subscription(Direction, User, Server, JID1, Type, Reason) ->
LUser = exmpp_stringprep:nodeprep(User), try
LServer = exmpp_stringprep:nameprep(Server), LUser = exmpp_stringprep:nodeprep(User),
US = {LUser, LServer}, LServer = exmpp_stringprep:nameprep(Server),
LJID = jlib:short_jid(JID1), US = {LUser, LServer},
F = fun() -> LJID = jlib:short_prepd_jid(JID1),
Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of F = fun() ->
[] -> Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
JID = {JID1#jid.node, [] ->
JID1#jid.domain, JID = jlib:short_jid(JID1),
JID1#jid.resource}, #roster{usj = {LUser, LServer, LJID},
#roster{usj = {LUser, LServer, LJID}, us = US,
us = US, jid = JID};
jid = JID}; [I] ->
[I] -> I
I
end,
NewState = case Direction of
out ->
out_state_change(Item#roster.subscription,
Item#roster.ask,
Type);
in ->
in_state_change(Item#roster.subscription,
Item#roster.ask,
Type)
end, end,
AutoReply = case Direction of NewState = case Direction of
out -> out ->
none; out_state_change(Item#roster.subscription,
in -> Item#roster.ask,
in_auto_reply(Item#roster.subscription, Type);
Item#roster.ask, in ->
Type) in_state_change(Item#roster.subscription,
end, Item#roster.ask,
AskMessage = case NewState of Type)
{_, both} -> Reason; end,
{_, in} -> Reason; AutoReply = case Direction of
_ -> "" out ->
end, none;
case NewState of in ->
none -> in_auto_reply(Item#roster.subscription,
{none, AutoReply}; Item#roster.ask,
{none, none} when Item#roster.subscription == none, Type)
Item#roster.ask == in -> end,
mnesia:delete({roster, {LUser, LServer, LJID}}), AskMessage = case NewState of
{none, AutoReply}; {_, both} -> Reason;
{Subscription, Pending} -> {_, in} -> Reason;
NewItem = Item#roster{subscription = Subscription, _ -> ""
ask = Pending, end,
askmessage = list_to_binary(AskMessage)}, case NewState of
mnesia:write(NewItem), none ->
{{push, NewItem}, AutoReply} {none, AutoReply};
end {none, none} when Item#roster.subscription == none,
end, Item#roster.ask == in ->
case mnesia:transaction(F) of mnesia:delete({roster, {LUser, LServer, LJID}}),
{atomic, {Push, AutoReply}} -> {none, AutoReply};
case AutoReply of {Subscription, Pending} ->
none -> NewItem = Item#roster{subscription = Subscription,
ok; ask = Pending,
_ -> askmessage = list_to_binary(AskMessage)},
ejabberd_router:route( mnesia:write(NewItem),
exmpp_jid:make_bare_jid(User, Server), JID1, {{push, NewItem}, AutoReply}
exmpp_presence:AutoReply()) end
end, end,
case Push of case mnesia:transaction(F) of
{push, Item} -> {atomic, {Push, AutoReply}} ->
if case AutoReply of
Item#roster.subscription == none, none ->
Item#roster.ask == in -> ok;
ok; _ ->
true -> ejabberd_router:route(
push_item(User, Server, exmpp_jid:make_bare_jid(User, Server), JID1,
exmpp_jid:make_bare_jid(User, Server), Item) exmpp_presence:AutoReply())
end, end,
true; case Push of
none -> {push, Item} ->
false if
end; Item#roster.subscription == none,
Item#roster.ask == in ->
ok;
true ->
push_item(User, Server,
exmpp_jid:make_bare_jid(User, Server), Item)
end,
true;
none ->
false
end;
_ ->
false
end
catch
_ -> _ ->
false false
end. end.
@ -557,35 +552,44 @@ in_auto_reply(_, _, _) -> none.
remove_user(User, Server) -> remove_user(User, Server) ->
LUser = exmpp_stringpre:nodeprep(User), try
LServer = exmpp_stringprep:nameprep(Server), LUser = exmpp_stringpre:nodeprep(User),
US = {LUser, LServer}, LServer = exmpp_stringprep:nameprep(Server),
F = fun() -> US = {LUser, LServer},
lists:foreach(fun(R) -> F = fun() ->
mnesia:delete_object(R) lists:foreach(fun(R) ->
end, mnesia:delete_object(R)
mnesia:index_read(roster, US, #roster.us)) end,
end, mnesia:index_read(roster, US, #roster.us))
mnesia:transaction(F). end,
mnesia:transaction(F)
catch
_ ->
ok
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_items(User, Server, SubEl) -> set_items(User, Server, #xmlel{children = Els}) ->
{xmlelement, _Name, _Attrs, Els} = SubEl, try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
F = fun() -> F = fun() ->
lists:foreach(fun(El) -> lists:foreach(fun(El) ->
process_item_set_t(LUser, LServer, El) process_item_set_t(LUser, LServer, El)
end, Els) end, Els)
end, end,
mnesia:transaction(F). mnesia:transaction(F)
catch
_ ->
ok
end.
process_item_set_t(LUser, LServer, #xmlel{} = El) -> process_item_set_t(LUser, LServer, #xmlel{} = El) ->
try try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")), JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource}, JID = jlib:short_jid(JID1),
LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource}, LJID = jlib:short_prepd_jid(JID1),
Item = #roster{usj = {LUser, LServer, LJID}, Item = #roster{usj = {LUser, LServer, LJID},
us = {LUser, LServer}, us = {LUser, LServer},
jid = JID}, jid = JID},
@ -606,15 +610,6 @@ process_item_set_t(_LUser, _LServer, _) ->
process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) -> process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of case Attr of
'jid' ->
try
JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
catch
_ ->
process_item_attrs_ws(Item, Attrs)
end;
'name' -> 'name' ->
process_item_attrs_ws(Item#roster{name = Val}, Attrs); process_item_attrs_ws(Item#roster{name = Val}, Attrs);
'subscription' -> 'subscription' ->
@ -650,14 +645,9 @@ get_in_pending_subscriptions(Ls, User, Server) ->
US = {JID#jid.lnode, JID#jid.ldomain}, US = {JID#jid.lnode, JID#jid.ldomain},
case mnesia:dirty_index_read(roster, US, #roster.us) of case mnesia:dirty_index_read(roster, US, #roster.us) of
Result when list(Result) -> Result when list(Result) ->
Ls ++ lists:map( Ls ++ lists:map(
fun(R) -> fun(R) ->
Message = R#roster.askmessage, Message = R#roster.askmessage,
Status = if is_binary(Message) ->
binary_to_list(Message);
true ->
""
end,
{U, S, R} = R#roster.jid, {U, S, R} = R#roster.jid,
Attrs1 = exmpp_stanza:set_sender_in_list([], Attrs1 = exmpp_stanza:set_sender_in_list([],
exmpp_jid:jid_to_list(U, S, R)), exmpp_jid:jid_to_list(U, S, R)),
@ -665,7 +655,7 @@ get_in_pending_subscriptions(Ls, User, Server) ->
exmpp_jid:jid_to_list(JID)), exmpp_jid:jid_to_list(JID)),
Pres1 = exmpp_presence:subscribe(), Pres1 = exmpp_presence:subscribe(),
Pres2 = Pres1#xmlel{attrs = Attrs2}, Pres2 = Pres1#xmlel{attrs = Attrs2},
exmpp_presence:set_status(Pres2, Status) exmpp_presence:set_status(Pres2, Message)
end, end,
lists:filter( lists:filter(
fun(R) -> fun(R) ->
@ -684,27 +674,32 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, Server, JID) -> get_jid_info(_, User, Server, JID) ->
LUser = exmpp_stringprep:nodeprep(User), try
LJID = jlib:short_jid(JID), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of LJID = jlib:short_prepd_jid(JID),
[#roster{subscription = Subscription, groups = Groups}] -> case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
{Subscription, Groups}; [#roster{subscription = Subscription, groups = Groups}] ->
{Subscription, Groups};
_ ->
LRJID = jlib:short_prepd_bare_jid(JID),
if
LRJID == LJID ->
{none, []};
true ->
case catch mnesia:dirty_read(
roster, {LUser, LServer, LRJID}) of
[#roster{subscription = Subscription,
groups = Groups}] ->
{Subscription, Groups};
_ ->
{none, []}
end
end
end
catch
_ -> _ ->
LRJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)), {none, []}
if
LRJID == LJID ->
{none, []};
true ->
case catch mnesia:dirty_read(
roster, {LUser, LServer, LRJID}) of
[#roster{subscription = Subscription,
groups = Groups}] ->
{Subscription, Groups};
_ ->
{none, []}
end
end
end. end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -714,7 +709,7 @@ update_table() ->
Fields = record_info(fields, roster), Fields = record_info(fields, roster),
case mnesia:table_info(roster, attributes) of case mnesia:table_info(roster, attributes) of
Fields -> Fields ->
ok; convert_to_exmpp();
[uj, user, jid, name, subscription, ask, groups, xattrs, xs] -> [uj, user, jid, name, subscription, ask, groups, xattrs, xs] ->
convert_table1(Fields); convert_table1(Fields);
[usj, us, jid, name, subscription, ask, groups, xattrs, xs] -> [usj, us, jid, name, subscription, ask, groups, xattrs, xs] ->
@ -742,11 +737,18 @@ convert_table1(Fields) ->
F1 = fun() -> F1 = fun() ->
mnesia:write_lock_table(mod_roster_tmp_table), mnesia:write_lock_table(mod_roster_tmp_table),
mnesia:foldl( mnesia:foldl(
fun(#roster{usj = {U, JID}, us = U} = R, _) -> fun(#roster{usj = {U, {JID_U, JID_S, JID_R}}, us = U, xs = XS, askmessage = AM} = R, _) ->
U1 = convert_jid_to_exmpp(U),
JID_U1 = convert_jid_to_exmpp(JID_U),
JID_R1 = convert_jid_to_exmpp(JID_R),
JID1 = {JID_U1, JID_S, JID_R1},
XS1 = convert_xs_to_exmpp(XS),
AM1 = convert_askmessage_to_exmpp(AM),
mnesia:dirty_write( mnesia:dirty_write(
mod_roster_tmp_table, mod_roster_tmp_table,
R#roster{usj = {U, Host, JID}, R#roster{usj = {U1, Host, JID1},
us = {U, Host}}) us = {U1, Host}, xs = XS1,
askmessage = AM1})
end, ok, roster) end, ok, roster)
end, end,
mnesia:transaction(F1), mnesia:transaction(F1),
@ -766,9 +768,74 @@ convert_table1(Fields) ->
convert_table2(Fields) -> convert_table2(Fields) ->
?INFO_MSG("Converting roster table from " ?INFO_MSG("Converting roster table from "
"{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []), "{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []),
mnesia:transform_table(roster, ignore, Fields). mnesia:transform_table(roster, ignore, Fields),
convert_to_exmpp().
convert_to_exmpp() ->
Fun = fun() ->
case mnesia:first(roster) of
'$end_of_table' ->
none;
Key ->
case mnesia:read({roster, Key}) of
[#roster{jid = {_, _, undefined}}] ->
none;
[#roster{jid = {_, _, ""}}] ->
mnesia:foldl(fun convert_to_exmpp2/2,
done, roster, write)
end
end
end,
Ret = mnesia:transaction(Fun),
io:format("Conversion return value: ~p~n", [Ret]).
convert_to_exmpp2(#roster{
usj = {USJ_U, USJ_S, {USJ_JU, USJ_JS, USJ_JR}} = Key,
us = {US_U, US_S},
jid = {JID_U, JID_S, JID_R},
xs = XS, askmessage = AM} = R, Acc) ->
% Remove old entry.
mnesia:delete({roster, Key}),
% Convert "" to undefined in JIDs.
USJ_U1 = convert_jid_to_exmpp(USJ_U),
USJ_JU1 = convert_jid_to_exmpp(USJ_JU),
USJ_JR1 = convert_jid_to_exmpp(USJ_JR),
US_U1 = convert_jid_to_exmpp(US_U),
JID_U1 = convert_jid_to_exmpp(JID_U),
JID_R1 = convert_jid_to_exmpp(JID_R),
% Convert xs.
XS1 = convert_xs_to_exmpp(XS),
% Convert askmessage.
AM1 = convert_askmessage_to_exmpp(AM),
% Prepare the new record.
New_R = R#roster{
usj = {USJ_U1, USJ_S, {USJ_JU1, USJ_JS, USJ_JR1}},
us = {US_U1, US_S},
jid = {JID_U1, JID_S, JID_R1},
xs = XS1, askmessage = AM1},
% Write the new record.
mnesia:write(New_R),
Acc.
convert_jid_to_exmpp("") -> undefined;
convert_jid_to_exmpp(V) -> V.
convert_xs_to_exmpp(Els) ->
convert_xs_to_exmpp(Els, []).
convert_xs_to_exmpp([El | Rest], Result) ->
New_El = exmpp_xml:xmlelement_to_xmlel(El,
[?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
convert_xs_to_exmpp(Rest, [New_El | Result]);
convert_xs_to_exmpp([], Result) ->
lists:reverse(Result).
convert_askmessage_to_exmpp(AM) when is_binary(AM) ->
AM;
convert_askmessage_to_exmpp(AM) ->
list_to_binary(AM).
webadmin_page(_, Host, webadmin_page(_, Host,
#request{us = _US, #request{us = _US,
path = ["user", U, "roster"], path = ["user", U, "roster"],
@ -780,74 +847,85 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc. webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) -> user_roster(User, Server, Query, Lang) ->
US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)}, try
Items1 = mnesia:dirty_index_read(roster, US, #roster.us), US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
Res = user_roster_parse_query(User, Server, Items1, Query), Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
Items = mnesia:dirty_index_read(roster, US, #roster.us), Res = user_roster_parse_query(User, Server, Items1, Query),
SItems = lists:sort(Items), Items = mnesia:dirty_index_read(roster, US, #roster.us),
FItems = SItems = lists:sort(Items),
case SItems of FItems =
[] -> case SItems of
[?CT("None")]; [] ->
_ -> [?CT("None")];
[?XE("table", _ ->
[?XE("thead", [?XE("table",
[?XE("tr", [?XE("thead",
[?XCT("td", "Jabber ID"), [?XE("tr",
?XCT("td", "Nickname"), [?XCT("td", "Jabber ID"),
?XCT("td", "Subscription"), ?XCT("td", "Nickname"),
?XCT("td", "Pending"), ?XCT("td", "Subscription"),
?XCT("td", "Groups") ?XCT("td", "Pending"),
])]), ?XCT("td", "Groups")
?XE("tbody", ])]),
lists:map( ?XE("tbody",
fun(R) -> lists:map(
Groups = fun(R) ->
lists:flatmap( Groups =
fun(Group) -> lists:flatmap(
[?C(Group), ?BR] fun(Group) ->
end, R#roster.groups), [?C(Group), ?BR]
Pending = ask_to_pending(R#roster.ask), end, R#roster.groups),
{U, S, R} = R#roster.jid, Pending = ask_to_pending(R#roster.ask),
?XE("tr", {U, S, R} = R#roster.jid,
[?XAC("td", [{"class", "valign"}], ?XE("tr",
catch exmpp_jid:jid_to_list(U, S, R)), [?XAC("td", [{"class", "valign"}],
?XAC("td", [{"class", "valign"}], catch exmpp_jid:jid_to_list(U, S, R)),
R#roster.name), ?XAC("td", [{"class", "valign"}],
?XAC("td", [{"class", "valign"}], R#roster.name),
atom_to_list(R#roster.subscription)), ?XAC("td", [{"class", "valign"}],
?XAC("td", [{"class", "valign"}], atom_to_list(R#roster.subscription)),
atom_to_list(Pending)), ?XAC("td", [{"class", "valign"}],
?XAE("td", [{"class", "valign"}], Groups), atom_to_list(Pending)),
if ?XAE("td", [{"class", "valign"}], Groups),
Pending == in -> if
?XAE("td", [{"class", "valign"}], Pending == in ->
[?INPUTT("submit", ?XAE("td", [{"class", "valign"}],
"validate" ++ [?INPUTT("submit",
ejabberd_web_admin:term_to_id(R#roster.jid), "validate" ++
"Validate")]); ejabberd_web_admin:term_to_id(R#roster.jid),
true -> "Validate")]);
?X("td") true ->
end, ?X("td")
?XAE("td", [{"class", "valign"}], end,
[?INPUTT("submit", ?XAE("td", [{"class", "valign"}],
"remove" ++ [?INPUTT("submit",
ejabberd_web_admin:term_to_id(R#roster.jid), "remove" ++
"Remove")])]) ejabberd_web_admin:term_to_id(R#roster.jid),
end, SItems))])] "Remove")])])
end, end, SItems))])]
[?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++ end,
case Res of [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
ok -> [?CT("Submitted"), ?P]; case Res of
error -> [?CT("Bad format"), ?P]; ok -> [?CT("Submitted"), ?P];
nothing -> [] error -> [?CT("Bad format"), ?P];
end ++ nothing -> []
[?XAE("form", [{"action", ""}, {"method", "post"}], end ++
FItems ++ [?XAE("form", [{"action", ""}, {"method", "post"}],
[?P, FItems ++
?INPUT("text", "newjid", ""), ?C(" "), [?P,
?INPUTT("submit", "addjid", "Add Jabber ID") ?INPUT("text", "newjid", ""), ?C(" "),
])]. ?INPUTT("submit", "addjid", "Add Jabber ID")
])]
catch
_ ->
[?XC("h1", ?T("Roster of ") ++ us_to_list({User, Server}))] ++
[?CT("Bad format"), ?P] ++
[?XAE("form", [{"action", ""}, {"method", "post"}],
[?P,
?INPUT("text", "newjid", ""), ?C(" "),
?INPUTT("submit", "addjid", "Add Jabber ID")
])]
end.
user_roster_parse_query(User, Server, Items, Query) -> user_roster_parse_query(User, Server, Items, Query) ->
case lists:keysearch("addjid", 1, Query) of case lists:keysearch("addjid", 1, Query) of

View File

@ -26,6 +26,6 @@
subscription = none, subscription = none,
ask = none, ask = none,
groups = [], groups = [],
askmessage = [], askmessage = <<>>,
xs = []}). xs = []}).