diff options
Diffstat (limited to 'src/mod_offline.erl')
-rw-r--r-- | src/mod_offline.erl | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/mod_offline.erl b/src/mod_offline.erl new file mode 100644 index 000000000..e6d340f10 --- /dev/null +++ b/src/mod_offline.erl @@ -0,0 +1,112 @@ +%%%---------------------------------------------------------------------- +%%% File : mod_offline.erl +%%% Author : Alexey Shchepin <alexey@sevcom.net> +%%% Purpose : +%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@sevcom.net> +%%%---------------------------------------------------------------------- + +-module(mod_offline). +-author('alexey@sevcom.net'). + +-export([start/0, + store_packet/3, + resend_offline_messages/1]). + +-include("namespaces.hrl"). + +-record(offline_msg, {user, timestamp, from, to, packet}). + + +start() -> + mnesia:create_table(offline_msg, + [{disc_only_copies, [node()]}, + {type, bag}, + {attributes, record_info(fields, offline_msg)}]). + + +store_packet(From, To, Packet) -> + case check_event(From, To, Packet) of + true -> + {User, Server, Resource} = To, + LUser = jlib:tolower(User), + TimeStamp = calendar:universal_time(), + F = fun() -> + mnesia:write(#offline_msg{user = LUser, + timestamp = TimeStamp, + from = From, + to = To, + packet = Packet}) + end, + mnesia:transaction(F); + _ -> + ok + end. + +check_event(From, To, Packet) -> + {xmlelement, Name, Attrs, Els} = Packet, + case find_x_event(Els) of + false -> + true; + El -> + case xml:get_subtag(El, "id") of + false -> + case xml:get_subtag(El, "offline") of + false -> + true; + _ -> + ID = case xml:get_tag_attr_s("id", Packet) of + "" -> + {xmlelement, "id", [], []}; + S -> + {xmlelement, "id", [], + [{xmlcdata, S}]} + end, + ejabberd_router:route( + To, From, {xmlelement, Name, Attrs, + [{xmlelement, "x", + [{"xmlns", ?NS_EVENT}], + [ID, + {xmlelement, "offline", [], []}]}] + }), + true + end; + _ -> + false + end + end. + +find_x_event([]) -> + false; +find_x_event([El | Els]) -> + case xml:get_tag_attr_s("xmlns", El) of + ?NS_EVENT -> + El; + _ -> + find_x_event(Els) + end. + + +resend_offline_messages(User) -> + LUser = jlib:tolower(User), + F = fun() -> + Rs = mnesia:read({offline_msg, LUser}), + mnesia:delete({offline_msg, LUser}), + Rs + end, + case mnesia:transaction(F) of + {atomic, Rs} -> + lists:foreach( + fun(R) -> + {xmlelement, Name, Attrs, Els} = R#offline_msg.packet, + ejabberd_sm ! + {route, + R#offline_msg.from, + R#offline_msg.to, + {xmlelement, Name, Attrs, + Els ++ + [jlib:timestamp_to_xml(R#offline_msg.timestamp)]}} + end, + lists:keysort(#offline_msg.timestamp, Rs)); + _ -> + ok + end. |