diff options
author | joe <joe@jerkface.net> | 2018-06-21 19:23:08 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2018-06-21 19:23:08 -0400 |
commit | 5b6f895c3b2bda2b46e8241a91476073308fc4cf (patch) | |
tree | 47fffdd8f3ea48a8b53600aff8f99ff01d3c4265 /Presence/Presence.hs | |
parent | efa0cec1aaa1aad9b66f2bfccc6b70b2093364a8 (diff) |
Send outgoing friend requests from XMPP clients.
Diffstat (limited to 'Presence/Presence.hs')
-rw-r--r-- | Presence/Presence.hs | 46 |
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 | |||
384 | getSolicited' :: Text -> Text -> IO [Text] | 384 | getSolicited' :: Text -> Text -> IO [Text] |
385 | getSolicited' = configText ConfigFiles.getSolicited | 385 | getSolicited' = configText ConfigFiles.getSolicited |
386 | 386 | ||
387 | sendProbesAndSolicitations :: 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 |
389 | sendProbesAndSolicitations 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 | -- | ||
402 | getBuddiesAndSolicited :: PresenceState -> (Text -> IO Bool) -> IO [(Bool, Maybe UserName, Text, Text)] | ||
403 | getBuddiesAndSolicited 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. | 424 | sendProbesAndSolicitations :: PresenceState |
409 | forM_ (nub xs) $ \(isbud,u,user,profile) -> do | 425 | -> ConnectionKey -> SockAddr -> TChan Stanza -> IO () |
426 | sendProbesAndSolicitations 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 |