summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent/Client.hs
blob: a6151857c68be428701450581a83c7077ef06125 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
module Network.BitTorrent.Client
       ( Options (..)
       , Client
       , newClient
       , addTorrent
       ) where

import Control.Concurrent.STM
import Data.Default
import Data.Function
import Data.HashMap.Strict as HM
import Data.Ord
import Data.Text
import Network

import Data.Torrent
import Data.Torrent.InfoHash
import Network.BitTorrent.Client.Swarm
import Network.BitTorrent.Core
import Network.BitTorrent.Exchange.Message


data Options = Options
  { fingerprint :: Fingerprint
  , name        :: Text
  , port        :: PortNumber
  , extensions  :: [Extension]
  }

instance Default Options where
  def = Options
    { fingerprint = def
    , name        = "hs-bittorrent"
    , port        = 6882
    , extensions  = []
    }

data Client = Client
  { clientPeerId       :: !PeerId
  , clientListenerPort :: !PortNumber
  , allowedExtensions  :: !Caps
  , torrents           :: TVar (HashMap InfoHash Swarm)
  }

instance Eq Client where
  (==) = (==) `on` clientPeerId

instance Ord Client where
  compare = comparing clientPeerId

newClient :: Options -> IO Client
newClient Options {..} = do
  pid <- genPeerId
  ts  <- newTVarIO HM.empty
  return Client
    { clientPeerId       = pid
    , clientListenerPort = port
    , allowedExtensions  = toCaps extensions
    , torrents           = ts
    }

addTorrent :: Torrent -> Client -> IO ()
addTorrent t Client {..} = do
  leecher <- newLeecher clientPeerId clientListenerPort t
  let ih = idInfoHash (tInfoDict t)
  atomically $ modifyTVar' torrents (HM.insert ih leecher)
  askPeers leecher >>= print