From fe03cf8d51ae3ec976d3f066c4dcb18a2384fe9e Mon Sep 17 00:00:00 2001
From: Ramakrishnan Muthukrishnan <ram@rkrishnan.org>
Date: Mon, 16 Feb 2015 15:57:59 +0530
Subject: [PATCH] print peer ip and port numbers

---
 src/Main.hs |  5 +++--
 src/Peer.hs | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 src/Peer.hs

diff --git a/src/Main.hs b/src/Main.hs
index 10aa287..24bd9a9 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -7,6 +7,7 @@ import qualified Bencode as Benc
 import qualified Metainfo as MInfo
 import qualified Tracker as T
 import qualified Text.ParserCombinators.Parsec as Parsec
+import qualified Peer as P
 import Data.Functor
 
 printError :: Parsec.ParseError -> IO ()
@@ -34,7 +35,7 @@ main = do
    Right d -> case (MInfo.mkMetaInfo d) of
                Nothing -> putStrLn "parse error"
                Just m -> do
-                 body <- (Benc.decode . BC.pack) <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId)
-                 putStrLn (show body)
+                 body <- BC.pack <$> T.connect (MInfo.announce m) (T.prepareRequest d genPeerId)
+                 putStrLn (show (P.getPeers body))
    Left e -> printError e
   putStrLn "done"
diff --git a/src/Peer.hs b/src/Peer.hs
new file mode 100644
index 0000000..967a212
--- /dev/null
+++ b/src/Peer.hs
@@ -0,0 +1,37 @@
+module Peer where
+
+import qualified Utils as U
+import qualified Bencode as Benc
+import qualified Data.Map as M
+import qualified Data.ByteString.Char8 as BC
+import qualified Data.ByteString.Base16 as B16
+import qualified Data.List as L
+
+data Peer = Peer { ip :: String
+                 , port :: Integer
+                 } deriving (Show)
+                            
+data PeerResp = PeerResponse { interval :: Maybe Integer
+                             , peers :: [Peer]
+                             } deriving (Show)
+
+toInt :: String -> Integer
+toInt = read
+
+getPeers :: BC.ByteString -> [Peer]
+getPeers body = case (Benc.decode body) of
+                 Right (Benc.Bdict peerM) -> 
+                   let interval' = M.lookup (Benc.Bstr (BC.pack "lookup")) peerM 
+                       (Benc.Bstr peersBS) = peerM M.! (Benc.Bstr (BC.pack "peers"))
+                   in
+                    map (\peer -> let (ip', port') = BC.splitAt 4 peer
+                                  in
+                                   Peer { ip = toIPNum ip',
+                                          port =  toPortNum port'
+                                        })
+                    (U.splitN 6 peersBS)
+                   where toPortNum = read . ("0x" ++) . BC.unpack . B16.encode
+                         toIPNum = (L.intercalate ".") .
+                                   map (show . toInt . ("0x" ++) . BC.unpack) .
+                                   (U.splitN 2) . B16.encode
+                 Left _ -> []
-- 
2.45.2