diff options
Diffstat (limited to 'src/mod_offline_odbc.erl')
-rw-r--r-- | src/mod_offline_odbc.erl | 176 |
1 files changed, 160 insertions, 16 deletions
diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl index 30c0f2bb5..324ea55e1 100644 --- a/src/mod_offline_odbc.erl +++ b/src/mod_offline_odbc.erl @@ -3,8 +3,8 @@ %%% Author : Alexey Shchepin <alexey@sevcom.net> %%% Purpose : %%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@sevcom.net> -%%% Id : $Id$ %%%---------------------------------------------------------------------- + -module(mod_offline_odbc). -author('alexey@sevcom.net'). @@ -15,10 +15,14 @@ stop/1, store_packet/3, pop_offline_messages/3, - remove_user/2]). + remove_user/2, + webadmin_page/3, + webadmin_user/4]). -include("ejabberd.hrl"). -include("jlib.hrl"). +-include("web/ejabberd_http.hrl"). +-include("web/ejabberd_web_admin.hrl"). -record(offline_msg, {user, timestamp, expire, from, to, packet}). @@ -34,6 +38,10 @@ start(Host, _Opts) -> ?MODULE, remove_user, 50), ejabberd_hooks:add(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), + ejabberd_hooks:add(webadmin_page_host, Host, + ?MODULE, webadmin_page, 50), + ejabberd_hooks:add(webadmin_user, Host, + ?MODULE, webadmin_user, 50), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [Host])). @@ -98,6 +106,10 @@ stop(Host) -> ?MODULE, remove_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), + ejabberd_hooks:delete(webadmin_page_host, Host, + ?MODULE, webadmin_page, 50), + ejabberd_hooks:delete(webadmin_user, Host, + ?MODULE, webadmin_user, 50), Proc = gen_mod:get_module_proc(Host, ?PROCNAME), exit(whereis(Proc), stop), ok. @@ -180,20 +192,16 @@ find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) -> find_x_expire(TimeStamp, [El | Els]) -> case xml:get_tag_attr_s("xmlns", El) of ?NS_EXPIRE -> - case xml:get_tag_attr_s("seconds", El) of - Val -> - case catch list_to_integer(Val) of - {'EXIT', _} -> - never; - Int when Int > 0 -> - {MegaSecs, Secs, MicroSecs} = TimeStamp, - S = MegaSecs * 1000000 + Secs + Int, - MegaSecs1 = S div 1000000, - Secs1 = S rem 1000000, - {MegaSecs1, Secs1, MicroSecs}; - _ -> - never - end; + Val = xml:get_tag_attr_s("seconds", El), + case catch list_to_integer(Val) of + {'EXIT', _} -> + never; + Int when Int > 0 -> + {MegaSecs, Secs, MicroSecs} = TimeStamp, + S = MegaSecs * 1000000 + Secs + Int, + MegaSecs1 = S div 1000000, + Secs1 = S rem 1000000, + {MegaSecs1, Secs1, MicroSecs}; _ -> never end; @@ -238,3 +246,139 @@ remove_user(User, Server) -> Username = ejabberd_odbc:escape(LUser), odbc_queries:del_spool_msg(LServer, Username). + +webadmin_page(_, Host, + #request{us = _US, + path = ["user", U, "queue"], + q = Query, + lang = Lang} = _Request) -> + Res = user_queue(U, Host, Query, Lang), + {stop, Res}; + +webadmin_page(Acc, _, _) -> Acc. + +user_queue(User, Server, Query, Lang) -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + Username = ejabberd_odbc:escape(LUser), + US = {LUser, LServer}, + Res = user_queue_parse_query(Username, LServer, Query), + Msgs = case catch ejabberd_odbc:sql_query( + LServer, + ["select username, xml from spool" + " where username='", Username, "'" + " order by seq;"]) of + {selected, ["username", "xml"], Rs} -> + lists:flatmap( + fun({_, XML}) -> + case xml_stream:parse_element(XML) of + {error, _Reason} -> + []; + El -> + [El] + end + end, Rs); + _ -> + [] + end, + FMsgs = + lists:map( + fun({xmlelement, Name, Attrs, Els} = Msg) -> + ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))), + Packet = Msg, + FPacket = ejabberd_web_admin:pretty_print_xml(Packet), + ?XE("tr", + [?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]), + ?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])] + ) + end, Msgs), + [?XC("h1", io_lib:format(?T("~s's Offline Messages Queue"), + [us_to_list(US)]))] ++ + case Res of + ok -> [?CT("Submitted"), ?P]; + nothing -> [] + end ++ + [?XAE("form", [{"action", ""}, {"method", "post"}], + [?XE("table", + [?XE("thead", + [?XE("tr", + [?X("td"), + ?XCT("td", "Packet") + ])]), + ?XE("tbody", + if + FMsgs == [] -> + [?XE("tr", + [?XAC("td", [{"colspan", "4"}], " ")] + )]; + true -> + FMsgs + end + )]), + ?BR, + ?INPUTT("submit", "delete", "Delete Selected") + ])]. + +user_queue_parse_query(Username, LServer, Query) -> + case lists:keysearch("delete", 1, Query) of + {value, _} -> + Msgs = case catch ejabberd_odbc:sql_query( + LServer, + ["select xml, seq from spool" + " where username='", Username, "'" + " order by seq;"]) of + {selected, ["xml", "seq"], Rs} -> + lists:flatmap( + fun({XML, Seq}) -> + case xml_stream:parse_element(XML) of + {error, _Reason} -> + []; + El -> + [{El, Seq}] + end + end, Rs); + _ -> + [] + end, + F = fun() -> + lists:foreach( + fun({Msg, Seq}) -> + ID = jlib:encode_base64( + binary_to_list(term_to_binary(Msg))), + case lists:member({"selected", ID}, Query) of + true -> + SSeq = ejabberd_odbc:escape(Seq), + catch ejabberd_odbc:sql_query( + LServer, + ["delete from spool" + " where username='", Username, "'" + " and seq='", SSeq, "';"]); + false -> + ok + end + end, Msgs) + end, + mnesia:transaction(F), + ok; + false -> + nothing + end. + +us_to_list({User, Server}) -> + jlib:jid_to_string({User, Server, ""}). + +webadmin_user(Acc, User, Server, Lang) -> + LUser = jlib:nodeprep(User), + LServer = jlib:nameprep(Server), + Username = ejabberd_odbc:escape(LUser), + QueueLen = case catch ejabberd_odbc:sql_query( + LServer, + ["select count(*) from spool" + " where username='", Username, "';"]) of + {selected, [_], [{SCount}]} -> + SCount; + _ -> + 0 + end, + FQueueLen = [?AC("queue/", QueueLen)], + Acc ++ [?XCT("h3", "Offline Messages:")] ++ FQueueLen. |