summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-07-20 20:08:12 -0400
committerjoe <joe@jerkface.net>2013-07-20 20:08:12 -0400
commit91f6d5730f0ceff2d640360e27be77101b425d3b (patch)
treeace67e37a5bec949ae4331aba695b06fd6d5bdfc
parentf48e0689821cb202c7b6c380ec5b75dd1b13ba93 (diff)
Progress toward respecting client's requeseted presence state.
-rw-r--r--Presence/XMPP.hs25
-rw-r--r--Presence/XMPPTypes.hs1
-rw-r--r--Presence/main.hs17
3 files changed, 40 insertions, 3 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index fb7d4204..756d300a 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -359,6 +359,28 @@ handleIQGet session cmdChan tag = do
359 req -> unhandledGet req 359 req -> unhandledGet req
360 360
361 361
362handleClientPresence session stanza = do
363 -- online (Available or Away)
364 let log = liftIO . debugL . ("(C) " <++>)
365 withJust (lookupAttrib "from" (tagAttrs stanza)) $ \jid -> do
366 -- cjid <- liftIO $ parseAddressJID (textToByteString jid)
367 let parseChildren stat = do
368 child <- nextElement
369 case child of
370 Just tag | tagName tag=="{jabber:server}show"
371 -> fmap toStat (lift content)
372 Just tag | otherwise -> parseChildren stat
373 Nothing -> return stat
374 toStat "away" = Away
375 toStat "xa" = ExtendedAway
376 toStat "dnd" = DoNotDisturb
377 toStat "chat" = Chatty
378
379 stat' <- parseChildren Available
380 liftIO $ setPresence session stat'
381 log $ "requesting presence: "<++>bshow stat'
382 return ()
383
362fromClient :: (MonadThrow m,MonadIO m, JabberClientSession session) => 384fromClient :: (MonadThrow m,MonadIO m, JabberClientSession session) =>
363 session -> TChan ClientCommands -> Sink XML.Event m () 385 session -> TChan ClientCommands -> Sink XML.Event m ()
364fromClient session cmdChan = doNestingXML $ do 386fromClient session cmdChan = doNestingXML $ do
@@ -395,6 +417,8 @@ fromClient session cmdChan = doNestingXML $ do
395 -> clientApprovesSubscription session stanza 417 -> clientApprovesSubscription session stanza
396 _ | stanza `isClientPresenceOf` presenceTypeUnsubscribed 418 _ | stanza `isClientPresenceOf` presenceTypeUnsubscribed
397 -> clientRejectsSubscription session stanza 419 -> clientRejectsSubscription session stanza
420 _ | stanza `isClientPresenceOf` presenceTypeOnline
421 -> handleClientPresence session stanza
398 _ | otherwise -> unhandledStanza 422 _ | otherwise -> unhandledStanza
399 423
400 awaitCloser stanza_lvl 424 awaitCloser stanza_lvl
@@ -672,6 +696,7 @@ isClientPresenceOf (EventBeginElement name attrs) testType
672 = True 696 = True
673isClientPresenceOf _ _ = False 697isClientPresenceOf _ _ = False
674 698
699
675handlePresenceProbe session stanza = do 700handlePresenceProbe session stanza = do
676 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do 701 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to -> do
677 -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do 702 -- withJust (lookupAttrib "from" (tagAttrs stanza)) $ \from -> do
diff --git a/Presence/XMPPTypes.hs b/Presence/XMPPTypes.hs
index e0b83a6c..b654b320 100644
--- a/Presence/XMPPTypes.hs
+++ b/Presence/XMPPTypes.hs
@@ -55,6 +55,7 @@ class JabberClientSession session where
55 data XMPPClass session 55 data XMPPClass session
56 newSession :: SocketLike sock => XMPPClass session -> sock -> IO session 56 newSession :: SocketLike sock => XMPPClass session -> sock -> IO session
57 setResource :: session -> ByteString -> IO () 57 setResource :: session -> ByteString -> IO ()
58 setPresence :: session -> JabberShow -> IO ()
58 getJID :: session -> IO JID 59 getJID :: session -> IO JID
59 closeSession :: session -> IO () 60 closeSession :: session -> IO ()
60 subscribe :: session -> Maybe JID -> IO (TChan Presence) 61 subscribe :: session -> Maybe JID -> IO (TChan Presence)
diff --git a/Presence/main.hs b/Presence/main.hs
index f51e6975..5de660b0 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -55,7 +55,7 @@ import Network.Socket (Family(AF_INET,AF_INET6))
55import Holumbus.Data.MultiMap as MM (MultiMap) 55import Holumbus.Data.MultiMap as MM (MultiMap)
56import qualified Holumbus.Data.MultiMap as MM 56import qualified Holumbus.Data.MultiMap as MM
57 57
58data Client = Client 58data Client = Client { clientShow :: JabberShow }
59 59
60-- see Data.Map.Lazy.fromSet 60-- see Data.Map.Lazy.fromSet
61fromSet f = Map.fromList . map (\a -> (a,f a)) . Set.toList 61fromSet f = Map.fromList . map (\a -> (a,f a)) . Set.toList
@@ -79,7 +79,7 @@ data PresenceState = PresenceState
79 79
80 -- activeUsers - a is a set of triples representing data in /var/run/utmp 80 -- activeUsers - a is a set of triples representing data in /var/run/utmp
81 -- it is kept up to date by an inotify watch on that file. 81 -- it is kept up to date by an inotify watch on that file.
82 , activeUsers :: TVar (Map (UserName, Tty) (ProcessID, Set Client)) 82 , activeUsers :: TVar (Map (UserName, Tty) (ProcessID, Map ProcessID Client))
83 83
84 -- subscriberMap - the idea was to allow subscribing to a particular user only. 84 -- subscriberMap - the idea was to allow subscribing to a particular user only.
85 -- When that user becomes present, an announcement would be sent 85 -- When that user becomes present, an announcement would be sent
@@ -186,6 +186,17 @@ instance JabberClientSession ClientSession where
186 writeIORef (unix_resource s) (Just rsc') 186 writeIORef (unix_resource s) (Just rsc')
187 debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")" 187 debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")"
188 188
189 setPresence s stat = do
190 user <- readIORef (unix_uid s) >>= getJabberUserForId
191 withJust (unix_pid s) $ \client_pid -> do
192 whenJust (readIORef (unix_resource s)) $ \tty -> do
193 let au = activeUsers . presence_state $ s
194 atomically $ do
195 us <- readTVar au
196 withJust (Map.lookup (user,tty) us) $ \(ttypid,cs) -> do
197 let entry = (ttypid,Map.insert client_pid (Client {clientShow=stat}) cs)
198 writeTVar au (Map.insert (user,tty) entry us)
199
189 getJID s = do 200 getJID s = do
190 let host = localhost s 201 let host = localhost s
191 user <- readIORef (unix_uid s) >>= getJabberUserForId 202 user <- readIORef (unix_uid s) >>= getJabberUserForId
@@ -668,7 +679,7 @@ track_login host state e = do
668 else Nothing 679 else Nothing
669 new_users0 = mapMaybe (toJabberId host) us 680 new_users0 = mapMaybe (toJabberId host) us
670 new_users' = Map.fromList 681 new_users' = Map.fromList
671 . map (\((u,tty),pid)-> ((u,tty),(pid,Set.empty))) 682 . map (\((u,tty),pid)-> ((u,tty),(pid,Map.empty)))
672 $ new_users0 683 $ new_users0
673 (Set.fromList->new_users,_) = unzip new_users0 684 (Set.fromList->new_users,_) = unzip new_users0
674 (tty,known_users,subs,locals_greedy) <- atomically $ do 685 (tty,known_users,subs,locals_greedy) <- atomically $ do