summaryrefslogtreecommitdiff
path: root/Presence/Presence.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2018-06-21 19:23:08 -0400
committerjoe <joe@jerkface.net>2018-06-21 19:23:08 -0400
commit5b6f895c3b2bda2b46e8241a91476073308fc4cf (patch)
tree47fffdd8f3ea48a8b53600aff8f99ff01d3c4265 /Presence/Presence.hs
parentefa0cec1aaa1aad9b66f2bfccc6b70b2093364a8 (diff)
Send outgoing friend requests from XMPP clients.
Diffstat (limited to 'Presence/Presence.hs')
-rw-r--r--Presence/Presence.hs46
1 files changed, 36 insertions, 10 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs
index a33de0a6..a55d49ab 100644
--- a/Presence/Presence.hs
+++ b/Presence/Presence.hs
@@ -384,11 +384,26 @@ getBuddies' = configText ConfigFiles.getBuddies
384getSolicited' :: Text -> Text -> IO [Text] 384getSolicited' :: Text -> Text -> IO [Text]
385getSolicited' = configText ConfigFiles.getSolicited 385getSolicited' = configText ConfigFiles.getSolicited
386 386
387sendProbesAndSolicitations :: PresenceState 387-- | Obtain from roster all buddies and pending buddies (called solicited
388 -> ConnectionKey -> SockAddr -> TChan Stanza -> IO () 388-- regardless of whether we've yet delivered a friend-request) matching the
389sendProbesAndSolicitations state k laddr chan = do 389-- supplied side-effecting predicate.
390 -- get all buddies & solicited matching k for all users 390--
391 xs <- runTraversableT $ do 391-- Returned tuple:
392--
393-- * Bool - True if buddy (should send probe).
394-- False if solicited (should send friend-request).
395--
396-- * Maybe Username - Username field of contact.
397--
398-- * Text - Unix user who owns this roster entry.
399--
400-- * Text - Profile, "." for xmpp, "tox" for a tox-enabled client.
401--
402getBuddiesAndSolicited :: PresenceState -> (Text -> IO Bool) -> IO [(Bool, Maybe UserName, Text, Text)]
403getBuddiesAndSolicited state pred
404 -- XXX: The following O(n²) nub may be a little
405 -- too onerous.
406 = fmap nub $ runTraversableT $ do
392 cbu <- lift $ atomically $ readTVar $ clientsByUser state 407 cbu <- lift $ atomically $ readTVar $ clientsByUser state
393 (user,LocalPresence cmap) <- liftT $ Map.toList cbu 408 (user,LocalPresence cmap) <- liftT $ Map.toList cbu
394 profile <- liftT $ nub $ map clientProfile $ Map.elems cmap 409 profile <- liftT $ nub $ map clientProfile $ Map.elems cmap
@@ -396,17 +411,28 @@ sendProbesAndSolicitations state k laddr chan = do
396 ,(False,getSolicited')] 411 ,(False,getSolicited')]
397 bud <- liftMT $ getter user profile 412 bud <- liftMT $ getter user profile
398 let (u,h,r) = splitJID bud 413 let (u,h,r) = splitJID bud
399 addr <- liftMT $ nub `fmap` resolvePeer h 414 interested <- lift $ pred h
400 liftT $ guard (PeerKey addr == k) 415 guard interested
416
401 -- Note: Earlier I was tempted to do all the IO 417 -- Note: Earlier I was tempted to do all the IO
402 -- within the TraversableT monad. That apparently 418 -- within the TraversableT monad. That apparently
403 -- is a bad idea. Perhaps due to laziness and an 419 -- is a bad idea. Perhaps due to laziness and an
404 -- unforced list? Instead, we will return a list 420 -- unforced list? Instead, we will return a list
405 -- of (Bool,Text) for processing outside. 421 -- of (Bool,Text) for processing outside.
406 return (isbud,u,user,profile) 422 return (isbud,u,user,profile)
407 -- XXX: The following O(n²) nub may be a little 423
408 -- too onerous. 424sendProbesAndSolicitations :: PresenceState
409 forM_ (nub xs) $ \(isbud,u,user,profile) -> do 425 -> ConnectionKey -> SockAddr -> TChan Stanza -> IO ()
426sendProbesAndSolicitations state k laddr chan = do
427 -- get all buddies & solicited matching k for all users
428 xs <- getBuddiesAndSolicited state $ \case
429 h | ".tox" `Text.isSuffixOf` h -> return False -- Tox probes/solicitations are handled in ToxToXMPP module.
430 h -> do
431 addrs <- nub `fmap` resolvePeer h
432 case k of
433 ClientKey _ -> return False -- Solicitations and probes are only for peers.
434 PeerKey a -> return $ a `elem` addrs -- Only for this peer /k/.
435 forM_ xs $ \(isbud,u,user,profile) -> do
410 let make = if isbud then presenceProbe 436 let make = if isbud then presenceProbe
411 else presenceSolicitation 437 else presenceSolicitation
412 toh = peerKeyToText k 438 toh = peerKeyToText k