diff options
author | joe <joe@jerkface.net> | 2013-07-20 20:08:12 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-07-20 20:08:12 -0400 |
commit | 91f6d5730f0ceff2d640360e27be77101b425d3b (patch) | |
tree | ace67e37a5bec949ae4331aba695b06fd6d5bdfc | |
parent | f48e0689821cb202c7b6c380ec5b75dd1b13ba93 (diff) |
Progress toward respecting client's requeseted presence state.
-rw-r--r-- | Presence/XMPP.hs | 25 | ||||
-rw-r--r-- | Presence/XMPPTypes.hs | 1 | ||||
-rw-r--r-- | Presence/main.hs | 17 |
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 | ||
362 | handleClientPresence 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 | |||
362 | fromClient :: (MonadThrow m,MonadIO m, JabberClientSession session) => | 384 | fromClient :: (MonadThrow m,MonadIO m, JabberClientSession session) => |
363 | session -> TChan ClientCommands -> Sink XML.Event m () | 385 | session -> TChan ClientCommands -> Sink XML.Event m () |
364 | fromClient session cmdChan = doNestingXML $ do | 386 | fromClient 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 |
673 | isClientPresenceOf _ _ = False | 697 | isClientPresenceOf _ _ = False |
674 | 698 | ||
699 | |||
675 | handlePresenceProbe session stanza = do | 700 | handlePresenceProbe 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)) | |||
55 | import Holumbus.Data.MultiMap as MM (MultiMap) | 55 | import Holumbus.Data.MultiMap as MM (MultiMap) |
56 | import qualified Holumbus.Data.MultiMap as MM | 56 | import qualified Holumbus.Data.MultiMap as MM |
57 | 57 | ||
58 | data Client = Client | 58 | data Client = Client { clientShow :: JabberShow } |
59 | 59 | ||
60 | -- see Data.Map.Lazy.fromSet | 60 | -- see Data.Map.Lazy.fromSet |
61 | fromSet f = Map.fromList . map (\a -> (a,f a)) . Set.toList | 61 | fromSet 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 |