mod_storage_*: Don't explicitly set driver name, to ease copying/renaming modules.
[prosody.git] / plugins / mod_message.lua
index 048a578dc1b2c9cbbdb8d9cd49e35bf609ab2c96..0b0ad8e4985a2a5d4d057081a208b8bd98325b60 100644 (file)
@@ -1,3 +1,11 @@
+-- Prosody IM
+-- Copyright (C) 2008-2010 Matthew Wild
+-- Copyright (C) 2008-2010 Waqas Hussain
+-- 
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
 
 local full_sessions = full_sessions;
 local bare_sessions = bare_sessions;
@@ -6,26 +14,6 @@ local st = require "util.stanza";
 local jid_bare = require "util.jid".bare;
 local jid_split = require "util.jid".split;
 local user_exists = require "core.usermanager".user_exists;
-local offlinemanager = require "core.offlinemanager";
-local t_insert = table.insert;
-
-local function select_top_resources(user)
-       local priority = 0;
-       local recipients = {};
-       for _, session in pairs(user.sessions) do -- find resource with greatest priority
-               if session.presence then
-                       -- TODO check active privacy list for session
-                       local p = session.priority;
-                       if p > priority then
-                               priority = p;
-                               recipients = {session};
-                       elseif p == priority then
-                               t_insert(recipients, session);
-                       end
-               end
-       end
-       return recipients;
-end
 
 local function process_to_bare(bare, origin, stanza)
        local user = bare_sessions[bare];
@@ -36,7 +24,7 @@ local function process_to_bare(bare, origin, stanza)
        elseif t == "groupchat" then
                origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
        elseif t == "headline" then
-               if user then
+               if user and stanza.attr.to == bare then
                        for _, session in pairs(user.sessions) do
                                if session.presence and session.priority >= 0 then
                                        session.send(stanza);
@@ -45,20 +33,30 @@ local function process_to_bare(bare, origin, stanza)
                end  -- current policy is to discard headlines if no recipient is available
        else -- chat or normal message
                if user then -- some resources are connected
-                       local recipients = select_top_resources(user);
-                       if #recipients > 0 then
+                       local recipients = user.top_resources;
+                       if recipients then
+                               local sent;
                                for i=1,#recipients do
-                                       recipients[i].send(stanza);
+                                       sent = recipients[i].send(stanza) or sent;
+                               end
+                               if sent then
+                                       return true;
                                end
-                               return true;
                        end
                end
                -- no resources are online
                local node, host = jid_split(bare);
+               local ok
                if user_exists(node, host) then
                        -- TODO apply the default privacy list
-                       offlinemanager.store(node, host, stanza);
-               else
+
+                       ok = module:fire_event('message/offline/handle', {
+                           origin = origin,
+                           stanza = stanza,
+                       });
+               end
+
+               if not ok then
                        origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
                end
        end
@@ -70,9 +68,7 @@ module:hook("message/full", function(data)
        local origin, stanza = data.origin, data.stanza;
        
        local session = full_sessions[stanza.attr.to];
-       if session then
-               -- TODO fire post processing event
-               session.send(stanza);
+       if session and session.send(stanza) then
                return true;
        else -- resource not online
                return process_to_bare(jid_bare(stanza.attr.to), origin, stanza);
@@ -85,3 +81,5 @@ module:hook("message/bare", function(data)
 
        return process_to_bare(stanza.attr.to or (origin.username..'@'..origin.host), origin, stanza);
 end);
+
+module:add_feature("msgoffline");