Add XEP82 Date Time, update XEP202 Entity Time and XEP203 Delayed Delivery (EJAB-234)

SVN Revision: 2345
This commit is contained in:
Badlop 2009-06-30 16:51:25 +00:00
parent f145a32b79
commit 49688feaf2
9 changed files with 121 additions and 16 deletions

View File

@ -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>&nbsp;</TD><TD ALIGN=left NOWRAP>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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:
&lt;/iq&gt;
</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>&#XA0;&#XA0;<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&#X2019;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

View File

@ -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:

View File

@ -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(

View File

@ -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]))}],

View File

@ -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").

View File

@ -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,

View File

@ -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(

View File

@ -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(

View File

@ -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.