mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-02 16:37:52 +01:00
Add XEP82 Date Time, update XEP202 Entity Time and XEP203 Delayed Delivery (EJAB-234)
SVN Revision: 2345
This commit is contained in:
parent
f145a32b79
commit
49688feaf2
@ -1805,7 +1805,7 @@ all entries end with a comma:
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modsharedroster"><TT>mod_shared_roster</TT></A></TD><TD ALIGN=left NOWRAP>Shared roster management</TD><TD ALIGN=left NOWRAP><TT>mod_roster</TT> or</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP><TT>mod_roster_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modstats"><TT>mod_stats</TT></A></TD><TD ALIGN=left NOWRAP>Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modtime"><TT>mod_time</TT></A></TD><TD ALIGN=left NOWRAP>Entity Time (<A HREF="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modtime"><TT>mod_time</TT></A></TD><TD ALIGN=left NOWRAP>Entity Time (<A HREF="http://www.xmpp.org/extensions/xep-0202.html">XEP-0202</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcard"><TT>mod_vcard</TT></A></TD><TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.xmpp.org/extensions/xep-0054.html">XEP-0054</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></TD><TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.xmpp.org/extensions/xep-0054.html">XEP-0054</A>)</TD><TD ALIGN=left NOWRAP>LDAP server</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcard"><TT>mod_vcard_odbc</TT></A></TD><TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://www.xmpp.org/extensions/xep-0054.html">XEP-0054</A>)</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
@ -2914,7 +2914,7 @@ by sending:
|
||||
</iq>
|
||||
</PRE></LI></UL><P> <A NAME="modtime"></A> </P><!--TOC subsection <TT>mod_time</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc59">3.3.22</A>  <A HREF="#modtime"><TT>mod_time</TT></A></H3><!--SEC END --><P> <A NAME="modtime"></A>
|
||||
</P><P>This module features support for Entity Time (<A HREF="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</A>). By using this XEP,
|
||||
</P><P>This module features support for Entity Time (<A HREF="http://www.xmpp.org/extensions/xep-0202.html">XEP-0202</A>). By using this XEP,
|
||||
you are able to discover the time at another entity’s location.</P><P>Options:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
|
@ -2398,7 +2398,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modsharedroster}{\modsharedroster{}} & Shared roster management & \modroster{} or \\
|
||||
& & \modrosterodbc\\
|
||||
\hline \ahrefloc{modstats}{\modstats{}} & Statistics Gathering (\xepref{0039}) & \\
|
||||
\hline \ahrefloc{modtime}{\modtime{}} & Entity Time (\xepref{0090}) & \\
|
||||
\hline \ahrefloc{modtime}{\modtime{}} & Entity Time (\xepref{0202}) & \\
|
||||
\hline \ahrefloc{modvcard}{\modvcard{}} & vcard-temp (\xepref{0054}) & \\
|
||||
\hline \ahrefloc{modvcardldap}{\modvcardldap{}} & vcard-temp (\xepref{0054}) & LDAP server \\
|
||||
\hline \ahrefloc{modvcard}{\modvcardodbc{}} & vcard-temp (\xepref{0054}) & supported DB (*) \\
|
||||
@ -3751,9 +3751,9 @@ in order to get the statistics. Here they are:
|
||||
\end{itemize}
|
||||
|
||||
\makesubsection{modtime}{\modtime{}}
|
||||
\ind{modules!\modtime{}}\ind{protocols!XEP-0090: Entity Time}
|
||||
\ind{modules!\modtime{}}\ind{protocols!XEP-0202: Entity Time}
|
||||
|
||||
This module features support for Entity Time (\xepref{0090}). By using this XEP,
|
||||
This module features support for Entity Time (\xepref{0202}). By using this XEP,
|
||||
you are able to discover the time at another entity's location.
|
||||
|
||||
Options:
|
||||
|
@ -131,7 +131,14 @@ export_offline(Server, Output) ->
|
||||
NewPacket = {xmlelement, Name, Attrs2,
|
||||
Els ++
|
||||
[jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(TimeStamp))]},
|
||||
calendar:now_to_universal_time(TimeStamp),
|
||||
utc,
|
||||
jlib:make_jid("", Server, ""),
|
||||
"Offline Storage"),
|
||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
TimeStamp))]},
|
||||
XML =
|
||||
ejabberd_odbc:escape(
|
||||
lists:flatten(
|
||||
|
39
src/jlib.erl
39
src/jlib.erl
@ -55,8 +55,10 @@
|
||||
is_iq_request_type/1,
|
||||
iq_to_xml/1,
|
||||
parse_xdata_submit/1,
|
||||
timestamp_to_iso/1,
|
||||
timestamp_to_xml/1,
|
||||
timestamp_to_iso/1, % TODO: Remove once XEP-0091 is Obsolete
|
||||
timestamp_to_iso/2,
|
||||
timestamp_to_xml/4,
|
||||
timestamp_to_xml/1, % TODO: Remove once XEP-0091 is Obsolete
|
||||
now_to_utc_string/1,
|
||||
now_to_local_string/1,
|
||||
datetime_string_to_timestamp/1,
|
||||
@ -553,14 +555,45 @@ rsm_encode_count(Count, Arr)->
|
||||
i2l(I) when is_integer(I) -> integer_to_list(I);
|
||||
i2l(L) when is_list(L) -> L.
|
||||
|
||||
%% Timezone = utc | {Hours, Minutes}
|
||||
%% Hours = integer()
|
||||
%% Minutes = integer()
|
||||
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}, Timezone) ->
|
||||
Timestamp_string =
|
||||
lists:flatten(
|
||||
io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w",
|
||||
[Year, Month, Day, Hour, Minute, Second])),
|
||||
Timezone_string =
|
||||
case Timezone of
|
||||
utc -> "Z";
|
||||
{TZh, TZm} ->
|
||||
Sign = case TZh >= 0 of
|
||||
true -> "+";
|
||||
false -> "-"
|
||||
end,
|
||||
io_lib:format("~s~2..0w:~2..0w", [Sign, abs(TZh),TZm])
|
||||
end,
|
||||
{Timestamp_string, Timezone_string}.
|
||||
|
||||
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||
lists:flatten(
|
||||
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
||||
[Year, Month, Day, Hour, Minute, Second])).
|
||||
|
||||
timestamp_to_xml(DateTime, Timezone, FromJID, Desc) ->
|
||||
{T_string, Tz_string} = timestamp_to_iso(DateTime, Timezone),
|
||||
Text = [{xmlcdata, Desc}],
|
||||
From = jlib:jid_to_string(FromJID),
|
||||
{xmlelement, "delay",
|
||||
[{"xmlns", ?NS_DELAY},
|
||||
{"from", From},
|
||||
{"stamp", T_string ++ Tz_string}],
|
||||
Text}.
|
||||
|
||||
%% TODO: Remove this function once XEP-0091 is Obsolete
|
||||
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
|
||||
{xmlelement, "x",
|
||||
[{"xmlns", ?NS_DELAY},
|
||||
[{"xmlns", ?NS_DELAY91},
|
||||
{"stamp", lists:flatten(
|
||||
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
|
||||
[Year, Month, Day, Hour, Minute, Second]))}],
|
||||
|
@ -30,11 +30,13 @@
|
||||
-define(NS_PRIVACY, "jabber:iq:privacy").
|
||||
-define(NS_PRIVATE, "jabber:iq:private").
|
||||
-define(NS_VERSION, "jabber:iq:version").
|
||||
-define(NS_TIME, "jabber:iq:time").
|
||||
-define(NS_TIME90, "jabber:iq:time"). % TODO: Remove once XEP-0090 is Obsolete
|
||||
-define(NS_TIME, "urn:xmpp:time").
|
||||
-define(NS_LAST, "jabber:iq:last").
|
||||
-define(NS_XDATA, "jabber:x:data").
|
||||
-define(NS_IQDATA, "jabber:iq:data").
|
||||
-define(NS_DELAY, "jabber:x:delay").
|
||||
-define(NS_DELAY91, "jabber:x:delay"). % TODO: Remove once XEP-0091 is Obsolete
|
||||
-define(NS_DELAY, "urn:xmpp:delay").
|
||||
-define(NS_EXPIRE, "jabber:x:expire").
|
||||
-define(NS_EVENT, "jabber:x:event").
|
||||
-define(NS_XCONFERENCE, "jabber:x:conference").
|
||||
@ -71,6 +73,7 @@
|
||||
-define(NS_FEATURE_IQAUTH, "http://jabber.org/features/iq-auth").
|
||||
-define(NS_FEATURE_IQREGISTER, "http://jabber.org/features/iq-register").
|
||||
-define(NS_FEATURE_COMPRESS, "http://jabber.org/features/compress").
|
||||
-define(NS_FEATURE_MSGOFFLINE, "msgoffline").
|
||||
|
||||
-define(NS_COMPRESS, "http://jabber.org/protocol/compress").
|
||||
|
||||
|
@ -546,6 +546,7 @@ handle_event({service_message, Msg}, _StateName, StateData) ->
|
||||
end,
|
||||
?DICT:to_list(StateData#state.users)),
|
||||
NSD = add_message_to_history("",
|
||||
StateData#state.jid,
|
||||
MessagePkt,
|
||||
StateData),
|
||||
{next_state, normal_state, NSD};
|
||||
@ -787,6 +788,7 @@ process_groupchat_message(From, {xmlelement, "message", Attrs, _Els} = Packet,
|
||||
?DICT:to_list(StateData#state.users)),
|
||||
NewStateData2 =
|
||||
add_message_to_history(FromNick,
|
||||
From,
|
||||
Packet,
|
||||
NewStateData1),
|
||||
{next_state, normal_state, NewStateData2};
|
||||
@ -1986,7 +1988,7 @@ lqueue_to_list(#lqueue{queue = Q1}) ->
|
||||
queue:to_list(Q1).
|
||||
|
||||
|
||||
add_message_to_history(FromNick, Packet, StateData) ->
|
||||
add_message_to_history(FromNick, FromJID, Packet, StateData) ->
|
||||
HaveSubject = case xml:get_subtag(Packet, "subject") of
|
||||
false ->
|
||||
false;
|
||||
@ -1994,8 +1996,18 @@ add_message_to_history(FromNick, Packet, StateData) ->
|
||||
true
|
||||
end,
|
||||
TimeStamp = calendar:now_to_universal_time(now()),
|
||||
%% Chatroom history is stored as XMPP packets, so
|
||||
%% the decision to include the original sender's JID or not is based on the
|
||||
%% chatroom configuration when the message was originally sent.
|
||||
%% Also, if the chatroom is anonymous, even moderators will not get the real JID
|
||||
SenderJid = case ((StateData#state.config)#config.anonymous) of
|
||||
true -> StateData#state.jid;
|
||||
false -> FromJID
|
||||
end,
|
||||
TSPacket = append_subtags(Packet,
|
||||
[jlib:timestamp_to_xml(TimeStamp)]),
|
||||
[jlib:timestamp_to_xml(TimeStamp, utc, SenderJid, ""),
|
||||
%% TODO: Delete the next line once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(TimeStamp)]),
|
||||
SPacket = jlib:replace_from_to(
|
||||
jlib:jid_replace_resource(StateData#state.jid, FromNick),
|
||||
StateData#state.jid,
|
||||
|
@ -293,6 +293,13 @@ resend_offline_messages(User, Server) ->
|
||||
{xmlelement, Name, Attrs,
|
||||
Els ++
|
||||
[jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
R#offline_msg.timestamp),
|
||||
utc,
|
||||
jlib:make_jid("", Server, ""),
|
||||
"Offline Storage"),
|
||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
R#offline_msg.timestamp))]}}
|
||||
end,
|
||||
@ -322,7 +329,14 @@ pop_offline_messages(Ls, User, Server) ->
|
||||
{xmlelement, Name, Attrs,
|
||||
Els ++
|
||||
[jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
calendar:now_to_universal_time(
|
||||
R#offline_msg.timestamp),
|
||||
utc,
|
||||
jlib:make_jid("", Server, ""),
|
||||
"Offline Storage"),
|
||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
R#offline_msg.timestamp))]}}
|
||||
end,
|
||||
lists:filter(
|
||||
|
@ -112,6 +112,13 @@ loop(Host, AccessMaxOfflineMsgs) ->
|
||||
Els ++
|
||||
[jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
M#offline_msg.timestamp),
|
||||
utc,
|
||||
jlib:make_jid("", Host, ""),
|
||||
"Offline Storage"),
|
||||
%% TODO: Delete the next three lines once XEP-0091 is Obsolete
|
||||
jlib:timestamp_to_xml(
|
||||
calendar:now_to_universal_time(
|
||||
M#offline_msg.timestamp))]},
|
||||
XML =
|
||||
ejabberd_odbc:escape(
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
-export([start/2,
|
||||
stop/1,
|
||||
process_local_iq90/3, % TODO: Remove once XEP-0090 is Obsolete
|
||||
process_local_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@ -39,13 +40,19 @@
|
||||
|
||||
start(Host, Opts) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
%% TODO: Remove the next two lines once XEP-0090 is Obsolete
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME90,
|
||||
?MODULE, process_local_iq90, IQDisc),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
|
||||
?MODULE, process_local_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
%% TODO: Remove the next line once XEP-0090 is Obsolete
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME90),
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_TIME).
|
||||
|
||||
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
%% TODO: Remove this function once XEP-0090 is Obsolete
|
||||
process_local_iq90(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
@ -53,9 +60,31 @@ process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
UTC = jlib:timestamp_to_iso(calendar:universal_time()),
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", ?NS_TIME}],
|
||||
[{"xmlns", ?NS_TIME90}],
|
||||
[{xmlelement, "utc", [],
|
||||
[{xmlcdata, UTC}]}]}]}
|
||||
end.
|
||||
|
||||
process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
|
||||
case Type of
|
||||
set ->
|
||||
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
||||
get ->
|
||||
Now = now(),
|
||||
Now_universal = calendar:now_to_universal_time(Now),
|
||||
Now_local = calendar:now_to_local_time(Now),
|
||||
{UTC, UTC_diff} = jlib:timestamp_to_iso(Now_universal, utc),
|
||||
Seconds_diff = calendar:datetime_to_gregorian_seconds(Now_local)
|
||||
- calendar:datetime_to_gregorian_seconds(Now_universal),
|
||||
{Hd, Md, _} = calendar:seconds_to_time(Seconds_diff),
|
||||
{_, TZO_diff} = jlib:timestamp_to_iso({{0, 0, 0}, {0, 0, 0}}, {Hd, Md}),
|
||||
IQ#iq{type = result,
|
||||
sub_el = [{xmlelement, "time",
|
||||
[{"xmlns", ?NS_TIME}],
|
||||
[{xmlelement, "tzo", [],
|
||||
[{xmlcdata, TZO_diff}]},
|
||||
{xmlelement, "utc", [],
|
||||
[{xmlcdata, UTC ++ UTC_diff}]}]}]}
|
||||
end.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user