Browse Source

Merge branch 'master' of github.com:pontarius/pontarius-xmpp

master
Jon Kristensen 11 years ago
parent
commit
ddfa468fe7
  1. 2
      source/Network/Xmpp/Concurrent.hs
  2. 10
      source/Network/Xmpp/Concurrent/Types.hs
  3. 2
      source/Network/Xmpp/IM.hs
  4. 4
      source/Network/Xmpp/IM/Presence.hs
  5. 30
      source/Network/Xmpp/IM/PresenceTracker.hs
  6. 2
      source/Network/Xmpp/IM/PresenceTracker/Types.hs
  7. 7
      source/Network/Xmpp/Lens.hs

2
source/Network/Xmpp/Concurrent.hs

@ -175,7 +175,7 @@ newSession stream config realm mbSasl = runErrorT $ do
then [handleRoster boundJid ros out] then [handleRoster boundJid ros out]
else [] else []
let presenceH = if (enablePresenceTracking config) let presenceH = if (enablePresenceTracking config)
then [handlePresence peers out] then [handlePresence (onPresenceChange config) peers out]
else [] else []
(sStanza, ps) <- initPlugins out $ plugins config (sStanza, ps) <- initPlugins out $ plugins config
let stanzaHandler = runHandlers $ List.concat let stanzaHandler = runHandlers $ List.concat

10
source/Network/Xmpp/Concurrent/Types.hs

@ -87,6 +87,15 @@ data SessionConfiguration = SessionConfiguration
, enableRoster :: Bool , enableRoster :: Bool
-- | Track incomming presence stancas. -- | Track incomming presence stancas.
, enablePresenceTracking :: Bool , enablePresenceTracking :: Bool
-- | Callback that is invoked when the presence status of a peer changes,
-- i.e. it comes online, goes offline or its IM presence changes. The
-- arguments are the (full) JID of the peer, the old state and the new
-- state. The function is called in a new thread to avoid blocking
-- handling stanzas
, onPresenceChange :: Maybe ( Jid
-> PeerStatus
-> PeerStatus
-> IO ())
} }
instance Default SessionConfiguration where instance Default SessionConfiguration where
@ -101,6 +110,7 @@ instance Default SessionConfiguration where
, plugins = [] , plugins = []
, enableRoster = True , enableRoster = True
, enablePresenceTracking = True , enablePresenceTracking = True
, onPresenceChange = Nothing
} }
-- | Handlers to be run when the Xmpp session ends and when the Xmpp connection is -- | Handlers to be run when the Xmpp session ends and when the Xmpp connection is

2
source/Network/Xmpp/IM.hs

@ -26,6 +26,7 @@ module Network.Xmpp.IM
, rosterAdd , rosterAdd
, rosterRemove , rosterRemove
-- * presenceTracker -- * presenceTracker
, PeerStatus(..)
, isPeerAvailable , isPeerAvailable
, getEntityStatus , getEntityStatus
, getAvailablePeers , getAvailablePeers
@ -37,3 +38,4 @@ import Network.Xmpp.IM.Presence
import Network.Xmpp.IM.Roster import Network.Xmpp.IM.Roster
import Network.Xmpp.IM.Roster.Types import Network.Xmpp.IM.Roster.Types
import Network.Xmpp.IM.PresenceTracker import Network.Xmpp.IM.PresenceTracker
import Network.Xmpp.IM.PresenceTracker.Types

4
source/Network/Xmpp/IM/Presence.hs

@ -13,12 +13,12 @@ import Network.Xmpp.Types
data ShowStatus = StatusAway data ShowStatus = StatusAway
| StatusChat | StatusChat
| StatusDnd | StatusDnd
| StatusXa deriving (Read, Show) | StatusXa deriving (Read, Show, Eq)
data IMPresence = IMP { showStatus :: Maybe ShowStatus data IMPresence = IMP { showStatus :: Maybe ShowStatus
, status :: Maybe Text , status :: Maybe Text
, priority :: Maybe Int , priority :: Maybe Int
} deriving Show } deriving (Show, Eq)
imPresence :: IMPresence imPresence :: IMPresence
imPresence = IMP { showStatus = Nothing imPresence = IMP { showStatus = Nothing

30
source/Network/Xmpp/IM/PresenceTracker.hs

@ -2,8 +2,10 @@
module Network.Xmpp.IM.PresenceTracker where module Network.Xmpp.IM.PresenceTracker where
import Control.Applicative import Control.Applicative
import Control.Concurrent
import Control.Concurrent.STM import Control.Concurrent.STM
import Data.Foldable import Control.Monad
import qualified Data.Foldable as Foldable
import Data.Map.Strict (Map) import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.Maybe import Data.Maybe
@ -57,21 +59,31 @@ peerMapPeerAvailable :: Jid -> Peers -> Bool
peerMapPeerAvailable j | isFull j = not . nullOf (peerStatusL j . _PeerAvailable) peerMapPeerAvailable j | isFull j = not . nullOf (peerStatusL j . _PeerAvailable)
| otherwise = not . nullOf (_peers . at j . _Just) | otherwise = not . nullOf (_peers . at j . _Just)
handlePresence :: TVar Peers -> StanzaHandler handlePresence :: Maybe (Jid -> PeerStatus -> PeerStatus -> IO ())
handlePresence peers _ st _ = do -> TVar Peers
-> StanzaHandler
handlePresence onChange peers _ st _ = do
let mbPr = do let mbPr = do
pr <- st ^? _Presence -- Only act on presence stanzas pr <- st ^? _Presence -- Only act on presence stanzas
fr <- pr ^? from . _Just . _isFull -- Only act on full JIDs fr <- pr ^? from . _Just . _isFull -- Only act on full JIDs
return (pr, fr) return (pr, fr)
forM_ mbPr $ \(pr, fr) -> Foldable.forM_ mbPr $ \(pr, fr) ->
case presenceType pr of case presenceType pr of
Available -> atomically . modifyTVar peers Available -> setStatus fr (PeerAvailable (getIMPresence pr))
$ set (peerStatusL fr) Unavailable -> setStatus fr PeerUnavailable
(PeerAvailable (getIMPresence pr))
Unavailable -> atomically . modifyTVar peers
$ set (peerStatusL fr) PeerUnavailable
_ -> return () _ -> return ()
return [(st, [])] return [(st, [])]
where
setStatus fr newStatus = do
os <- atomically $ do
ps <- readTVar peers
let oldStatus = ps ^. peerStatusL fr
writeTVar peers $ ps & set (peerStatusL fr) newStatus
return oldStatus
unless (os == newStatus) $ case onChange of
Nothing -> return ()
Just oc -> void . forkIO $ oc fr os newStatus
return ()
-- | Check whether a given jid is available -- | Check whether a given jid is available
isPeerAvailable :: Jid -> Session -> STM Bool isPeerAvailable :: Jid -> Session -> STM Bool

2
source/Network/Xmpp/IM/PresenceTracker/Types.hs

@ -17,4 +17,4 @@ newtype Peers = Peers { unPeers :: Map Jid (Map Jid (Maybe IMPresence))}
data PeerStatus = PeerAvailable (Maybe IMPresence) data PeerStatus = PeerAvailable (Maybe IMPresence)
| PeerUnavailable | PeerUnavailable
deriving (Show) deriving (Show, Eq)

7
source/Network/Xmpp/Lens.hs

@ -94,6 +94,7 @@ module Network.Xmpp.Lens
, sessionStanzaIDsL , sessionStanzaIDsL
, ensableRosterL , ensableRosterL
, pluginsL , pluginsL
, onPresenceChangeL
-- ** IM -- ** IM
-- *** Roster -- *** Roster
-- **** 'Roster' -- **** 'Roster'
@ -152,6 +153,7 @@ import Network.TLS as TLS
import Network.Xmpp.Concurrent.Types import Network.Xmpp.Concurrent.Types
import Network.Xmpp.IM.Message import Network.Xmpp.IM.Message
import Network.Xmpp.IM.Presence import Network.Xmpp.IM.Presence
import Network.Xmpp.IM.PresenceTracker.Types
import Network.Xmpp.IM.Roster.Types import Network.Xmpp.IM.Roster.Types
import Network.Xmpp.Types import Network.Xmpp.Types
@ -538,6 +540,11 @@ pluginsL :: Lens SessionConfiguration [Plugin]
pluginsL inj sc@SessionConfiguration{plugins = x} pluginsL inj sc@SessionConfiguration{plugins = x}
= (\x' -> sc{plugins = x'}) <$> inj x = (\x' -> sc{plugins = x'}) <$> inj x
onPresenceChangeL :: Lens SessionConfiguration (Maybe ( Jid -> PeerStatus
-> PeerStatus -> IO ()))
onPresenceChangeL inj sc@SessionConfiguration{onPresenceChange = x}
= (\x' -> sc{onPresenceChange = x'}) <$> inj x
-- | Access clientServerIdentification inside tlsParams inside streamConfiguration -- | Access clientServerIdentification inside tlsParams inside streamConfiguration
tlsServerIdentificationL :: Lens SessionConfiguration (String, BS.ByteString) tlsServerIdentificationL :: Lens SessionConfiguration (String, BS.ByteString)
tlsServerIdentificationL = streamConfigurationL tlsServerIdentificationL = streamConfigurationL

Loading…
Cancel
Save