diff options
Diffstat (limited to 'Presence/Presence.hs')
-rw-r--r-- | Presence/Presence.hs | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index befe47e1..5fe4e8cf 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -394,36 +394,38 @@ getSolicited' = configText ConfigFiles.getSolicited | |||
394 | -- | 394 | -- |
395 | -- * Text - Profile, "." for xmpp, "tox" for a tox-enabled client. | 395 | -- * Text - Profile, "." for xmpp, "tox" for a tox-enabled client. |
396 | -- | 396 | -- |
397 | getBuddiesAndSolicited :: PresenceState -> (Text -> IO Bool) -> IO [(Bool, Maybe UserName, Text, Text)] | 397 | getBuddiesAndSolicited :: PresenceState |
398 | getBuddiesAndSolicited state pred | 398 | -> Text -- ^ Config profile: "." or tox host. |
399 | -> (Text -> IO Bool) -- ^ Return True if you want this hostname. | ||
400 | -> IO [(Bool, Maybe UserName, Text, Text)] | ||
401 | getBuddiesAndSolicited state profile pred | ||
399 | -- XXX: The following O(n²) nub may be a little | 402 | -- XXX: The following O(n²) nub may be a little |
400 | -- too onerous. | 403 | -- too onerous. |
401 | = fmap nub $ runTraversableT $ do | 404 | = fmap nub $ do |
402 | cbu <- lift $ atomically $ readTVar $ clientsByUser state | 405 | cbu <- atomically $ readTVar $ clientsByUser state |
403 | (user,LocalPresence cmap) <- liftT $ Map.toList cbu | 406 | fmap concat $ sequence $ do |
404 | profile <- liftT $ nub $ map clientProfile $ Map.elems cmap | 407 | (user,LocalPresence cmap) <- Map.toList cbu |
405 | (isbud,getter) <- liftT [(True ,getBuddies' ) | 408 | (isbud, getter) <- [(True ,getBuddies' ) |
406 | ,(False,getSolicited')] | 409 | ,(False,getSolicited')] |
407 | bud <- liftMT $ getter user profile | 410 | return $ do |
408 | let (u,h,r) = splitJID bud | 411 | buds <- map splitJID <$> getter user profile |
409 | interested <- lift $ pred h | 412 | fmap concat $ forM buds $ \(u,h,r) -> do |
410 | guard interested | 413 | interested <- pred h |
411 | 414 | if interested | |
412 | -- Note: Earlier I was tempted to do all the IO | 415 | then return [(isbud,u,user,profile)] |
413 | -- within the TraversableT monad. That apparently | 416 | else return [] |
414 | -- is a bad idea. Perhaps due to laziness and an | ||
415 | -- unforced list? Instead, we will return a list | ||
416 | -- of (Bool,Text) for processing outside. | ||
417 | return (isbud,u,user,profile) | ||
418 | 417 | ||
419 | sendProbesAndSolicitations :: PresenceState -> PeerAddress -> Local SockAddr -> TChan Stanza -> IO () | 418 | sendProbesAndSolicitations :: PresenceState -> PeerAddress -> Local SockAddr -> TChan Stanza -> IO () |
420 | sendProbesAndSolicitations state k (Local laddr) chan = do | 419 | sendProbesAndSolicitations state k (Local laddr) chan = do |
420 | prof <- atomically $ do | ||
421 | pktc <- readTVar (pkeyToChan state) | ||
422 | return $ maybe "." (cdProfile . auxData) $ Map.lookup k pktc | ||
421 | -- get all buddies & solicited matching k for all users | 423 | -- get all buddies & solicited matching k for all users |
422 | xs <- getBuddiesAndSolicited state $ \case | 424 | xs <- getBuddiesAndSolicited state prof $ \case |
423 | h | ".tox" `Text.isSuffixOf` h -> return False -- Tox probes/solicitations are handled in ToxToXMPP module. | 425 | h | ".tox" `Text.isSuffixOf` h -> return False -- Tox probes/solicitations are handled in ToxToXMPP module. |
424 | h -> do | 426 | h -> do |
425 | addrs <- nub `fmap` resolvePeer h | 427 | addrs <- nub <$> resolvePeer h |
426 | return $ k `elem` addrs -- Only for this peer /k/. | 428 | return $ k `elem` addrs -- Roster item resolves to /k/ peer. |
427 | forM_ xs $ \(isbud,u,user,profile) -> do | 429 | forM_ xs $ \(isbud,u,user,profile) -> do |
428 | let make = if isbud then presenceProbe | 430 | let make = if isbud then presenceProbe |
429 | else presenceSolicitation | 431 | else presenceSolicitation |