]> granicus.if.org Git - ejabberd/commitdiff
add pubsub#purge_offline (EJAB-1186) (thanks karim)
authorChristophe Romain <chris.romain@gmail.com>
Fri, 5 Mar 2010 10:11:44 +0000 (11:11 +0100)
committerChristophe Romain <chris.romain@gmail.com>
Fri, 5 Mar 2010 10:11:44 +0000 (11:11 +0100)
14 files changed:
src/mod_pubsub/mod_pubsub.erl
src/mod_pubsub/node.template
src/mod_pubsub/node_buddy.erl
src/mod_pubsub/node_club.erl
src/mod_pubsub/node_dispatch.erl
src/mod_pubsub/node_flat.erl
src/mod_pubsub/node_flat_odbc.erl
src/mod_pubsub/node_hometree.erl
src/mod_pubsub/node_hometree_odbc.erl
src/mod_pubsub/node_mb.erl
src/mod_pubsub/node_pep.erl
src/mod_pubsub/node_pep_odbc.erl
src/mod_pubsub/node_private.erl
src/mod_pubsub/node_public.erl

index 592d11d35ae29d612fb9718c05100acbe1c010bb..f29f6a040a18d20411c4e6792b7e6948e765dfa2 100644 (file)
@@ -62,6 +62,7 @@
 -export([presence_probe/3,
         in_subscription/6,
         out_subscription/4,
+        on_user_offline/3,
         remove_user/2,
         feature_check_packet/6,
         disco_local_identity/5,
@@ -197,6 +198,7 @@ init([ServerHost, Opts]) ->
     ets:insert(gen_mod:get_module_proc(ServerHost, config), {pep_mapping, PepMapping}),
     ets:insert(gen_mod:get_module_proc(ServerHost, config), {ignore_pep_from_offline, PepOffline}),
     ets:insert(gen_mod:get_module_proc(ServerHost, config), {host, Host}),
+    ejabberd_hooks:add(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75),
     ejabberd_hooks:add(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:add(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
     ejabberd_hooks:add(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
@@ -864,6 +866,7 @@ terminate(_Reason, #state{host = Host,
        false ->
            ok
     end,
+    ejabberd_hooks:delete(sm_remove_connection_hook, ServerHost, ?MODULE, on_user_offline, 75),
     ejabberd_hooks:delete(disco_sm_identity, ServerHost, ?MODULE, disco_sm_identity, 75),
     ejabberd_hooks:delete(disco_sm_features, ServerHost, ?MODULE, disco_sm_features, 75),
     ejabberd_hooks:delete(disco_sm_items, ServerHost, ?MODULE, disco_sm_items, 75),
@@ -3313,6 +3316,7 @@ get_configure_xfields(_Type, Options, Lang, Groups) ->
      ?LISTM_CONFIG_FIELD("Roster groups allowed to subscribe", roster_groups_allowed, Groups),
      ?ALIST_CONFIG_FIELD("Specify the publisher model", publish_model,
                         [publishers, subscribers, open]),
+                ?BOOL_CONFIG_FIELD("Purge all items when the relevant publisher goes offline", purge_offline),
      ?ALIST_CONFIG_FIELD("Specify the event message type", notification_type,
                         [headline, normal]),
      ?INTEGER_CONFIG_FIELD("Max payload size in bytes", max_payload_size),
@@ -3456,6 +3460,8 @@ set_xoption(Host, [{"pubsub#send_last_published_item", [Val]} | Opts], NewOpts)
     ?SET_ALIST_XOPT(send_last_published_item, Val, [never, on_sub, on_sub_and_presence]);
 set_xoption(Host, [{"pubsub#presence_based_delivery", [Val]} | Opts], NewOpts) ->
     ?SET_BOOL_XOPT(presence_based_delivery, Val);
+set_xoption(Host, [{"pubsub#purge_offline", [Val]} | Opts], NewOpts) ->
+    ?SET_BOOL_XOPT(purge_offline, Val);
 set_xoption(Host, [{"pubsub#title", Value} | Opts], NewOpts) ->
     ?SET_STRING_XOPT(title, Value);
 set_xoption(Host, [{"pubsub#type", Value} | Opts], NewOpts) ->
@@ -3789,3 +3795,73 @@ is_feature_supported({xmlelement, "presence", _, Els}, Feature) ->
     nothing -> false;
     Caps -> lists:member(Feature ++ "+notify", mod_caps:get_features(Caps))
   end.
+
+on_user_offline(_, JID, _) ->
+  {User, Server, Resource} = jlib:jid_tolower(JID),
+  case ejabberd_sm:get_user_resources(User, Server) of
+    [] -> purge_offline({User, Server, Resource});
+    _  -> true
+  end.
+
+purge_offline({User, Server, _} = LJID) ->
+  Host = host(element(2, LJID)),
+  Plugins = plugins(Host),
+  Result =
+    lists:foldl(
+      fun(Type, {Status, Acc}) ->
+        case lists:member("retrieve-affiliations", features(Type)) of
+          false ->
+            {{error, extended_error('feature-not-implemented', unsupported, "retrieve-affiliations")}, Acc};
+          true ->
+            {result, Affiliations} = node_action(Host, Type, get_entity_affiliations, [Host, LJID]),
+            {Status, [Affiliations|Acc]}
+        end
+      end,
+        {ok, []}, Plugins),
+  case Result of
+    {ok, Affiliations} ->
+      lists:foreach(
+        fun({#pubsub_node{nodeid = {_, NodeId}, options = Options, type = Type, id = NodeIdx}, Affiliation})
+             when Affiliation == 'owner' orelse Affiliation == 'publisher' ->
+               Action = fun(#pubsub_node{type = Type, id = NodeId}) ->
+                 node_call(Type, get_items, [NodeId, service_jid(Host)])
+               end,
+               case transaction(Host, NodeId, Action, sync_dirty) of
+                 {result, {_, []}}    -> true;
+                 {result, {_, Items}} ->
+                   Features = features(Type),
+                   case
+                     {lists:member("retract-items", Features),
+                      lists:member("persistent-items", Features),
+                      get_option(Options, persist_items),
+                      get_option(Options, purge_offline)}
+                   of
+                     {true, true, true, true} ->
+                       ForceNotify = get_option(Options, notify_retract),
+                       lists:foreach(
+                         fun(#pubsub_item{itemid = {ItemId, _}, modification = {_, Modification}}) ->
+                           case Modification of
+                             {User, Server, _} ->
+                               delete_item(Host, NodeId, LJID, ItemId, ForceNotify);
+                             _ ->
+                               true
+                           end;
+                            (_) ->
+                              true
+                         end,
+                           Items);
+                     _ ->
+                       true
+                   end;
+                 Error ->
+                   Error
+               end
+           end;
+           (_) ->
+              true
+        end, lists:usort(lists:flatten(Affiliations)));
+    {Error, _} ->
+      ?DEBUG("on_user_offline ~p", [Error])
+  end,
+  ok.
+
index 03bb03a0c3d9148edf2397371c553a1d494b9d3a..0c5555131ee2553fd1059cd998a3a2c4589872b0 100644 (file)
@@ -82,6 +82,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index f7608a92bd9977c31e4c4c5c6c59f5f76c9adc10..315dd01e20eab36828ee3cda38c21a6c6adc75f9 100644 (file)
@@ -85,6 +85,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index d76d73f642b78b9d900d89a538f28927e7328fab..6e71c5b1526d11ddee32a90d67a648006e28dd3d 100644 (file)
@@ -85,6 +85,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 87b2caec8cdad341a20140a97a4fa356e26c8e07..ed6bf85ae46d2b48e597031ab195923a8a2f1dcc 100644 (file)
@@ -83,6 +83,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index f3d7d4bcee5f471f27eeac2bc5c99b2782698bdc..5b0bcde060381b9c4094a6378ac946e78315d68d 100644 (file)
@@ -76,6 +76,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index b3e331349a990c6a01d462cabfb3bf5eb9b29570..a255e9b0dbb89cd2af32eaf30533ddf850bfe11b 100644 (file)
@@ -81,6 +81,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 740b2f5ff4eb6c21f048acfaeecc5f6275b53681..69deef211ef1bb2ad04141f6110d6ebbcbb018ac 100644 (file)
@@ -139,6 +139,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 8f024f6b78d804dc429681444cc69ff23c263cd3..a3618b78cea8d072bd93c141d2b885cd4032b8d1 100644 (file)
@@ -143,6 +143,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index ef64418aa0ea2781b58be91276ebb6e2645bb4ae..4a8be3f0b470f49d2ec42d87cdc9a31b79a24f17 100644 (file)
@@ -88,6 +88,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, false},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 103fffc492f3749c8d0cf2b4cebb2d9cc3fff7ec..0f406296d8df0b7e24827a63d72b4086cdf0409e 100644 (file)
@@ -83,6 +83,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, false},
+     {purge_offline, false},
      {persist_items, false},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index f39b4e11f876d2b5f2b013a7a7b35db7fb56c94e..9f0071bbcd3db97d2e5c4dc8b0e290a2699a63d7 100644 (file)
@@ -91,6 +91,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, false},
+     {purge_offline, false},
      {persist_items, false},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 4e3cb0bad04b47afd31affe9fc1456ae718b5fa9..1ba0bc3d5763c9d3b1e8e2726870ebde75cc71ec 100644 (file)
@@ -85,6 +85,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},
index 6013c0ba44995f566fd83d1bbc4093794915bbab..c8895dd15456b5bc6614050e0034f1c03b8705a9 100644 (file)
@@ -85,6 +85,7 @@ options() ->
      {notify_config, false},
      {notify_delete, false},
      {notify_retract, true},
+     {purge_offline, false},
      {persist_items, true},
      {max_items, ?MAXITEMS},
      {subscribe, true},