blob: 7ca4330e4ade614d01d97b270a4b087ba84537cb (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module XMPPToTox
( module XMPPToTox
, CryptoMessage(..)
, MessageID(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Catch
import Data.Conduit
import Data.Function
import Data.Monoid
import Data.Text (Text)
import Data.Text.Encoding as T
import Data.XML.Types as XML
import Network.Tox.Crypto.Transport (CryptoMessage (..), MessageID (..))
import Text.XML.Stream.Parse as XML
-- Debugging. Not real Tox message.
funnyMessage :: MonadThrow m => Text -> ConduitM i CryptoMessage m ()
funnyMessage txt = yield $ UpToN Padding (T.encodeUtf8 txt)
sendMsg :: MonadThrow m => Text -> ConduitM i CryptoMessage m ()
sendMsg txt = yield $ UpToN MESSAGE (T.encodeUtf8 txt)
eom :: MonadThrow m => ConduitM Event o m ()
eom = many_ ignoreAnyTreeContent
msgToTox :: MonadThrow m =>
ConduitM Event CryptoMessage m (Maybe ())
msgToTox = tag' "{jabber:server}message"
(requireAttr "type" >>= \case
"chat" -> ignoreAttrs
_ -> empty)
$ \_ -> many_ $ choose
[ tagIgnoreAttrs "{jabber:server}body"
$ do content >>= sendMsg
eom
, tagIgnoreAttrs "{http://jabber.org/protocol/chatstates}composing"
$ do yield $ TwoByte TYPING 1
eom
, tagIgnoreAttrs "{http://jabber.org/protocol/chatstates}paused"
$ do yield $ TwoByte TYPING 0
eom
, ignoreAnyTreeContent
]
unknownToTox :: MonadThrow m =>
ConduitM Event CryptoMessage m (Maybe ())
unknownToTox = tag anyName (\n -> ignoreAttrs >> return n) $ \n -> do
funnyMessage $ nameLocalName n
eom
xmppToTox :: MonadThrow m => Conduit XML.Event m CryptoMessage
xmppToTox = do
eventBeginDocument <- await
streamTag <- await
fix $ \loop -> do
got <- choose
[ msgToTox
, unknownToTox
]
forM_ got $ \_ -> loop
|