diff options
Diffstat (limited to 'XMPPToTox.hs')
-rw-r--r-- | XMPPToTox.hs | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/XMPPToTox.hs b/XMPPToTox.hs index ae9a774b..f0505ac7 100644 --- a/XMPPToTox.hs +++ b/XMPPToTox.hs | |||
@@ -14,10 +14,13 @@ import Data.Function | |||
14 | import Data.Monoid | 14 | import Data.Monoid |
15 | import Data.Text (Text) | 15 | import Data.Text (Text) |
16 | import Data.Text.Encoding as T | 16 | import Data.Text.Encoding as T |
17 | import Data.Word | ||
17 | import Data.XML.Types as XML | 18 | import Data.XML.Types as XML |
18 | import Network.Tox.Crypto.Transport (CryptoMessage (..), MessageID (..)) | 19 | import Network.Tox.Crypto.Transport (CryptoMessage (..), MessageID (..)) |
19 | import Text.XML.Stream.Parse as XML | 20 | import Text.XML.Stream.Parse as XML |
20 | 21 | ||
22 | import XMPPServer (JabberShow(..)) | ||
23 | |||
21 | -- Debugging. Not real Tox message. | 24 | -- Debugging. Not real Tox message. |
22 | funnyMessage :: MonadThrow m => Text -> ConduitM i CryptoMessage m () | 25 | funnyMessage :: MonadThrow m => Text -> ConduitM i CryptoMessage m () |
23 | funnyMessage txt = yield $ UpToN Padding (T.encodeUtf8 txt) | 26 | funnyMessage txt = yield $ UpToN Padding (T.encodeUtf8 txt) |
@@ -53,6 +56,53 @@ msgToTox = tag' "{jabber:server}message" | |||
53 | , ignoreAnyTreeContent | 56 | , ignoreAnyTreeContent |
54 | ] | 57 | ] |
55 | 58 | ||
59 | readJabberShow :: Text -> JabberShow | ||
60 | readJabberShow "xa" = ExtendedAway | ||
61 | readJabberShow "chat" = Chatty | ||
62 | readJabberShow "away" = Away | ||
63 | readJabberShow "dnd" = DoNotDisturb | ||
64 | readJabberShow _ = Available | ||
65 | |||
66 | -- | Convert XMPP "show" field to Tox USERSTATUS. | ||
67 | jabberUserStatus :: JabberShow -> Word8 | ||
68 | jabberUserStatus Available = 0 | ||
69 | jabberUserStatus Chatty = 0 | ||
70 | jabberUserStatus Away = 1 | ||
71 | jabberUserStatus ExtendedAway = 1 | ||
72 | jabberUserStatus Offline = 1 | ||
73 | jabberUserStatus DoNotDisturb = 2 | ||
74 | |||
75 | |||
76 | requireMissing :: XML.Name -> AttrParser () | ||
77 | requireMissing nm = force ("Unexpected "++show (XML.nameLocalName nm)++" attribute.") $ do | ||
78 | m <- attr nm | ||
79 | case m of | ||
80 | Nothing -> return $ Just () | ||
81 | Just _ -> return Nothing | ||
82 | |||
83 | presenceToTox :: MonadThrow m => | ||
84 | ConduitM Event CryptoMessage m (Maybe ()) | ||
85 | presenceToTox = tag' "{jabber:server}presence" | ||
86 | (requireMissing "type" >> ignoreAttrs) | ||
87 | $ \_ -> do | ||
88 | xs <- XML.many $ choose | ||
89 | [ tagIgnoreAttrs "{jabber:server}show" | ||
90 | $ do shw <- readJabberShow <$> content | ||
91 | yield $ TwoByte USERSTATUS $ jabberUserStatus shw | ||
92 | eom | ||
93 | return USERSTATUS | ||
94 | , tagIgnoreAttrs "{jabber:server}status" | ||
95 | -- TODO: The <status> tag may occur multiple times for different "xml:lang" values. | ||
96 | $ do txt <- content | ||
97 | yield $ UpToN STATUSMESSAGE $ T.encodeUtf8 txt | ||
98 | eom | ||
99 | return STATUSMESSAGE | ||
100 | , fmap (const Padding) <$> ignoreAnyTreeContent -- Ignore the priority tag and anything else. | ||
101 | ] | ||
102 | when (not $ USERSTATUS `elem` xs) $ do | ||
103 | -- Missing <show> element means Available. | ||
104 | yield $ TwoByte USERSTATUS $ jabberUserStatus Available | ||
105 | |||
56 | unknownToTox :: MonadThrow m => | 106 | unknownToTox :: MonadThrow m => |
57 | ConduitM Event CryptoMessage m (Maybe ()) | 107 | ConduitM Event CryptoMessage m (Maybe ()) |
58 | unknownToTox = tag anyName (\n -> ignoreAttrs >> return n) $ \n -> do | 108 | unknownToTox = tag anyName (\n -> ignoreAttrs >> return n) $ \n -> do |
@@ -60,13 +110,14 @@ unknownToTox = tag anyName (\n -> ignoreAttrs >> return n) $ \n -> do | |||
60 | eom | 110 | eom |
61 | 111 | ||
62 | 112 | ||
63 | xmppToTox :: MonadThrow m => Conduit XML.Event m CryptoMessage | 113 | xmppToTox :: MonadThrow m => ConduitM XML.Event CryptoMessage m () |
64 | xmppToTox = do | 114 | xmppToTox = do |
65 | eventBeginDocument <- await | 115 | eventBeginDocument <- await |
66 | streamTag <- await | 116 | streamTag <- await |
67 | fix $ \loop -> do | 117 | fix $ \loop -> do |
68 | got <- choose | 118 | got <- choose |
69 | [ msgToTox | 119 | [ msgToTox |
120 | , presenceToTox | ||
70 | , unknownToTox | 121 | , unknownToTox |
71 | ] | 122 | ] |
72 | forM_ got $ \_ -> loop | 123 | forM_ got $ \_ -> loop |