From 4f0cd053c4e9227495c48afc7b73b52eee3bc057 Mon Sep 17 00:00:00 2001 From: Badlop Date: Tue, 30 Jun 2009 19:32:22 +0000 Subject: [PATCH] Support XEP-0085 Chat State Notifications (EJAB-961) SVN Revision: 2350 --- src/jlib.hrl | 1 + src/mod_offline.erl | 37 +++++++++++++++++++++++++------------ src/mod_offline_odbc.erl | 39 ++++++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/jlib.hrl b/src/jlib.hrl index 0a01a7b75..32765e08a 100644 --- a/src/jlib.hrl +++ b/src/jlib.hrl @@ -39,6 +39,7 @@ -define(NS_DELAY, "urn:xmpp:delay"). -define(NS_EXPIRE, "jabber:x:expire"). -define(NS_EVENT, "jabber:x:event"). +-define(NS_CHATSTATES, "http://jabber.org/protocol/chatstates"). -define(NS_XCONFERENCE, "jabber:x:conference"). -define(NS_STATS, "http://jabber.org/protocol/stats"). -define(NS_MUC, "http://jabber.org/protocol/muc"). diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 9c375997a..78c3b2eca 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -181,7 +181,7 @@ store_packet(From, To, Packet) -> if (Type /= "error") and (Type /= "groupchat") and (Type /= "headline") -> - case check_event(From, To, Packet) of + case check_event_chatstates(From, To, Packet) of true -> #jid{luser = LUser, lserver = LServer} = To, TimeStamp = now(), @@ -202,12 +202,22 @@ store_packet(From, To, Packet) -> ok end. -check_event(From, To, Packet) -> +%% Check if the packet has any content about XEP-0022 or XEP-0085 +check_event_chatstates(From, To, Packet) -> {xmlelement, Name, Attrs, Els} = Packet, - case find_x_event(Els) of - false -> + case find_x_event_chatstates(Els, {false, false, false}) of + %% There wasn't any x:event or chatstates subelements + {false, false, _} -> true; - El -> + %% There a chatstates subelement and other stuff, but no x:event + {false, CEl, true} when CEl /= false -> + true; + %% There was only a subelement: a chatstates + {false, CEl, false} when CEl /= false -> + %% Don't allow offline storage + false; + %% There was an x:event element, and maybe also other stuff + {El, _, _} when El /= false -> case xml:get_subtag(El, "id") of false -> case xml:get_subtag(El, "offline") of @@ -235,16 +245,19 @@ check_event(From, To, Packet) -> end end. -find_x_event([]) -> - false; -find_x_event([{xmlcdata, _} | Els]) -> - find_x_event(Els); -find_x_event([El | Els]) -> +%% Check if the packet has subelements about XEP-0022, XEP-0085 or other +find_x_event_chatstates([], Res) -> + Res; +find_x_event_chatstates([{xmlcdata, _} | Els], Res) -> + find_x_event_chatstates(Els, Res); +find_x_event_chatstates([El | Els], {A, B, C}) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EVENT -> - El; + find_x_event_chatstates(Els, {El, B, C}); + ?NS_CHATSTATES -> + find_x_event_chatstates(Els, {A, El, C}); _ -> - find_x_event(Els) + find_x_event_chatstates(Els, {A, B, true}) end. find_x_expire(_, []) -> diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl index 891ec6419..d7bbd3bf3 100644 --- a/src/mod_offline_odbc.erl +++ b/src/mod_offline_odbc.erl @@ -199,7 +199,7 @@ store_packet(From, To, Packet) -> if (Type /= "error") and (Type /= "groupchat") and (Type /= "headline") -> - case check_event(From, To, Packet) of + case check_event_chatstates(From, To, Packet) of true -> #jid{luser = LUser} = To, TimeStamp = now(), @@ -220,12 +220,22 @@ store_packet(From, To, Packet) -> ok end. -check_event(From, To, Packet) -> +%% Check if the packet has any content about XEP-0022 or XEP-0085 +check_event_chatstates(From, To, Packet) -> {xmlelement, Name, Attrs, Els} = Packet, - case find_x_event(Els) of - false -> + case find_x_event_chatstates(Els, {false, false, false}) of + %% There wasn't any x:event or chatstates subelements + {false, false, _} -> true; - El -> + %% There a chatstates subelement and other stuff, but no x:event + {false, CEl, true} when CEl /= false -> + true; + %% There was only a subelement: a chatstates + {false, CEl, false} when CEl /= false -> + %% Don't allow offline storage + false; + %% There was an x:event element, and maybe also other stuff + {El, _, _} when El /= false -> case xml:get_subtag(El, "id") of false -> case xml:get_subtag(El, "offline") of @@ -247,22 +257,25 @@ check_event(From, To, Packet) -> {xmlelement, "offline", [], []}]}] }), true - end; + end; _ -> false end end. -find_x_event([]) -> - false; -find_x_event([{xmlcdata, _} | Els]) -> - find_x_event(Els); -find_x_event([El | Els]) -> +%% Check if the packet has subelements about XEP-0022, XEP-0085 or other +find_x_event_chatstates([], Res) -> + Res; +find_x_event_chatstates([{xmlcdata, _} | Els], Res) -> + find_x_event_chatstates(Els, Res); +find_x_event_chatstates([El | Els], {A, B, C}) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EVENT -> - El; + find_x_event_chatstates(Els, {El, B, C}); + ?NS_CHATSTATES -> + find_x_event_chatstates(Els, {A, El, C}); _ -> - find_x_event(Els) + find_x_event_chatstates(Els, {A, B, true}) end. find_x_expire(_, []) ->