]> granicus.if.org Git - ejabberd/commitdiff
* src/mod_offline.erl: Added function remove_old_messages/1
authorAlexey Shchepin <alexey@process-one.net>
Fri, 24 Oct 2003 19:21:07 +0000 (19:21 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Fri, 24 Oct 2003 19:21:07 +0000 (19:21 +0000)
* src/mod_last.erl: jabber:iq:last support (JEP-0012)
* src/ejabberd_sm.erl: Likewise

* src/jlib.hrl: Added NS_LAST macros

SVN Revision: 159

ChangeLog
src/ejabberd.app
src/ejabberd.cfg.example
src/ejabberd_sm.erl
src/jlib.hrl
src/mod_last.erl [new file with mode: 0644]
src/mod_offline.erl

index 56668a0b9af1998bbbd965d6c113df0e98dc01bf..2f72cee34742c79111f6e9f97010fabf8d9cc91e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-10-24  Alexey Shchepin  <alexey@sevcom.net>
+
+       * src/mod_offline.erl: Added function remove_old_messages/1
+
+       * src/mod_last.erl: jabber:iq:last support (JEP-0012)
+       * src/ejabberd_sm.erl: Likewise
+
+       * src/jlib.hrl: Added NS_LAST macros
+
 2003-10-23  Alexey Shchepin  <alexey@sevcom.net>
 
        * src/ejabberd_logger_h.erl: New error_logger handler
index 02b11118128dac9c07de9fcfb01c427ab66b5032..df772dbab6887393e56f1886e1e6c05db87f152d 100644 (file)
@@ -14,6 +14,7 @@
             ejabberd_c2s,
             ejabberd_config,
             ejabberd_listener,
+            ejabberd_logger_h,
             ejabberd_local,
             ejabberd_router,
             ejabberd_s2s,
@@ -30,6 +31,7 @@
             mod_configure,
             mod_disco,
             mod_echo,
+            mod_last,
             mod_offline,
             mod_private,
             mod_register,
index f1d915c4ebd91aafe61d2b05ffcbfcd744a732ee..0626cfce464b6fd213bcdca23bd43500a28fbf8d 100644 (file)
@@ -90,7 +90,8 @@
            {mod_irc,       []},
            {mod_muc,       []},
            {mod_pubsub,    []},
-           {mod_time,      [{iqdisc, no_queue}]},
+           {mod_time,      []},
+           {mod_last,      []},
            {mod_version,   []}
           ]}.
 
index 1e2bc204c2f03561cca06bae7be1a318cfd84c11..32c333b9e975a3e0cabb06a34304bbb50cc96357 100644 (file)
@@ -177,9 +177,9 @@ clean_table_from_bad_node(Node) ->
 do_route(From, To, Packet) ->
     ?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
           [From, To, Packet, 8]),
-    #jid{user = User, server =  Server, resource = Resource,
+    #jid{user = User, resource = Resource,
         luser = LUser, lserver = LServer, lresource = LResource} = To,
-    {xmlelement, Name, Attrs, Els} = Packet,
+    {xmlelement, Name, Attrs, _Els} = Packet,
     case Resource of
        "" ->
            case Name of
@@ -316,7 +316,7 @@ route_message(From, To, Packet) ->
 get_user_resources(User) ->
     LUser = jlib:nodeprep(User),
     case catch mnesia:dirty_index_read(session, LUser, #session.user) of
-       {'EXIT', Reason} ->
+       {'EXIT', _Reason} ->
            [];
        Rs ->
            lists:map(fun(R) ->
@@ -342,11 +342,12 @@ unset_presence(User, Resource) ->
                UR = {User, Resource},
                mnesia:delete({presence, UR})
        end,
-    mnesia:transaction(F).
+    mnesia:transaction(F),
+    catch mod_last:on_presence_update(LUser).
 
 get_user_present_resources(LUser) ->
     case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
-       {'EXIT', Reason} ->
+       {'EXIT', _Reason} ->
            [];
        Rs ->
            lists:map(fun(R) ->
@@ -366,7 +367,7 @@ dirty_get_my_sessions_list() ->
 process_iq(From, To, Packet) ->
     IQ = jlib:iq_query_info(Packet),
     case IQ of
-       {iq, ID, Type, XMLNS, SubEl} ->
+       {iq, _ID, _Type, XMLNS, _SubEl} ->
            case ets:lookup(sm_iqtable, XMLNS) of
                [{_, Module, Function}] ->
                    ResIQ = Module:Function(From, To, IQ),
index 4ca09fc3470d5035ece3c349d0e059cc414cc1a9..fdbf35daec45f904283d957a25b57f2322bfc7df 100644 (file)
@@ -17,6 +17,7 @@
 -define(NS_PRIVATE,      "jabber:iq:private").
 -define(NS_VERSION,      "jabber:iq:version").
 -define(NS_TIME,         "jabber:iq:time").
+-define(NS_LAST,         "jabber:iq:last").
 -define(NS_XDATA,        "jabber:x:data").
 -define(NS_IQDATA,       "jabber:iq:data").
 -define(NS_DELAY,        "jabber:x:delay").
diff --git a/src/mod_last.erl b/src/mod_last.erl
new file mode 100644 (file)
index 0000000..50f16fd
--- /dev/null
@@ -0,0 +1,114 @@
+%%%----------------------------------------------------------------------
+%%% File    : mod_last.erl
+%%% Author  : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose : jabber:iq:last support (JEP-0012)
+%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_last).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-behaviour(gen_mod).
+
+-export([start/1,
+        stop/0,
+        process_local_iq/3,
+        process_sm_iq/3,
+        on_presence_update/1]).
+
+-include("ejabberd.hrl").
+-include("jlib.hrl").
+
+-record(last_activity, {user, timestamp}).
+
+
+start(Opts) ->
+    IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
+    mnesia:create_table(last_activity,
+                       [{disc_copies, [node()]},
+                        {attributes, record_info(fields, last_activity)}]),
+    gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
+                                 ?MODULE, process_local_iq, IQDisc),
+    gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
+                                 ?MODULE, process_sm_iq, IQDisc).
+
+stop() ->
+    gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST).
+
+process_local_iq(_From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS,
+            [SubEl, ?ERR_NOT_ALLOWED]};
+       get ->
+           Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
+           {iq, ID, result, XMLNS,
+            [{xmlelement, "query",
+              [{"xmlns", ?NS_LAST},
+               {"seconds", integer_to_list(Sec)}],
+              []}]}
+    end.
+
+
+process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+    case Type of
+       set ->
+           {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]};
+       get ->
+           User = To#jid.luser,
+           {Subscription, _Groups} =
+               mod_roster:get_jid_info(User, From),
+           if
+               (Subscription == both) or (Subscription == from) ->
+                   case catch mod_privacy:get_user_list(User) of
+                       {'EXIT', _Reason} ->
+                           get_last(ID, XMLNS, SubEl, User);
+                       List ->
+                           case mod_privacy:check_packet(
+                                  User, List,
+                                  {From, To,
+                                   {xmlelement, "presence", [], []}},
+                                  out) of
+                               allow ->
+                                   get_last(ID, XMLNS, SubEl, User);
+                               deny ->
+                                   {iq, ID, error, XMLNS,
+                                    [SubEl, ?ERR_NOT_ALLOWED]}
+                           end
+                   end;
+               true ->
+                   {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}
+           end
+    end.
+
+get_last(ID, XMLNS, SubEl, LUser) ->
+    case catch mnesia:dirty_read(last_activity, LUser) of
+       {'EXIT', _Reason} ->
+           {iq, ID, error, XMLNS, [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
+       [] ->
+           {iq, ID, error, XMLNS, [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
+       [#last_activity{timestamp = TimeStamp}] ->
+           {MegaSecs, Secs, _MicroSecs} = now(),
+           TimeStamp2 = MegaSecs * 1000000 + Secs,
+           Sec = TimeStamp2 - TimeStamp,
+           {iq, ID, result, XMLNS,
+            [{xmlelement, "query",
+              [{"xmlns", ?NS_LAST},
+               {"seconds", integer_to_list(Sec)}],
+              []}]}
+    end.
+
+
+
+on_presence_update(LUser) ->
+    {MegaSecs, Secs, _MicroSecs} = now(),
+    TimeStamp = MegaSecs * 1000000 + Secs,
+    F = fun() ->
+               mnesia:write(#last_activity{user = LUser,
+                                           timestamp = TimeStamp})
+       end,
+    mnesia:transaction(F).
+
+
index 9462d77f07387105d8aeaea43c603637ceed7015..63537600ea824613763b3aa666214f30fbb9c056 100644 (file)
@@ -16,6 +16,7 @@
         stop/0,
         store_packet/3,
         resend_offline_messages/1,
+        remove_old_messages/1,
         remove_user/1]).
 
 -include("jlib.hrl").
@@ -150,6 +151,22 @@ resend_offline_messages(User) ->
            ok
     end.
 
+remove_old_messages(Days) ->
+    {MegaSecs, Secs, _MicroSecs} = now(),
+    S = MegaSecs * 1000000 + Secs - 60 * 60 * 24 * Days,
+    MegaSecs1 = S div 1000000,
+    Secs1 = S rem 1000000,
+    TimeStamp = {MegaSecs1, Secs1, 0},
+    F = fun() ->
+               mnesia:foldl(
+                 fun(#offline_msg{timestamp = TS} = Rec, _Acc)
+                    when TS < TimeStamp ->
+                         mnesia:delete_object(Rec);
+                    (_Rec, _Acc) -> ok
+                 end, ok, offline_msg)
+       end,
+    mnesia:transaction(F).
+
 remove_user(User) ->
     LUser = jlib:nodeprep(User),
     F = fun() ->