summaryrefslogtreecommitdiff
path: root/ToxToXMPP.hs
blob: 1493827aab061ac8a16bdebdcfe7e7a6ac5fa9be (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
68
69
70
{-# LANGUAGE CPP                      #-}
{-# LANGUAGE LambdaCase               #-}
{-# LANGUAGE NamedFieldPuns           #-}
{-# LANGUAGE NondecreasingIndentation #-}
{-# LANGUAGE ViewPatterns             #-}
module ToxToXMPP where

import Crypto.Tox
import Data.Conduit                 as C
import qualified Data.Conduit.List  as CL
import Data.Monoid
import qualified Data.Text          as T
         ;import Data.Text          (Text)
import Data.Text.Encoding           as T
import Data.XML.Types               as XML
import EventUtil
import Network.Address
import Network.Tox.Crypto.Transport as Tox
import Network.Tox.NodeId
import Util                         (unsplitJID)
import XMPPServer                   as XMPP

toxToXmpp :: Monad m => SockAddr -> PublicKey -> Text -> Conduit Tox.CryptoMessage m XML.Event
toxToXmpp laddr me theirhost = do
    CL.sourceList $ XMPP.greet' "jabber:server" theirhost
    let me_u = T.pack $ show (key2id me)
    awaitForever $ \case

        UpToN { msgID    = MESSAGE
              , msgBytes = bs      }
               -> do
            xmppInstantMessage "jabber:server"
                (Just $ "root@" <> theirhost)      -- /from/
                (Just $ unsplitJID (Just me_u,T.pack (show laddr),Nothing)) -- /to/ should match local address of this node.
                []
                (T.decodeUtf8 bs)

        toxmsg | msgID toxmsg == PacketRequest -> return ()

        toxmsg -> do
            xmppInstantMessage "jabber:server"
                (Just theirhost)      -- /from/
                (Just $ unsplitJID (Just me_u,T.pack (show laddr),Nothing)) -- /to/ should match local address of this node.
                [ attr "style" "font-weight:bold; color:red" ]
                (T.pack $ show $ msgID toxmsg)

xmppInstantMessage :: Monad m => Text
                              -> Maybe Text
                              -> Maybe Text
                              -> [(Name, [Content])]
                              -> Text
                              -> ConduitM i Event m ()
xmppInstantMessage namespace mfrom mto style text = do
    let ns n = n { nameNamespace = Just namespace }
    C.yield $ EventBeginElement (ns "message")
               (  maybe id (\t->(attr "from" t:)) mfrom
                $ maybe id (\t->(attr "to" t:)) mto
                $ [attr "type" "normal" ] )
    C.yield $   EventBeginElement (ns "body") []
    C.yield $     EventContent $ ContentText text
    C.yield $   EventEndElement (ns "body")
    C.yield $   EventBeginElement "{http://jabber.org/protocol/xhtml-im}html" []
    C.yield $     EventBeginElement "{http://www.w3.org/1999/xhtml}body" []
    C.yield $        EventBeginElement "{http://www.w3.org/1999/xhtml}p" style
    C.yield $          EventContent $ ContentText text
    C.yield $        EventEndElement "{http://www.w3.org/1999/xhtml}p"
    C.yield $     EventEndElement "{http://www.w3.org/1999/xhtml}body"
    C.yield $   EventEndElement "{http://jabber.org/protocol/xhtml-im}html"
    C.yield $ EventEndElement (ns "message")