summaryrefslogtreecommitdiff
path: root/Presence/main.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2013-06-19 00:14:48 -0400
committerjoe <joe@jerkface.net>2013-06-19 00:14:48 -0400
commit2a2126403c681e498c7980043fd18e9e904eae30 (patch)
treedde59d1c1f49465751132484608879e9182cfe47 /Presence/main.hs
parent31aee2ac1bf2eb4ad1b2725659f6e6695c2f84d3 (diff)
presence subscription API
Diffstat (limited to 'Presence/main.hs')
-rw-r--r--Presence/main.hs63
1 files changed, 31 insertions, 32 deletions
diff --git a/Presence/main.hs b/Presence/main.hs
index 4168feca..78ca4363 100644
--- a/Presence/main.hs
+++ b/Presence/main.hs
@@ -37,7 +37,6 @@ import Data.Map as Map (Map)
37 37
38import Control.Concurrent.STM 38import Control.Concurrent.STM
39import Control.Concurrent (threadDelay) 39import Control.Concurrent (threadDelay)
40import Control.DeepSeq
41import Control.Monad.Trans.Maybe 40import Control.Monad.Trans.Maybe
42import Control.Monad.IO.Class 41import Control.Monad.IO.Class
43 42
@@ -48,34 +47,20 @@ import qualified Prelude
48import Prelude hiding (putStrLn) 47import Prelude hiding (putStrLn)
49 48
50 49
51-- | Jabber ID (JID) datatype
52data JID = JID { name :: Maybe ByteString
53 , server :: ByteString
54 , resource :: Maybe ByteString
55 }
56 deriving (Ord,Eq)
57
58instance Show JID where
59 show (JID n s r ) = L.unpack $ fmap (<++>"@") n <?++> s <++?> fmap ("/"<++>) r
60
61instance NFData JID where
62 rnf v@(JID n s r) = n `seq` s `seq` r `seq` ()
63
64jid user host rsrc = JID (Just user) host (Just rsrc)
65
66data UnixSession = UnixSession { 50data UnixSession = UnixSession {
67 unix_uid :: (IORef (Maybe UserID)), 51 unix_uid :: (IORef (Maybe UserID)),
68 unix_resource :: (IORef (Maybe L.ByteString)) 52 unix_resource :: (IORef (Maybe L.ByteString)),
53 presence_state :: PresenceState
69} 54}
70 55
71instance XMPPSession UnixSession where 56instance XMPPSession UnixSession where
72 data XMPPClass UnixSession = UnixSessions 57 data XMPPClass UnixSession = UnixSessions PresenceState
73 newSession _ sock handle = do 58 newSession (UnixSessions state) sock handle = do
74 muid <- getLocalPeerCred sock 59 muid <- getLocalPeerCred sock
75 L.putStrLn $ "SESSION: open " <++> bshow muid 60 L.putStrLn $ "SESSION: open " <++> bshow muid
76 uid_ref <- newIORef muid 61 uid_ref <- newIORef muid
77 res_ref <- newIORef Nothing 62 res_ref <- newIORef Nothing
78 return $ UnixSession uid_ref res_ref 63 return $ UnixSession uid_ref res_ref state
79 setResource s resource = do 64 setResource s resource = do
80 writeIORef (unix_resource s) (Just resource) 65 writeIORef (unix_resource s) (Just resource)
81 L.putStrLn $ "SESSION: resource " <++> resource 66 L.putStrLn $ "SESSION: resource " <++> resource
@@ -97,17 +82,31 @@ instance XMPPSession UnixSession where
97 L.putStrLn $ "SESSION: jid " <++> jid 82 L.putStrLn $ "SESSION: jid " <++> jid
98 return jid 83 return jid
99 closeSession _ = L.putStrLn "SESSION: close" 84 closeSession _ = L.putStrLn "SESSION: close"
100 85 subscribeToPresence session Nothing = do
101data JabberShow = Offline 86 let tmvar = greedySubscriber (presence_state session)
102 | Away 87 chan <- atomically $
103 | Available 88 (do (cnt,chan) <- takeTMVar tmvar
104 deriving (Show,Enum,Ord,Eq,Read) 89 putTMVar tmvar (cnt+1,chan)
105 90 return chan )
106data Presence = Presence JID JabberShow 91 `orElse`
107type MaybePresence = Maybe Presence 92 (do chan <- newTChan
108 93 putTMVar tmvar (1,chan)
109instance NFData Presence where 94 return chan )
110 rnf (Presence jid stat) = rnf jid `seq` stat `seq` () 95 return chan
96 subscribeToPresence session (Just jid) = do
97 let tvar = subscriberMap (presence_state session)
98 atomically $ do
99 subs <- readTVar tvar
100 let mbchan = Map.lookup jid subs
101 (chan,subs') <-
102 do case mbchan of
103 Nothing -> do
104 newchan <- newTChan
105 return (newchan, Map.insert jid (1,newchan) subs)
106 Just (cnt,chan) -> do
107 return (chan, Map.insert jid (cnt+1,chan) subs)
108 writeTVar tvar subs'
109 return chan
111 110
112matchResource tty jid = maybe Away (avail . (==tty)) $ resource jid 111matchResource tty jid = maybe Away (avail . (==tty)) $ resource jid
113 where 112 where
@@ -196,7 +195,7 @@ start = do
196 utmp_file 195 utmp_file
197 dologin 196 dologin
198#endif 197#endif
199 sock <- listenForXmppClients UnixSessions 5222 HNil 198 sock <- listenForXmppClients (UnixSessions tracked) 5222 HNil
200 199
201 threadDelay 1000 -- wait a moment to obtain current tty 200 threadDelay 1000 -- wait a moment to obtain current tty
202 dologin () 201 dologin ()