diff options
Diffstat (limited to 'examples/dhtd.hs')
-rw-r--r-- | examples/dhtd.hs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index ce1e1b16..291d0530 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -35,6 +35,7 @@ import Data.Function | |||
35 | import Data.Hashable | 35 | import Data.Hashable |
36 | import Data.List | 36 | import Data.List |
37 | import Data.Word | 37 | import Data.Word |
38 | import Data.InOrOut | ||
38 | import qualified Data.IntMap.Strict as IntMap | 39 | import qualified Data.IntMap.Strict as IntMap |
39 | import qualified Data.Map.Strict as Map | 40 | import qualified Data.Map.Strict as Map |
40 | import Data.Maybe | 41 | import Data.Maybe |
@@ -122,10 +123,15 @@ showColumns rows = do | |||
122 | _ <- take 1 fs -- Guard against empty rows so that 'last' is safe. | 123 | _ <- take 1 fs -- Guard against empty rows so that 'last' is safe. |
123 | " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n" | 124 | " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n" |
124 | 125 | ||
126 | pshow :: Show a => a -> B.ByteString | ||
127 | pshow = B.pack . show | ||
125 | 128 | ||
126 | marshalForClient :: String -> String | 129 | marshalForClient :: String -> String |
127 | marshalForClient s = show (length s) ++ ":" ++ s | 130 | marshalForClient s = show (length s) ++ ":" ++ s |
128 | 131 | ||
132 | marshalForClientB :: B.ByteString -> B.ByteString | ||
133 | marshalForClientB s = B.concat [pshow (B.length s),":",s] | ||
134 | |||
129 | data ClientHandle = ClientHandle Handle (MVar Int) | 135 | data ClientHandle = ClientHandle Handle (MVar Int) |
130 | 136 | ||
131 | -- | Writes a message and signals ready for next command. | 137 | -- | Writes a message and signals ready for next command. |
@@ -135,6 +141,13 @@ hPutClient (ClientHandle h hstate) s = do | |||
135 | hPutStr h ('.' : marshalForClient s) | 141 | hPutStr h ('.' : marshalForClient s) |
136 | putMVar hstate 1 -- ready for input | 142 | putMVar hstate 1 -- ready for input |
137 | 143 | ||
144 | -- | Writes a message and signals ready for next command. | ||
145 | hPutClientB :: ClientHandle -> B.ByteString -> IO () | ||
146 | hPutClientB (ClientHandle h hstate) s = do | ||
147 | st <- takeMVar hstate | ||
148 | B.hPutStr h ('.' `B.cons` marshalForClientB s) | ||
149 | putMVar hstate 1 -- ready for input | ||
150 | |||
138 | -- | Writes message, but signals there is more to come. | 151 | -- | Writes message, but signals there is more to come. |
139 | hPutClientChunk :: ClientHandle -> String -> IO () | 152 | hPutClientChunk :: ClientHandle -> String -> IO () |
140 | hPutClientChunk (ClientHandle h hstate) s = do | 153 | hPutClientChunk (ClientHandle h hstate) s = do |
@@ -730,6 +743,41 @@ clientSession s@Session{..} sock cnum h = do | |||
730 | else do | 743 | else do |
731 | rows <- sessionsReport | 744 | rows <- sessionsReport |
732 | hPutClient h (showColumns (headers:rows)) | 745 | hPutClient h (showColumns (headers:rows)) |
746 | -- session <N> tail | ||
747 | -- show context (latest lossless messages) | ||
748 | ("session", s) | (idStr,tailcmd,unstripped) <- twoWords s | ||
749 | , "" <- strp unstripped | ||
750 | , tailcmd `elem` ["tail","context"] | ||
751 | -> cmd0 $ do | ||
752 | lrSession <- strToSession idStr | ||
753 | case lrSession of | ||
754 | Left s -> hPutClient h s | ||
755 | Right session -> do | ||
756 | msgs <- atomically $ CB.cyclicBufferViewList (Tox.ncLastNMsgs session) | ||
757 | hPutClientB h (B.unlines (map showMsg msgs)) | ||
758 | -- session <N> me | ||
759 | -- display information about how you look to that session | ||
760 | ("session", s) | (idStr,"me",unstripped) <- twoWords s | ||
761 | , "" <- strp unstripped | ||
762 | -> cmd0 $ do | ||
763 | lrSession <- strToSession idStr | ||
764 | case lrSession of | ||
765 | Left s -> hPutClient h s | ||
766 | Right session -> do | ||
767 | view <- atomically (readTVar (Tox.ncView session) >>= Tox.viewSnapshot) | ||
768 | hPutClientB h (vShowMe view 0) | ||
769 | -- session <N> them | ||
770 | -- display information about the person on the other end of the session | ||
771 | ("session", s) | (idStr,them,unstripped) <- twoWords s | ||
772 | , "" <- strp unstripped | ||
773 | , them `elem` ["them","you"] | ||
774 | -> cmd0 $ do | ||
775 | lrSession <- strToSession idStr | ||
776 | case lrSession of | ||
777 | Left s -> hPutClient h s | ||
778 | Right session -> do | ||
779 | view <- atomically (readTVar (Tox.ncView session) >>= Tox.viewSnapshot) | ||
780 | hPutClientB h (vShowThem view 0) | ||
733 | -- session <N> online | 781 | -- session <N> online |
734 | -- send ONLINE packet to session N | 782 | -- send ONLINE packet to session N |
735 | ("session", s) | (idStr,"online",unstripped) <- twoWords s | 783 | ("session", s) | (idStr,"online",unstripped) <- twoWords s |
@@ -833,6 +881,20 @@ clientSession s@Session{..} sock cnum h = do | |||
833 | Just tox-> do | 881 | Just tox-> do |
834 | Tox.setStatusMsg (Tox.toxCryptoKeys tox) session (B.pack statusmsg) | 882 | Tox.setStatusMsg (Tox.toxCryptoKeys tox) session (B.pack statusmsg) |
835 | hPutClient h "sent STATUSMESSAGE" | 883 | hPutClient h "sent STATUSMESSAGE" |
884 | -- session <N> c <MSG> | ||
885 | -- send MESSAGE packet to session N (send chat message MSG) | ||
886 | ("session", s) | (idStr,msgcmd,msg) <- twoWords s | ||
887 | , msgcmd `elem` ["c","msg","send"] | ||
888 | -> cmd0 $ do | ||
889 | lrSession <- strToSession idStr | ||
890 | case lrSession of | ||
891 | Left s -> hPutClient h s | ||
892 | Right session -> do | ||
893 | case mbTox of | ||
894 | Nothing -> hPutClient h "Requires Tox enabled." | ||
895 | Just tox-> do | ||
896 | Tox.sendChatMsg (Tox.toxCryptoKeys tox) session (B.pack msg) | ||
897 | hPutClient h "sent MESSAGE" | ||
836 | 898 | ||
837 | ("onion", s) -> cmd0 $ join $ atomically $ do | 899 | ("onion", s) -> cmd0 $ join $ atomically $ do |
838 | rm <- readTVar $ routeMap onionRouter | 900 | rm <- readTVar $ routeMap onionRouter |
@@ -1432,6 +1494,34 @@ announceToxJabberPeer echan laddr saddr pingflag tsrc tsnk | |||
1432 | 1494 | ||
1433 | #endif | 1495 | #endif |
1434 | 1496 | ||
1497 | vShowMe :: Tox.ViewSnapshot -> Int -> B.ByteString | ||
1498 | vShowMe (Tox.ViewSnapshot { vNick, vStatus, vStatusMsg, vTyping }) indent | ||
1499 | = B.unlines | ||
1500 | . map doRow $ [ ["Nick: ", vNick ] | ||
1501 | , ["Status: ", "(" <> pshow vStatus <> ") " <> vStatusMsg ] | ||
1502 | , ["Typing: ", pshow vTyping ] | ||
1503 | ] | ||
1504 | where (<>) = B.append | ||
1505 | space = B.replicate indent ' ' | ||
1506 | doRow = B.append space . B.concat | ||
1507 | |||
1508 | vShowThem :: Tox.ViewSnapshot -> Int -> B.ByteString | ||
1509 | vShowThem (Tox.ViewSnapshot { vTheirNick, vTheirStatus, vTheirStatusMsg, vTheirTyping }) indent | ||
1510 | = B.unlines | ||
1511 | . map doRow $ [ ["Nick: ", vTheirNick ] | ||
1512 | , ["Status: ", "(" <> pshow vTheirStatus <> ") " <> vTheirStatusMsg ] | ||
1513 | , ["Typing: ", pshow vTheirTyping ] | ||
1514 | ] | ||
1515 | where (<>) = B.append | ||
1516 | space = B.replicate indent ' ' | ||
1517 | doRow = B.append space . B.concat | ||
1518 | |||
1519 | showMsg ::(Word32, (Bool,(Tox.ViewSnapshot, InOrOut Tox.CryptoMessage))) -> B.ByteString | ||
1520 | showMsg (n,(flg,(snapshot,iocm))) = B.concat [bool " " "h " flg, showmsg' (snapshot,iocm)] | ||
1521 | where | ||
1522 | showmsg' (snapshot,In cm) = B.concat [Tox.vNick snapshot,"> ", pshow cm] | ||
1523 | showmsg' (snapshot,Out cm) = B.concat [utf8boldify (Tox.vNick snapshot),": ",pshow cm] | ||
1524 | utf8boldify s = s | ||
1435 | 1525 | ||
1436 | main :: IO () | 1526 | main :: IO () |
1437 | main = runResourceT $ liftBaseWith $ \resT -> do | 1527 | main = runResourceT $ liftBaseWith $ \resT -> do |