]> git.rkrishnan.org Git - functorrent.git/blob - src/Peer.hs
refactoring
[functorrent.git] / src / Peer.hs
1 module Peer where
2
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 ((<$>))
10
11 data Peer = Peer { ip :: String
12                  , port :: Integer
13                  } deriving (Show)
14                             
15 data PeerResp = PeerResponse { interval :: Maybe Integer
16                              , peers :: [Peer]
17                              } deriving (Show)
18
19 toInt :: String -> Integer
20 toInt = read
21
22 getPeers :: PeerResp -> [Peer]
23 getPeers = peers
24
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'
33                                                          })
34                                    (U.splitN 6 peersBS)
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 = [] }