aboutsummaryrefslogtreecommitdiff
path: root/src/mod_offline_odbc.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_offline_odbc.erl')
-rw-r--r--src/mod_offline_odbc.erl176
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.