25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-22 17:28:25 +01:00

Deprecate most of the functions from jlib.erl

This commit is contained in:
Evgeniy Khramtsov 2016-11-13 10:44:53 +03:00
parent 534e73f732
commit b8f22ff538
18 changed files with 229 additions and 163 deletions

View File

@ -3471,10 +3471,10 @@ enc_tzo({H, M}) ->
-spec dec_utc(_) -> erlang:timestamp().
dec_utc(Val) ->
{_, _, _} = jlib:datetime_string_to_timestamp(Val).
xmpp_util:decode_timestamp(Val).
enc_utc(Val) ->
jlib:now_to_utc_string(Val).
xmpp_util:encode_timestamp(Val).
-spec dec_jid(_) -> jid:jid().
dec_jid(Val) ->

View File

@ -494,7 +494,7 @@ process(_Handlers,
TTL = proplists:get_value(<<"ttl">>, Q, <<"">>),
ExpiresIn = case TTL of
<<>> -> undefined;
_ -> jlib:binary_to_integer(TTL)
_ -> binary_to_integer(TTL)
end,
case oauth2:authorize_password({Username, Server},
ClientId,
@ -556,7 +556,7 @@ process(_Handlers,
TTL = proplists:get_value(<<"ttl">>, Q, <<"">>),
ExpiresIn = case TTL of
<<>> -> undefined;
_ -> jlib:binary_to_integer(TTL)
_ -> binary_to_integer(TTL)
end,
case oauth2:authorize_password({Username, Server},
Scope,

View File

@ -35,27 +35,33 @@
binary_to_integer/1,
integer_to_binary/1]}).
-export([tolower/1, term_to_base64/1, base64_to_term/1,
decode_base64/1, encode_base64/1, ip_to_list/1,
atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1,
l2i/1, i2l/1, i2l/2, queue_drop_while/2,
expr_to_term/1, term_to_expr/1]).
%% The following functions are used by gen_iq_handler.erl for providing backward
%% compatibility and must not be used in other parts of the code
%% Use xmpp:decode() and xmpp:encode() instead
-export([iq_query_info/1, iq_to_xml/1]).
%% The following functions are deprecated and will be removed soon
%% Use functions from xmpp.erl and xmpp_util.erl instead
-export([make_result_iq_reply/1, make_error_reply/3,
make_error_reply/2, make_error_element/2,
make_correct_from_to_attrs/3, replace_from_to_attrs/3,
replace_from_to/3, replace_from_attrs/2, replace_from/2,
remove_attr/2, tolower/1,
get_iq_namespace/1, iq_query_info/1,
remove_attr/2, get_iq_namespace/1,
iq_query_or_response_info/1, is_iq_request_type/1,
iq_to_xml/1, parse_xdata_submit/1,
unwrap_carbon/1, is_standalone_chat_state/1,
parse_xdata_submit/1, unwrap_carbon/1, is_standalone_chat_state/1,
add_delay_info/3, add_delay_info/4,
timestamp_to_legacy/1, timestamp_to_iso_basic/1, timestamp_to_iso/2,
now_to_utc_string/1, now_to_local_string/1,
datetime_string_to_timestamp/1,
term_to_base64/1, base64_to_term/1,
decode_base64/1, encode_base64/1, ip_to_list/1,
rsm_encode/1, rsm_encode/2, rsm_decode/1,
binary_to_integer/1, binary_to_integer/2,
integer_to_binary/1, integer_to_binary/2,
atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1,
l2i/1, i2l/1, i2l/2, queue_drop_while/2,
expr_to_term/1, term_to_expr/1]).
integer_to_binary/1, integer_to_binary/2]).
%% The following functions are deprecated and will be removed soon
%% Use corresponding functions from jid.erl instead
@ -75,8 +81,37 @@
{jid_tolower, 1},
{jid_remove_resource, 1},
{jid_replace_resource, 2},
{add_delay_info, 3},
{add_delay_info, 4},
{make_result_iq_reply, 1},
{make_error_reply, 3},
{make_error_reply, 2},
{make_error_element, 2},
{make_correct_from_to_attrs, 3},
{replace_from_to_attrs, 3},
{replace_from_to, 3},
{replace_from_attrs, 2},
{replace_from, 2},
{remove_attr, 2},
{get_iq_namespace, 1},
{iq_query_or_response_info, 1},
{is_iq_request_type, 1},
{parse_xdata_submit, 1},
{unwrap_carbon, 1},
{is_standalone_chat_state, 1},
{timestamp_to_legacy, 1},
{timestamp_to_iso_basic, 1},
{timestamp_to_iso, 2},
{now_to_utc_string, 1},
{now_to_local_string, 1},
{datetime_string_to_timestamp, 1},
{rsm_encode, 1},
{rsm_encode, 2},
{rsm_decode, 1},
{binary_to_integer, 1},
{binary_to_integer, 2},
{integer_to_binary, 1},
{binary_to_integer, 1}]).
{integer_to_binary, 2}]).
-include("ejabberd.hrl").
-include("jlib.hrl").

View File

@ -761,7 +761,9 @@ set_random_password(User, Server, Reason) ->
set_password_auth(User, Server, NewPass).
build_random_password(Reason) ->
Date = jlib:timestamp_to_legacy(calendar:universal_time()),
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:universal_time(),
Date = str:format("~4..0B~2..0B~2..0BT~2..0B:~2..0B:~2..0B",
[Year, Month, Day, Hour, Minute, Second]),
RandomString = randoms:get_string(),
<<"BANNED_ACCOUNT--", Date/binary, "--", RandomString/binary, "--", Reason/binary>>.

View File

@ -312,14 +312,14 @@ parse_query(#mam_query{xdata = #xdata{fields = Fs}} = Query, Lang) ->
try
lists:foldl(
fun(#xdata_field{var = <<"start">>, values = [Data|_]}, Q) ->
case jlib:datetime_string_to_timestamp(Data) of
undefined -> throw({error, <<"start">>});
try xmpp_util:decode_timestamp(Data) of
{_, _, _} = TS -> Q#mam_query{start = TS}
catch _:{bad_timestamp, _} -> throw({error, <<"start">>})
end;
(#xdata_field{var = <<"end">>, values = [Data|_]}, Q) ->
case jlib:datetime_string_to_timestamp(Data) of
undefined -> throw({error, <<"end">>});
{_, _, _} = TS -> Q#mam_query{'end' = TS}
try xmpp_util:decode_timestamp(Data) of
{_, _, _} = TS -> Q#mam_query{start = TS}
catch _:{bad_timestamp, _} -> throw({error, <<"end">>})
end;
(#xdata_field{var = <<"with">>, values = [Data|_]}, Q) ->
case jid:from_string(Data) of

View File

@ -388,7 +388,7 @@ build_info_room({Name, Host, Pid}) ->
false ->
Last_message1 = queue:last(History),
{_, _, _, Ts_last, _} = Last_message1,
jlib:timestamp_to_legacy(Ts_last)
xmpp_util:encode_timestamp(Ts_last)
end,
{<<Name/binary, "@", Host/binary>>,

View File

@ -285,7 +285,7 @@ get_sm_items(_Acc, #jid{luser = U, lserver = S, lresource = R} = JID,
BareJID = jid:remove_resource(JID),
Pid ! dont_ask_offline,
{result, lists:map(
fun({Seq, From, _To, _El}) ->
fun({Seq, From, _To, _TS, _El}) ->
Node = integer_to_binary(Seq),
#disco_item{jid = BareJID,
node = Node,
@ -400,10 +400,10 @@ handle_offline_fetch(#jid{luser = U, lserver = S, lresource = R}) ->
Pid when is_pid(Pid) ->
Pid ! dont_ask_offline,
lists:foreach(
fun({Node, From, To, El}) ->
fun({Node, El}) ->
NewEl = set_offline_tag(El, Node),
Pid ! {route, From, To, NewEl}
end, read_message_headers(U, S))
Pid ! {route, xmpp:get_from(El), xmpp:get_to(El), NewEl}
end, read_messages(U, S))
end.
-spec fetch_msg_by_node(jid(), binary()) -> error | {ok, #offline_msg{}}.
@ -476,11 +476,13 @@ store_packet(From, To, Packet) ->
NewPacket ->
TimeStamp = p1_time_compat:timestamp(),
Expire = find_x_expire(TimeStamp, NewPacket),
El = xmpp:encode(NewPacket),
gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
#offline_msg{us = {LUser, LServer},
timestamp = TimeStamp, expire = Expire,
from = From, to = To, packet = El},
timestamp = TimeStamp,
expire = Expire,
from = From,
to = To,
packet = NewPacket},
stop
end;
_ -> ok
@ -547,10 +549,13 @@ resend_offline_messages(User, Server) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
case Mod:pop_messages(LUser, LServer) of
{ok, Rs} ->
lists:foreach(fun (R) ->
ejabberd_sm ! offline_msg_to_route(LServer, R)
end,
lists:keysort(#offline_msg.timestamp, Rs));
lists:foreach(
fun(R) ->
case offline_msg_to_route(LServer, R) of
error -> ok;
RouteMsg -> ejabberd_sm ! RouteMsg
end
end, lists:keysort(#offline_msg.timestamp, Rs));
_ -> ok
end.
@ -565,22 +570,26 @@ pop_offline_messages(Ls, User, Server) ->
{ok, Rs} ->
TS = p1_time_compat:timestamp(),
Ls ++
lists:map(fun (R) ->
offline_msg_to_route(LServer, R)
end,
lists:filter(
fun(#offline_msg{packet = Pkt} = R) ->
Expire = case R#offline_msg.expire of
undefined ->
find_x_expire(TS, Pkt);
Exp ->
Exp
end,
case Expire of
never -> true;
TimeStamp -> TS < TimeStamp
end
end, Rs));
lists:flatmap(
fun(R) ->
case offline_msg_to_route(LServer, R) of
error -> [];
RouteMsg -> [RouteMsg]
end
end,
lists:filter(
fun(#offline_msg{packet = Pkt} = R) ->
Expire = case R#offline_msg.expire of
undefined ->
find_x_expire(TS, Pkt);
Exp ->
Exp
end,
case Expire of
never -> true;
TimeStamp -> TS < TimeStamp
end
end, Rs));
_ ->
Ls
end.
@ -625,52 +634,61 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc.
get_offline_els(LUser, LServer) ->
Hdrs = read_message_headers(LUser, LServer),
lists:map(
fun({_Seq, From, To, Packet}) ->
xmpp:set_from_to(Packet, From, To)
end, Hdrs).
[Packet || {_Seq, Packet} <- read_messages(LUser, LServer)].
-spec offline_msg_to_route(binary(), #offline_msg{}) ->
{route, jid(), jid(), message()} | error.
offline_msg_to_route(LServer, #offline_msg{} = R) ->
Pkt = xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]),
Pkt1 = case R#offline_msg.timestamp of
undefined ->
Pkt;
TS ->
xmpp_util:add_delay_info(Pkt, jid:make(LServer), TS,
<<"Offline Storage">>)
end,
{route, R#offline_msg.from, R#offline_msg.to, Pkt1}.
try xmpp:decode(R#offline_msg.packet, ?NS_CLIENT, [ignore_els]) of
Pkt ->
NewPkt = add_delay_info(Pkt, LServer, R#offline_msg.timestamp),
{route, R#offline_msg.from, R#offline_msg.to, NewPkt}
catch _:{xmpp_codec, Why} ->
?ERROR_MSG("failed to decode packet ~p of user ~s: ~s",
[R#offline_msg.packet, jid:to_string(R#offline_msg.to),
xmpp:format_error(Why)]),
error
end.
read_message_headers(LUser, LServer) ->
-spec read_messages(binary(), binary()) -> [{binary(), message()}].
read_messages(LUser, LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
lists:map(
fun({Seq, From, To, El}) ->
lists:flatmap(
fun({Seq, From, To, TS, El}) ->
Node = integer_to_binary(Seq),
Packet = xmpp:decode(El, ?NS_CLIENT, [ignore_els]),
{Node, From, To, Packet}
try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of
Pkt ->
Node = integer_to_binary(Seq),
Pkt1 = add_delay_info(Pkt, LServer, TS),
Pkt2 = xmpp:set_from_to(Pkt1, From, To),
[{Node, Pkt2}]
catch _:{xmpp_codec, Why} ->
?ERROR_MSG("failed to decode packet ~p "
"of user ~s: ~s",
[El, jid:to_string(To),
xmpp:format_error(Why)]),
[]
end
end, Mod:read_message_headers(LUser, LServer)).
format_user_queue(Hdrs) ->
lists:map(
fun({Seq, From, To, El}) ->
fun({Seq, From, To, TS, El}) ->
ID = integer_to_binary(Seq),
FPacket = ejabberd_web_admin:pretty_print_xml(El),
SFrom = jid:to_string(From),
STo = jid:to_string(To),
Stamp = fxml:get_path_s(El, [{elem, <<"delay">>},
{attr, <<"stamp">>}]),
Time = case jlib:datetime_string_to_timestamp(Stamp) of
Time = case TS of
undefined ->
Stamp = fxml:get_path_s(El, [{elem, <<"delay">>},
{attr, <<"stamp">>}]),
try xmpp_util:decode_timestamp(Stamp) of
{_, _, _} = Now -> format_time(Now)
catch _:_ ->
<<"">>
end;
{_, _, _} = Now ->
{{Year, Month, Day}, {Hour, Minute, Second}} =
calendar:now_to_local_time(Now),
iolist_to_binary(
io_lib:format(
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
[Year, Month, Day, Hour, Minute,
Second]));
_ ->
<<"">>
format_time(Now)
end,
?XE(<<"tr">>,
[?XAE(<<"td">>, [{<<"class">>, <<"valign">>}],
@ -682,6 +700,11 @@ format_user_queue(Hdrs) ->
[?XC(<<"pre">>, FPacket)])])
end, Hdrs).
format_time(Now) ->
{{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_local_time(Now),
str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
[Year, Month, Day, Hour, Minute, Second]).
user_queue(User, Server, Query, Lang) ->
LUser = jid:nodeprep(User),
LServer = jid:nameprep(Server),
@ -815,6 +838,14 @@ count_offline_messages(User, Server) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:count_messages(LUser, LServer).
-spec add_delay_info(message(), binary(),
undefined | erlang:timestamp()) -> message().
add_delay_info(Packet, _LServer, undefined) ->
Packet;
add_delay_info(Packet, LServer, {_, _, _} = TS) ->
xmpp_util:add_delay_info(Packet, jid:make(LServer), TS,
<<"Offline storage">>).
export(LServer) ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod:export(LServer).

View File

@ -42,7 +42,11 @@ store_messages(_Host, US, Msgs, Len, MaxOfflineMsgs) ->
mnesia:write_lock_table(offline_msg);
true -> ok
end,
lists:foreach(fun (M) -> mnesia:write(M) end, Msgs)
lists:foreach(
fun(#offline_msg{packet = Pkt} = M) ->
El = xmpp:encode(Pkt),
mnesia:write(M#offline_msg{packet = El})
end, Msgs)
end
end,
mnesia:transaction(F).
@ -107,9 +111,7 @@ read_message_headers(LUser, LServer) ->
fun(#offline_msg{from = From, to = To, packet = Pkt,
timestamp = TS}) ->
Seq = now_to_integer(TS),
NewPkt = jlib:add_delay_info(Pkt, LServer, TS,
<<"Offline Storage">>),
{Seq, From, To, NewPkt}
{Seq, From, To, TS, Pkt}
end, Msgs),
lists:keysort(1, Hdrs).

View File

@ -36,9 +36,12 @@ store_messages(Host, {User, _}, Msgs, Len, MaxOfflineMsgs) ->
try
lists:foreach(
fun(#offline_msg{us = US,
packet = Pkt,
timestamp = TS} = M) ->
El = xmpp:encode(Pkt),
ok = ejabberd_riak:put(
M, offline_msg_schema(),
M#offline_msg{packet = El},
offline_msg_schema(),
[{i, TS}, {'2i', [{<<"us">>, US}]}])
end, Msgs),
{atomic, ok}
@ -85,9 +88,7 @@ read_message_headers(LUser, LServer) ->
fun(#offline_msg{from = From, to = To, packet = Pkt,
timestamp = TS}) ->
Seq = now_to_integer(TS),
NewPkt = jlib:add_delay_info(
Pkt, LServer, TS, <<"Offline Storage">>),
{Seq, From, To, NewPkt}
{Seq, From, To, Pkt}
end, Rs),
lists:keysort(1, Hdrs);
_Err ->

View File

@ -41,14 +41,14 @@ store_messages(Host, {User, _Server}, Msgs, Len, MaxOfflineMsgs) ->
LUser = (M#offline_msg.to)#jid.luser,
From = M#offline_msg.from,
To = M#offline_msg.to,
Packet =
jlib:replace_from_to(From, To,
M#offline_msg.packet),
NewPacket =
jlib:add_delay_info(Packet, Host,
M#offline_msg.timestamp,
<<"Offline Storage">>),
XML = fxml:element_to_binary(NewPacket),
Packet = xmpp:set_from_to(
M#offline_msg.packet, From, To),
NewPacket = xmpp_util:add_delay_info(
Packet, jid:make(Host),
M#offline_msg.timestamp,
<<"Offline Storage">>),
XML = fxml:element_to_binary(
xmpp:encode(NewPacket)),
sql_queries:add_spool_sql(LUser, XML)
end,
Msgs),
@ -171,15 +171,23 @@ export(_Server) ->
[{offline_msg,
fun(Host, #offline_msg{us = {LUser, LServer},
timestamp = TimeStamp, from = From, to = To,
packet = Packet})
packet = El})
when LServer == Host ->
Packet1 = jlib:replace_from_to(From, To, Packet),
Packet2 = jlib:add_delay_info(Packet1, LServer, TimeStamp,
<<"Offline Storage">>),
XML = fxml:element_to_binary(Packet2),
[?SQL("delete from spool where username=%(LUser)s;"),
?SQL("insert into spool(username, xml) values ("
"%(LUser)s, %(XML)s);")];
try xmpp:decode(El, ?NS_CLIENT, [ignore_els]) of
Packet ->
Packet1 = xmpp:set_from_to(Packet, From, To),
Packet2 = xmpp_util:add_delay_info(
Packet1, jid:make(LServer),
TimeStamp, <<"Offline Storage">>),
XML = fxml:element_to_binary(xmpp:encode(Packet2)),
[?SQL("delete from spool where username=%(LUser)s;"),
?SQL("insert into spool(username, xml) values ("
"%(LUser)s, %(XML)s);")]
catch _:{xmpp_codec, Why} ->
?ERROR_MSG("failed to decode packet ~p of user ~s@~s: ~s",
[El, LUser, LServer, xmpp:format_error(Why)]),
[]
end;
(_Host, _R) ->
[]
end}].
@ -188,23 +196,21 @@ import(LServer) ->
[{<<"select username, xml from spool;">>,
fun([LUser, XML]) ->
El = #xmlel{} = fxml_stream:parse_element(XML),
From = #jid{} = jid:from_string(
fxml:get_attr_s(<<"from">>, El#xmlel.attrs)),
To = #jid{} = jid:from_string(
fxml:get_attr_s(<<"to">>, El#xmlel.attrs)),
Stamp = fxml:get_path_s(El, [{elem, <<"delay">>},
{attr, <<"stamp">>}]),
TS = case jlib:datetime_string_to_timestamp(Stamp) of
{_, _, _} = Now ->
Now;
undefined ->
p1_time_compat:timestamp()
end,
Expire = mod_offline:find_x_expire(TS, El#xmlel.children),
#offline_msg{us = {LUser, LServer},
from = From, to = To,
#message{} = Pkt = xmpp:decode(El, ?NS_CLIENT, [ignore_els]),
From = Pkt#message.from,
To = case Pkt#message.to of
undefined -> jid:make(LUser, LServer);
JID -> JID
end,
TS = case xmpp:get_subtag(Pkt, #delay{}) of
#delay{stamp = Stamp} -> Stamp;
false -> p1_time_compat:timestamp()
end,
Expire = mod_offline:find_x_expire(TS, Pkt),
#offline_msg{us = {LUser, LServer},
from = From, to = To,
packet = El,
timestamp = TS, expire = Expire}
timestamp = TS, expire = Expire}
end}].
import(_, _) ->

View File

@ -300,8 +300,8 @@ convert_privacy_item({_, Item}) ->
match_presence_out = MatchPresOut}.
el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) ->
case jlib:datetime_string_to_timestamp(
fxml:get_attr_s(<<"stamp">>, Attrs)) of
try xmpp_util:decode_timestamp(
fxml:get_attr_s(<<"stamp">>, Attrs)) of
{_, _, _} = TS ->
Attrs1 = lists:filter(
fun(<<"stamp">>) -> false;
@ -321,8 +321,8 @@ el_to_offline_msg(LUser, LServer, #xmlel{attrs = Attrs} = El) ->
packet = Packet}];
_ ->
[]
end;
_ ->
end
catch _:{bad_timestamp, _} ->
[]
end.

View File

@ -132,10 +132,10 @@ integer_to_sql(N) -> iolist_to_binary(integer_to_list(N)).
boolean_to_sql(true) -> <<"1">>;
boolean_to_sql(false) -> <<"0">>.
timestamp_to_sql(T) -> jlib:now_to_utc_string(T).
timestamp_to_sql(T) -> xmpp_util:encode_timestamp(T).
sql_to_integer(N) -> binary_to_integer(N).
sql_to_boolean(B) -> B == <<"1">>.
sql_to_timestamp(T) -> jlib:datetime_string_to_timestamp(T).
sql_to_timestamp(T) -> xmpp_util:decode_timestamp(T).

View File

@ -211,13 +211,11 @@ val_xfield(digest_frequency = Opt, [Val]) ->
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}
end;
val_xfield(expire = Opt, [Val]) ->
case jlib:datetime_string_to_timestamp(Val) of
undefined ->
try xmpp_util:decode_timestamp(Val)
catch _:{bad_timestamp, _} ->
Txt = <<"Value of '~s' should be datetime string">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)};
Timestamp ->
Timestamp
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}
end;
val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
val_xfield(show_values, Vals) -> Vals;

View File

@ -176,13 +176,11 @@ val_xfield(digest_frequency = Opt, [Val]) ->
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}
end;
val_xfield(expire = Opt, [Val]) ->
case jlib:datetime_string_to_timestamp(Val) of
undefined ->
try xmpp_util:decode_timestamp(Val)
catch _:{bad_timestamp, _} ->
Txt = <<"Value of '~s' should be datetime string">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)};
Timestamp ->
Timestamp
{error, xmpp:err_not_acceptable(ErrTxt, ?MYLANG)}
end;
val_xfield(include_body = Opt, [Val]) -> xopt_to_bool(Opt, Val);
val_xfield(show_values, Vals) -> Vals;

View File

@ -38,7 +38,7 @@ start() ->
get_string() ->
R = crypto:rand_uniform(0, ?THRESHOLD),
jlib:integer_to_binary(R).
integer_to_binary(R).
uniform() ->
crypto:rand_uniform(0, ?THRESHOLD)/?THRESHOLD.

View File

@ -18,7 +18,7 @@
format_error/1, is_stanza/1, set_subtag/2, get_subtag/2,
remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3,
pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2,
is_known_tag/1, is_known_tag/2]).
is_known_tag/1, is_known_tag/2, append_subtags/2]).
%% XMPP errors
-export([err_bad_request/0, err_bad_request/2,
@ -369,6 +369,11 @@ has_subtag([El|Els], TagName, XMLNS) ->
has_subtag([], _, _) ->
false.
-spec append_subtags(stanza(), [xmpp_element() | xmlel()]) -> stanza().
append_subtags(Stanza, Tags) ->
Els = get_els(Stanza),
set_els(Stanza, Els ++ Tags).
-spec get_text([text()]) -> binary().
get_text([]) -> <<"">>;
get_text([#text{data = Data}|_]) -> Data.

View File

@ -6782,10 +6782,9 @@ dec_jid(Val) ->
J -> J
end.
enc_utc(Val) -> jlib:now_to_utc_string(Val).
enc_utc(Val) -> xmpp_util:encode_timestamp(Val).
dec_utc(Val) ->
{_, _, _} = jlib:datetime_string_to_timestamp(Val).
dec_utc(Val) -> xmpp_util:decode_timestamp(Val).
enc_tzo({H, M}) ->
Sign = if H >= 0 -> <<>>;

View File

@ -27,28 +27,17 @@ add_delay_info(Stz, From, Time) ->
erlang:timestamp(), binary()) -> stanza().
add_delay_info(Stz, From, Time, Desc) ->
NewDelay = #delay{stamp = Time, from = From, desc = Desc},
case xmpp:get_subtag(Stz, #delay{}) of
#delay{from = OldFrom, desc = OldDesc} = Delay ->
#delay{from = OldFrom} ->
case jid:tolower(From) == jid:tolower(OldFrom) of
true when Desc == <<"">> ->
Stz;
true when OldDesc == <<"">> ->
xmpp:set_subtag(Stz, Delay#delay{desc = Desc});
true ->
case binary:match(OldDesc, Desc) of
nomatch ->
NewDesc = <<OldDesc/binary, ", ", Desc/binary>>,
xmpp:set_subtag(Stz, Delay#delay{desc = NewDesc});
_ ->
Stz
end;
false ->
NewDelay = #delay{stamp = Time, from = From, desc = Desc},
xmpp:set_subtag(Stz, NewDelay)
xmpp:set_subtag(Stz, NewDelay);
true ->
xmpp:append_subtags(Stz, [NewDelay])
end;
false ->
Delay = #delay{stamp = Time, from = From, desc = Desc},
xmpp:set_subtag(Stz, Delay)
xmpp:append_subtags(Stz, [NewDelay])
end.
-spec unwrap_carbon(stanza()) -> xmpp_element().
@ -147,10 +136,10 @@ try_decode_timestamp(<<Y:4/binary, Mo:2/binary, D:2/binary, $T,
H:2/binary, $:, Mi:2/binary, $:, S:2/binary, $Z>>).
try_decode_fraction(<<$., T/binary>>) ->
{match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], binary}]),
Size = size(V),
<<V:Size/binary, TZD/binary>> = T,
{to_integer(binary:part(V, 0, min(6, Size)), 0, 999999),
{match, [V]} = re:run(T, <<"^[0-9]+">>, [{capture, [0], list}]),
Size = length(V),
<<_:Size/binary, TZD/binary>> = T,
{list_to_integer(string:left(V, 6, $0)),
try_decode_tzd(TZD)};
try_decode_fraction(TZD) ->
{0, try_decode_tzd(TZD)}.