diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2014-01-03 22:51:16 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2014-01-03 22:51:16 +0400 |
commit | 30a3dc92168c3c82d4cfd7a773cd3b63f34a6b03 (patch) | |
tree | bf5b81b7cff71410d992410420c82a2415933a8b /examples | |
parent | 7571c99b816087bd1422c2c3a948e53662ddba3b (diff) |
Add basic gettorrent implementation
Diffstat (limited to 'examples')
-rw-r--r-- | examples/GetTorrent.hs | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/examples/GetTorrent.hs b/examples/GetTorrent.hs index a9d2a44f..5e624fa1 100644 --- a/examples/GetTorrent.hs +++ b/examples/GetTorrent.hs | |||
@@ -1,27 +1,49 @@ | |||
1 | {-# LANGUAGE RecordWildCards #-} | ||
1 | module Main (main) where | 2 | module Main (main) where |
3 | import Control.Applicative | ||
4 | import Control.Concurrent | ||
5 | import Control.Monad | ||
6 | import Control.Monad.Trans | ||
7 | import Data.Conduit as C | ||
8 | import Data.Conduit.List as C | ||
2 | import Data.Default | 9 | import Data.Default |
3 | 10 | import Data.Maybe | |
11 | import Network.URI | ||
4 | import Options.Applicative | 12 | import Options.Applicative |
13 | import System.Exit | ||
14 | import System.FilePath | ||
15 | |||
16 | import Data.Torrent | ||
5 | import Data.Torrent.InfoHash | 17 | import Data.Torrent.InfoHash |
6 | import Network.BitTorrent.Core | 18 | import Network.BitTorrent.Core |
19 | import Network.BitTorrent.DHT.Session | ||
20 | import Network.BitTorrent.DHT as DHT | ||
21 | import Network.BitTorrent.Exchange.Message | ||
22 | import Network.BitTorrent.Exchange.Wire | ||
7 | 23 | ||
8 | 24 | ||
9 | data Params = Params | 25 | data Params = Params |
10 | { infohash :: InfoHash | 26 | { topic :: InfoHash |
11 | , thisNode :: NodeAddr IPv4 | 27 | , thisNode :: NodeAddr IPv4 |
12 | , bootNode :: NodeAddr IPv4 | 28 | , bootNode :: NodeAddr IPv4 |
29 | , buckets :: Int | ||
13 | } deriving Show | 30 | } deriving Show |
14 | 31 | ||
15 | paramsParser :: Parser Params | 32 | paramsParser :: Parser Params |
16 | paramsParser = Params | 33 | paramsParser = Params |
17 | <$> option (long "infohash" <> short 'i' | 34 | <$> option (long "infohash" <> short 'i' |
18 | <> metavar "SHA1" <> help "infohash of torrent file") | 35 | <> metavar "SHA1" <> help "infohash of torrent file") |
19 | <*> option (long "node" <> short 'n' <> value def | 36 | <*> option (long "port" <> short 'p' |
20 | <> metavar "NODE" <> help "this node address" | 37 | <> value def <> showDefault |
38 | <> metavar "NUM" <> help "port number to bind" | ||
21 | ) | 39 | ) |
22 | <*> option (long "boot" <> short 'b' | 40 | <*> option (long "boot" <> short 'b' |
23 | <> metavar "NODE" <> help "bootstrap node address" | 41 | <> metavar "NODE" <> help "bootstrap node address" |
24 | ) | 42 | ) |
43 | <*> option (long "bucket" <> short 'n' | ||
44 | <> value 2 <> showDefault | ||
45 | <> metavar "NUM" <> help "number of buckets to maintain" | ||
46 | ) | ||
25 | 47 | ||
26 | programInfo :: ParserInfo Params | 48 | programInfo :: ParserInfo Params |
27 | programInfo = info (helper <*> paramsParser) | 49 | programInfo = info (helper <*> paramsParser) |
@@ -30,8 +52,29 @@ programInfo = info (helper <*> paramsParser) | |||
30 | <> header "gettorrent - get torrent file by infohash" | 52 | <> header "gettorrent - get torrent file by infohash" |
31 | ) | 53 | ) |
32 | 54 | ||
55 | fakeTracker :: URI | ||
56 | fakeTracker = fromJust $ parseURI "http://foo.org" | ||
57 | |||
58 | exchangeTorrent :: PeerAddr IP -> InfoHash -> IO InfoDict | ||
59 | exchangeTorrent addr ih = do | ||
60 | pid <- genPeerId | ||
61 | var <- newEmptyMVar | ||
62 | let hs = Handshake def (toCaps [ExtExtended]) ih pid | ||
63 | connectWire hs addr (toCaps [ExtMetadata]) $ do | ||
64 | infodict <- getMetadata | ||
65 | liftIO $ putMVar var infodict | ||
66 | takeMVar var | ||
67 | |||
33 | getTorrent :: Params -> IO () | 68 | getTorrent :: Params -> IO () |
34 | getTorrent = print | 69 | getTorrent Params {..} = do |
70 | dht (def { optBucketCount = buckets }) thisNode $ do | ||
71 | bootstrap [bootNode] | ||
72 | DHT.lookup topic $$ C.mapM_ $ \ peers -> do | ||
73 | liftIO $ forM_ peers $ \ peer -> do | ||
74 | infodict <- exchangeTorrent (IPv4 <$> peer) topic | ||
75 | let torrent = nullTorrent fakeTracker infodict | ||
76 | toFile (show topic <.> torrentExt) torrent | ||
77 | exitSuccess | ||
35 | 78 | ||
36 | main :: IO () | 79 | main :: IO () |
37 | main = execParser programInfo >>= getTorrent | 80 | main = execParser programInfo >>= getTorrent |