3 import qualified Utils as U
4 import qualified Bencode as Benc
5 import qualified Data.Map as M
6 import qualified Data.ByteString.Char8 as BC
7 import qualified Data.ByteString.Base16 as B16
8 import qualified Data.List as L
9 import Control.Applicative ((<$>))
11 data Peer = Peer { ip :: String
15 data PeerResp = PeerResponse { interval :: Maybe Integer
19 toInt :: String -> Integer
22 getPeers :: PeerResp -> [Peer]
25 getPeerResponse :: BC.ByteString -> PeerResp
26 getPeerResponse body = case (Benc.decode body) of
27 Right (Benc.Bdict peerM) ->
28 let (Just (Benc.Bint i)) = M.lookup (Benc.Bstr (BC.pack "lookup")) peerM
29 (Benc.Bstr peersBS) = peerM M.! (Benc.Bstr (BC.pack "peers"))
30 pl = map (\peer -> let (ip', port') = BC.splitAt 4 peer
31 in Peer { ip = toIPNum ip',
32 port = toPortNum port'
35 in PeerResponse { interval = Just i, peers = pl }
36 where toPortNum = read . ("0x" ++) . BC.unpack . B16.encode
37 toIPNum = (L.intercalate ".") .
38 map (show . toInt . ("0x" ++) . BC.unpack) .
39 (U.splitN 2) . B16.encode
40 Left _ -> PeerResponse { interval = Nothing, peers = [] }