diff options
author | joe <joe@jerkface.net> | 2018-06-22 04:44:50 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-06-22 04:44:50 -0400 |
commit | 6bbc15735f6e28740c0e05fc8219fd83a5a464a4 (patch) | |
tree | 7bfef6823a2c1d88a71ef27c0f2bb3f3600ca59a /Presence | |
parent | 716f51cce4ab52b3f67567b405e6455f0752e10c (diff) |
It sends tox-messages to pidgin!
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/ConfigFiles.hs | 8 | ||||
-rw-r--r-- | Presence/ConsoleWriter.hs | 23 | ||||
-rw-r--r-- | Presence/Presence.hs | 60 |
3 files changed, 58 insertions, 33 deletions
diff --git a/Presence/ConfigFiles.hs b/Presence/ConfigFiles.hs index 5682ea94..46d5a01c 100644 --- a/Presence/ConfigFiles.hs +++ b/Presence/ConfigFiles.hs | |||
@@ -16,6 +16,8 @@ import ByteStringOperators () -- For NFData instance | |||
16 | import Data.List (partition) | 16 | import Data.List (partition) |
17 | import Data.Maybe (catMaybes,isJust) | 17 | import Data.Maybe (catMaybes,isJust) |
18 | 18 | ||
19 | import DPut | ||
20 | |||
19 | type User = ByteString | 21 | type User = ByteString |
20 | type Profile = String | 22 | type Profile = String |
21 | 23 | ||
@@ -36,9 +38,15 @@ configPath :: User -> Profile -> String -> IO String | |||
36 | configPath user "." filename = do | 38 | configPath user "." filename = do |
37 | ue <- getUserEntryForName (unpack user) | 39 | ue <- getUserEntryForName (unpack user) |
38 | return $ (++("/"++configDir++"/"++filename)) $ homeDirectory ue | 40 | return $ (++("/"++configDir++"/"++filename)) $ homeDirectory ue |
41 | `catchIOError` \e -> do | ||
42 | dput XJabber $ "configPath " ++ show user ++ "\".\": " ++ show e | ||
43 | return $ (++("/"++configDir++"/"++filename)) $ "/tmp" | ||
39 | configPath user profile filename = do | 44 | configPath user profile filename = do |
40 | ue <- getUserEntryForName (unpack user) | 45 | ue <- getUserEntryForName (unpack user) |
41 | return $ (++("/"++configDir++"/"++profile++"/"++filename)) $ homeDirectory ue | 46 | return $ (++("/"++configDir++"/"++profile++"/"++filename)) $ homeDirectory ue |
47 | `catchIOError` \e -> do | ||
48 | dput XJabber $ "configPath " ++ show user ++ " " ++ show profile ++ ": " ++ show e | ||
49 | return $ (++("/"++configDir++"/"++filename)) $ "/tmp" | ||
42 | 50 | ||
43 | createConfigFile :: ByteString -> FilePath -> IO () | 51 | createConfigFile :: ByteString -> FilePath -> IO () |
44 | createConfigFile tag path = do | 52 | createConfigFile tag path = do |
diff --git a/Presence/ConsoleWriter.hs b/Presence/ConsoleWriter.hs index 6b611e68..7c377d83 100644 --- a/Presence/ConsoleWriter.hs +++ b/Presence/ConsoleWriter.hs | |||
@@ -23,6 +23,7 @@ import System.Posix.Process ( forkProcess, exitImmediately, executeFile ) | |||
23 | import System.Posix.User ( setUserID, getUserEntryForName, userID ) | 23 | import System.Posix.User ( setUserID, getUserEntryForName, userID ) |
24 | import System.Posix.Files ( getFileStatus, fileMode ) | 24 | import System.Posix.Files ( getFileStatus, fileMode ) |
25 | import System.INotify ( initINotify, EventVariety(Modify), addWatch ) | 25 | import System.INotify ( initINotify, EventVariety(Modify), addWatch ) |
26 | import System.IO.Error | ||
26 | import Data.Word ( Word8 ) | 27 | import Data.Word ( Word8 ) |
27 | import Data.Text ( Text ) | 28 | import Data.Text ( Text ) |
28 | import Data.Map ( Map ) | 29 | import Data.Map ( Map ) |
@@ -34,6 +35,7 @@ import qualified Data.Text as Text | |||
34 | -- import qualified Data.Text.IO as Text | 35 | -- import qualified Data.Text.IO as Text |
35 | import qualified Network.BSD as BSD | 36 | import qualified Network.BSD as BSD |
36 | 37 | ||
38 | import DPut | ||
37 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) | 39 | import UTmp ( users2, utmp_file, UtmpRecord(..), UT_Type(..) ) |
38 | import FGConsole ( forkTTYMonitor ) | 40 | import FGConsole ( forkTTYMonitor ) |
39 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType | 41 | import XMPPServer ( Stanza, makePresenceStanza, JabberShow(..), stanzaType |
@@ -256,14 +258,19 @@ deliverGUIMessage cw tty utmp msg = do | |||
256 | Nothing -> t | 258 | Nothing -> t |
257 | putStrLn $ "deliverGUI: " ++ text | 259 | putStrLn $ "deliverGUI: " ++ text |
258 | handleIO_ (return False) $ do | 260 | handleIO_ (return False) $ do |
259 | uentry <- getUserEntryForName (Text.unpack $ utmpUser utmp) | 261 | muentry <- fmap Just (getUserEntryForName (Text.unpack $ utmpUser utmp)) |
260 | let display = Text.unpack $ utmpHost utmp | 262 | `catchIOError` \e -> do |
261 | pid <- forkProcess $ do | 263 | dput XJabber $ "deliverGUIMessage(getUserEntryForName "++show (utmpUser utmp)++"): "++show e |
262 | setUserID (userID uentry) | 264 | return Nothing |
263 | setEnv "DISPLAY" display True | 265 | forM_ muentry $ \uentry -> do |
264 | -- rawSystem "/usr/bin/notify-send" [text] | 266 | let display = Text.unpack $ utmpHost utmp |
265 | executeFile "/usr/bin/notify-send" False [text] (Just [("DISPLAY",display)]) | 267 | pid <- forkProcess $ do |
266 | exitImmediately ExitSuccess | 268 | setUserID (userID uentry) |
269 | setEnv "DISPLAY" display True | ||
270 | -- rawSystem "/usr/bin/notify-send" [text] | ||
271 | executeFile "/usr/bin/notify-send" False [text] (Just [("DISPLAY",display)]) | ||
272 | exitImmediately ExitSuccess | ||
273 | return () | ||
267 | return True | 274 | return True |
268 | 275 | ||
269 | crlf :: Text -> Text | 276 | crlf :: Text -> Text |
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index daa93716..697c1476 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -99,8 +99,8 @@ data ToxManager k = ToxManager | |||
99 | 99 | ||
100 | data PresenceState = forall status. PresenceState | 100 | data PresenceState = forall status. PresenceState |
101 | { clients :: TVar (Map ConnectionKey ClientState) | 101 | { clients :: TVar (Map ConnectionKey ClientState) |
102 | , clientsByUser :: TVar (Map Text LocalPresence) -- TODO: For tox-enabled clients, the lookup key should be the client's toxid | 102 | , clientsByUser :: TVar (Map Text LocalPresence) |
103 | -- rather than the unix user. | 103 | , clientsByProfile :: TVar (Map Text LocalPresence) |
104 | , remotesByPeer :: TVar (Map ConnectionKey | 104 | , remotesByPeer :: TVar (Map ConnectionKey |
105 | (Map UserName RemotePresence)) | 105 | (Map UserName RemotePresence)) |
106 | , server :: TMVar (XMPPServer, Connection.Manager status Text) | 106 | , server :: TMVar (XMPPServer, Connection.Manager status Text) |
@@ -115,18 +115,20 @@ newPresenceState :: Maybe ConsoleWriter | |||
115 | -> TMVar (XMPPServer, Connection.Manager status Text) | 115 | -> TMVar (XMPPServer, Connection.Manager status Text) |
116 | -> IO PresenceState | 116 | -> IO PresenceState |
117 | newPresenceState cw toxman xmpp = atomically $ do | 117 | newPresenceState cw toxman xmpp = atomically $ do |
118 | clients <- newTVar Map.empty | 118 | clients <- newTVar Map.empty |
119 | clientsByUser <- newTVar Map.empty | 119 | clientsByUser <- newTVar Map.empty |
120 | remotesByPeer <- newTVar Map.empty | 120 | clientsByProfile <- newTVar Map.empty |
121 | keyToChan <- newTVar Map.empty | 121 | remotesByPeer <- newTVar Map.empty |
122 | keyToChan <- newTVar Map.empty | ||
122 | let st = PresenceState | 123 | let st = PresenceState |
123 | { clients = clients | 124 | { clients = clients |
124 | , clientsByUser = clientsByUser | 125 | , clientsByUser = clientsByUser |
125 | , remotesByPeer = remotesByPeer | 126 | , clientsByProfile = clientsByProfile |
126 | , keyToChan = keyToChan | 127 | , remotesByPeer = remotesByPeer |
127 | , server = xmpp | 128 | , keyToChan = keyToChan |
128 | , consoleWriter = cw | 129 | , server = xmpp |
129 | , toxManager = Nothing | 130 | , consoleWriter = cw |
131 | , toxManager = Nothing | ||
130 | } | 132 | } |
131 | return $ st { toxManager = fmap ($ st) toxman } | 133 | return $ st { toxManager = fmap ($ st) toxman } |
132 | 134 | ||
@@ -277,10 +279,11 @@ chooseResourceName state k addr clientsNameForMe desired = do | |||
277 | 279 | ||
278 | atomically $ do | 280 | atomically $ do |
279 | modifyTVar' (clients state) $ Map.insert k client | 281 | modifyTVar' (clients state) $ Map.insert k client |
280 | modifyTVar' (clientsByUser state) $ flip Map.alter (clientUser client) | 282 | let add mb = Just $ maybe (pcSingletonNetworkClient k client) |
281 | $ \mb -> Just $ maybe (pcSingletonNetworkClient k client) | ||
282 | (pcInsertNetworkClient k client) | 283 | (pcInsertNetworkClient k client) |
283 | mb | 284 | mb |
285 | modifyTVar' (clientsByUser state) $ Map.alter add (clientUser client) | ||
286 | modifyTVar' (clientsByProfile state) $ Map.alter add (clientProfile client) | ||
284 | 287 | ||
285 | localJID (clientUser client) (clientProfile client) (clientResource client) | 288 | localJID (clientUser client) (clientProfile client) (clientResource client) |
286 | 289 | ||
@@ -477,8 +480,8 @@ eofConn state k = do | |||
477 | stanza <- makePresenceStanza "jabber:server" Nothing Offline | 480 | stanza <- makePresenceStanza "jabber:server" Nothing Offline |
478 | informClientPresence state k stanza | 481 | informClientPresence state k stanza |
479 | atomically $ do | 482 | atomically $ do |
480 | modifyTVar' (clientsByUser state) | 483 | modifyTVar' (clientsByUser state) $ Map.alter (delclient k) (clientUser client) |
481 | $ Map.alter (delclient k) (clientUser client) | 484 | modifyTVar' (clientsByProfile state) $ Map.alter (delclient k) (clientProfile client) |
482 | PeerKey {} -> do | 485 | PeerKey {} -> do |
483 | let h = peerKeyToText k | 486 | let h = peerKeyToText k |
484 | jids <- atomically $ do | 487 | jids <- atomically $ do |
@@ -600,24 +603,31 @@ deliverMessage state fail msg = | |||
600 | (mine,(n,h,r)) <- rewriteJIDForClient laddr to [] | 603 | (mine,(n,h,r)) <- rewriteJIDForClient laddr to [] |
601 | if not mine then fail else do | 604 | if not mine then fail else do |
602 | let to' = unsplitJID (n,h,r) | 605 | let to' = unsplitJID (n,h,r) |
603 | cmap <- atomically . readTVar $ clientsByUser state | 606 | let (cmapVar,ckey) = case ctyp of |
607 | Tox -> (clientsByProfile state , n <&> (<> ".tox") ) | ||
608 | XMPP -> (clientsByUser state , n ) | ||
609 | cmap <- atomically . readTVar $ cmapVar | ||
604 | chans <- fmap (fromMaybe []) $ do | 610 | chans <- fmap (fromMaybe []) $ do |
605 | -- TODO: Tox-enabled clients need to be found by tox key. | 611 | forM (ckey >>= flip Map.lookup cmap) $ \presence_container -> do |
606 | forM (n >>= flip Map.lookup cmap) $ \presence_container -> do | ||
607 | let ks = Map.keys (networkClients presence_container) | 612 | let ks = Map.keys (networkClients presence_container) |
608 | chans = do | 613 | chans = do |
609 | (k,client) <- Map.toList $ networkClients presence_container | 614 | (k,client) <- Map.toList $ networkClients presence_container |
610 | chan <- maybeToList $ Map.lookup k key_to_chan | 615 | chan <- maybeToList $ Map.lookup k key_to_chan |
611 | return (clientProfile client, chan) | 616 | return (clientProfile client, clientUser client, chan) |
612 | forM chans $ \(profile,chan) -> do | 617 | forM chans $ \(profile,user,chan) -> do |
613 | buds <- configText ConfigFiles.getBuddies (fromJust n) profile | 618 | buds <- configText ConfigFiles.getBuddies user profile |
614 | from' <- do | 619 | from' <- case ctyp of |
620 | Tox -> return $ stanzaFrom msg | ||
621 | XMPP -> do | ||
615 | forM (stanzaFrom msg) $ \from -> do | 622 | forM (stanzaFrom msg) $ \from -> do |
616 | (_,trip) <- rewriteJIDForClient laddr from buds | 623 | (_,trip) <- rewriteJIDForClient laddr from buds |
617 | return $ unsplitJID trip | 624 | return $ unsplitJID trip |
625 | to' <- case ctyp of | ||
626 | XMPP -> return $ stanzaTo msg | ||
627 | Tox -> return $ Just $ unsplitJID (Just user, profile, Nothing) | ||
618 | return (from',chan) | 628 | return (from',chan) |
619 | putStrLn $ "chan count: " ++ show (length chans) | 629 | putStrLn $ "chan count: " ++ show (length chans) |
620 | if null chans then do | 630 | if null chans then when (ctyp == XMPP) $ do |
621 | forM_ (stanzaFrom msg) $ \from -> do | 631 | forM_ (stanzaFrom msg) $ \from -> do |
622 | from' <- do | 632 | from' <- do |
623 | -- Fallback to "." profile when no clients. | 633 | -- Fallback to "." profile when no clients. |