diff options
author | joe <joe@jerkface.net> | 2013-07-20 21:59:22 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2013-07-20 21:59:22 -0400 |
commit | e57941161715a28543794bdd346110c67f0cf224 (patch) | |
tree | 104adef89ce56521aa93100e8fb1138628f82c1c | |
parent | 91f6d5730f0ceff2d640360e27be77101b425d3b (diff) |
Now honors client's requested status.
-rw-r--r-- | Presence/main.hs | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/Presence/main.hs b/Presence/main.hs index 5de660b0..d7510f94 100644 --- a/Presence/main.hs +++ b/Presence/main.hs | |||
@@ -15,6 +15,7 @@ import Data.Maybe | |||
15 | import Data.Char | 15 | import Data.Char |
16 | import ConfigFiles | 16 | import ConfigFiles |
17 | import Control.Arrow (second) | 17 | import Control.Arrow (second) |
18 | import Data.Traversable (sequenceA) | ||
18 | 19 | ||
19 | import System.INotify | 20 | import System.INotify |
20 | #ifndef NOUTMP | 21 | #ifndef NOUTMP |
@@ -35,7 +36,7 @@ import LocalPeerCred | |||
35 | import System.Posix.User | 36 | import System.Posix.User |
36 | import Logging | 37 | import Logging |
37 | import qualified Data.Set as Set | 38 | import qualified Data.Set as Set |
38 | import Data.Set as Set (Set,(\\)) | 39 | import Data.Set as Set ((\\)) |
39 | import qualified Data.Map as Map | 40 | import qualified Data.Map as Map |
40 | import Data.Map as Map (Map) | 41 | import Data.Map as Map (Map) |
41 | 42 | ||
@@ -187,15 +188,26 @@ instance JabberClientSession ClientSession where | |||
187 | debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")" | 188 | debugL $ "CLIENT SESSION: resource " <++> rsc' <++> " (wanted: "<++>wanted_resource<++>")" |
188 | 189 | ||
189 | setPresence s stat = do | 190 | setPresence s stat = do |
190 | user <- readIORef (unix_uid s) >>= getJabberUserForId | ||
191 | withJust (unix_pid s) $ \client_pid -> do | 191 | withJust (unix_pid s) $ \client_pid -> do |
192 | whenJust (readIORef (unix_resource s)) $ \tty -> do | 192 | whenJust (readIORef (unix_resource s)) $ \tty -> do |
193 | let au = activeUsers . presence_state $ s | 193 | user <- readIORef (unix_uid s) >>= getJabberUserForId |
194 | atomically $ do | 194 | greedysubs <- atomically $ do |
195 | let au = activeUsers . presence_state $ s | ||
195 | us <- readTVar au | 196 | us <- readTVar au |
196 | withJust (Map.lookup (user,tty) us) $ \(ttypid,cs) -> do | 197 | sequenceA $ Map.lookup (user,tty) us >>= \(ttypid,cs) -> do |
197 | let entry = (ttypid,Map.insert client_pid (Client {clientShow=stat}) cs) | 198 | let entry = (ttypid,Map.insert client_pid (Client {clientShow=stat}) cs) |
198 | writeTVar au (Map.insert (user,tty) entry us) | 199 | Just $ do |
200 | writeTVar au (Map.insert (user,tty) entry us) | ||
201 | subs <- readTVar $ subscriberMap (presence_state s) | ||
202 | greedy <- fmap snd . readTMVar $ localSubscriber (presence_state s) | ||
203 | activetty <- readTVar $ currentTTY (presence_state s) | ||
204 | usermap <- readTVar $ activeUsers (presence_state s) | ||
205 | return (greedy,subs,activetty,usermap) | ||
206 | withJust greedysubs $ \(greedy,subs,active_tty,usermap) -> do | ||
207 | update_presence (Just greedy) | ||
208 | (fmap snd subs) | ||
209 | [JID (Just user) (localhost s) (Just tty)] | ||
210 | (matchResource usermap active_tty) | ||
199 | 211 | ||
200 | getJID s = do | 212 | getJID s = do |
201 | let host = localhost s | 213 | let host = localhost s |
@@ -206,12 +218,20 @@ instance JabberClientSession ClientSession where | |||
206 | -- debugL $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc) | 218 | -- debugL $ "CLIENT SESSION: jid " <++> L.show (JID (Just user) host rsc) |
207 | return (JID (Just user) host rsc) | 219 | return (JID (Just user) host rsc) |
208 | 220 | ||
209 | closeSession session = do | 221 | closeSession s = do |
210 | atomically $ do | 222 | atomically $ do |
211 | cs <- readTVar (chans session) | 223 | cs <- readTVar (chans s) |
212 | forM_ cs $ \(RefCountedChan c) -> do | 224 | forM_ cs $ \(RefCountedChan c) -> do |
213 | unsubscribeToChan c | 225 | unsubscribeToChan c |
214 | debugL "CLIENT SESSION: close" | 226 | debugL "CLIENT SESSION: close" |
227 | withJust (unix_pid s) $ \client_pid -> do | ||
228 | whenJust (readIORef (unix_resource s)) $ \tty -> do | ||
229 | user <- readIORef (unix_uid s) >>= getJabberUserForId | ||
230 | atomically $ do | ||
231 | let au = activeUsers . presence_state $ s | ||
232 | us <- readTVar au | ||
233 | let remove = second (Map.delete client_pid) | ||
234 | writeTVar au (Map.adjust remove (user,tty) us) | ||
215 | 235 | ||
216 | subscribe session Nothing = do | 236 | subscribe session Nothing = do |
217 | let tmvar = localSubscriber (presence_state session) | 237 | let tmvar = localSubscriber (presence_state session) |
@@ -616,9 +636,15 @@ unrefFromMap tvar key finalizer = do | |||
616 | subscribeToMap tvar jid = | 636 | subscribeToMap tvar jid = |
617 | getRefFromMap tvar jid newTChan dupTChan | 637 | getRefFromMap tvar jid newTChan dupTChan |
618 | 638 | ||
619 | matchResource tty jid = maybe Away (avail . (==tty)) $ resource jid | 639 | matchResource usermap tty jid = maybe Away (avail . (==tty)) $ resource jid |
620 | where | 640 | where |
621 | avail True = Available | 641 | avail True = case ( name jid >>= \u -> Map.lookup (u,tty) usermap ) of |
642 | Nothing -> Available | ||
643 | Just (pid,clients) -> | ||
644 | let stats = map (clientShow . snd) . Map.toList $ clients | ||
645 | in if null stats | ||
646 | then Available | ||
647 | else maximum stats | ||
622 | avail False = Away | 648 | avail False = Away |
623 | 649 | ||
624 | matchResource' tty (_,rsc) = avail (rsc==tty) | 650 | matchResource' tty (_,rsc) = avail (rsc==tty) |
@@ -682,32 +708,34 @@ track_login host state e = do | |||
682 | . map (\((u,tty),pid)-> ((u,tty),(pid,Map.empty))) | 708 | . map (\((u,tty),pid)-> ((u,tty),(pid,Map.empty))) |
683 | $ new_users0 | 709 | $ new_users0 |
684 | (Set.fromList->new_users,_) = unzip new_users0 | 710 | (Set.fromList->new_users,_) = unzip new_users0 |
685 | (tty,known_users,subs,locals_greedy) <- atomically $ do | 711 | (tty,active_users,subs,locals_greedy) <- atomically $ do |
686 | tty <- readTVar $ currentTTY state | 712 | tty <- readTVar $ currentTTY state |
687 | st <- flip swapTVar new_users' $ activeUsers state | 713 | st <- flip swapTVar new_users' $ activeUsers state |
688 | xs <- readTVar $ subscriberMap state | 714 | xs <- readTVar $ subscriberMap state |
689 | locals_greedy <- tryReadTMVar $ localSubscriber state | 715 | locals_greedy <- tryReadTMVar $ localSubscriber state |
690 | return (tty,Map.keysSet st,fmap snd xs,fmap snd locals_greedy) | 716 | return (tty,st,fmap snd xs,fmap snd locals_greedy) |
717 | let known_users = Map.keysSet active_users | ||
691 | let arrivals = map tupleToJID . Set.toList $ new_users \\ known_users | 718 | let arrivals = map tupleToJID . Set.toList $ new_users \\ known_users |
692 | departures = map tupleToJID . Set.toList $ known_users \\ new_users | 719 | departures = map tupleToJID . Set.toList $ known_users \\ new_users |
693 | update_presence locals_greedy subs departures $ const Offline | 720 | update_presence locals_greedy subs departures $ const Offline |
694 | update_presence locals_greedy subs arrivals $ matchResource tty | 721 | update_presence locals_greedy subs arrivals $ matchResource active_users tty |
695 | forM_ arrivals | 722 | forM_ arrivals |
696 | $ sendProbes state | 723 | $ sendProbes state |
697 | 724 | ||
698 | on_chvt state vtnum = do | 725 | on_chvt state vtnum = do |
699 | let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum) | 726 | let tty = L.snoc "tty" $ intToDigit (fromIntegral vtnum) |
700 | debugL $ "VT switch: " <++> tty | 727 | debugL $ "VT switch: " <++> tty |
701 | (users,subs,locals_greedy) <- atomically $ do | 728 | (active_users,subs,locals_greedy) <- atomically $ do |
702 | us <- readTVar $ activeUsers state | 729 | us <- readTVar $ activeUsers state |
703 | subs <- readTVar $ subscriberMap state | 730 | subs <- readTVar $ subscriberMap state |
704 | writeTVar (currentTTY state) tty | 731 | writeTVar (currentTTY state) tty |
705 | locals_greedy <- tryReadTMVar $ localSubscriber state | 732 | locals_greedy <- tryReadTMVar $ localSubscriber state |
706 | return (Map.keysSet us,fmap snd subs,fmap snd locals_greedy) | 733 | return (us,fmap snd subs,fmap snd locals_greedy) |
734 | let users = Map.keysSet active_users | ||
707 | update_presence locals_greedy | 735 | update_presence locals_greedy |
708 | subs | 736 | subs |
709 | (map tupleToJID . Set.toList $ users) | 737 | (map tupleToJID . Set.toList $ users) |
710 | $ matchResource tty | 738 | $ matchResource active_users tty |
711 | 739 | ||
712 | -- start | 740 | -- start |
713 | -- | 741 | -- |