%%%---------------------------------------------------------------------- %%% File : mod_offline.erl %%% Author : Alexey Shchepin %%% Purpose : %%% Created : 5 Jan 2003 by Alexey Shchepin %%%---------------------------------------------------------------------- -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.