summaryrefslogtreecommitdiff
path: root/examples/MkTorrent.hs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/MkTorrent.hs')
-rw-r--r--examples/MkTorrent.hs78
1 files changed, 74 insertions, 4 deletions
diff --git a/examples/MkTorrent.hs b/examples/MkTorrent.hs
index 16e1e245..ab3144b4 100644
--- a/examples/MkTorrent.hs
+++ b/examples/MkTorrent.hs
@@ -5,12 +5,16 @@
5module Main (main) where 5module Main (main) where
6 6
7import Prelude as P 7import Prelude as P
8import Control.Concurrent
8import Control.Concurrent.ParallelIO 9import Control.Concurrent.ParallelIO
9import Control.Exception 10import Control.Exception
10import Control.Lens hiding (argument) 11import Control.Lens hiding (argument, (<.>))
11import Control.Monad 12import Control.Monad
13import Control.Monad.Trans
14import Data.Conduit as C
15import Data.Conduit.List as C
12import Data.List as L 16import Data.List as L
13import Data.Maybe 17import Data.Maybe as L
14import Data.Monoid 18import Data.Monoid
15import Data.Text as T 19import Data.Text as T
16import qualified Data.Text.IO as T 20import qualified Data.Text.IO as T
@@ -18,18 +22,25 @@ import Data.Text.Read as T
18import Data.Version 22import Data.Version
19import Network.URI 23import Network.URI
20import Options.Applicative 24import Options.Applicative
25import System.Exit
26import System.FilePath
21import System.Log 27import System.Log
22import System.Log.Logger 28import System.Log.Logger
23import System.Exit
24import Text.Read 29import Text.Read
25import Text.PrettyPrint.Class 30import Text.PrettyPrint.Class
26 31
27import Paths_bittorrent (version) 32import Paths_bittorrent (version)
28import Data.Torrent 33import Data.Torrent
29import Data.Torrent.Bitfield as BF 34import Data.Torrent.Bitfield as BF
35import Data.Torrent.InfoHash
30import Data.Torrent.Piece 36import Data.Torrent.Piece
31import Data.Torrent.Layout 37import Data.Torrent.Layout
32import Data.Torrent.Magnet hiding (Magnet) 38import Data.Torrent.Magnet hiding (Magnet)
39import Network.BitTorrent.Core
40import Network.BitTorrent.DHT.Session hiding (Options)
41import Network.BitTorrent.DHT as DHT
42import Network.BitTorrent.Exchange.Message
43import Network.BitTorrent.Exchange.Wire hiding (Options)
33import System.Torrent.Storage 44import System.Torrent.Storage
34 45
35 46
@@ -179,7 +190,7 @@ validateStorage s pinfo = do
179 let total = totalPieces s 190 let total = totalPieces s
180 pixs <- parallel $ L.map (validatePiece s pinfo) [0 .. total - 1] 191 pixs <- parallel $ L.map (validatePiece s pinfo) [0 .. total - 1]
181 infoM "check" "storage validation finished" 192 infoM "check" "storage validation finished"
182 return $ fromList total $ catMaybes pixs 193 return $ fromList total $ L.catMaybes pixs
183 194
184-- TODO use local thread pool 195-- TODO use local thread pool
185checkContent :: Storage -> PieceInfo -> IO () 196checkContent :: Storage -> PieceInfo -> IO ()
@@ -297,6 +308,62 @@ putTorrent opts @ ShowOpts {..} = do
297 msg = "Torrent file is either invalid or do not exist" 308 msg = "Torrent file is either invalid or do not exist"
298 309
299{----------------------------------------------------------------------- 310{-----------------------------------------------------------------------
311-- Get command - fetch torrent by infohash
312-----------------------------------------------------------------------}
313
314data GetOpts = GetOpts
315 { topic :: InfoHash
316 , thisNode :: NodeAddr IPv4
317 , bootNode :: NodeAddr IPv4
318 , buckets :: Int
319 } deriving Show
320
321paramsParser :: Parser GetOpts
322paramsParser = GetOpts
323 <$> option (long "infohash" <> short 'i'
324 <> metavar "SHA1" <> help "infohash of torrent file")
325 <*> option (long "port" <> short 'p'
326 <> value def <> showDefault
327 <> metavar "NUM" <> help "port number to bind"
328 )
329 <*> option (long "boot" <> short 'b'
330 <> metavar "NODE" <> help "bootstrap node address"
331 )
332 <*> option (long "bucket" <> short 'n'
333 <> value 2 <> showDefault
334 <> metavar "NUM" <> help "number of buckets to maintain"
335 )
336
337getInfo :: ParserInfo GetOpts
338getInfo = info (helper <*> paramsParser)
339 ( fullDesc
340 <> progDesc "Get torrent file by infohash"
341 <> header "get torrent file by infohash"
342 )
343
344exchangeTorrent :: PeerAddr IP -> InfoHash -> IO InfoDict
345exchangeTorrent addr ih = do
346 pid <- genPeerId
347 var <- newEmptyMVar
348 let hs = Handshake def (toCaps [ExtExtended]) ih pid
349 connectWire hs addr (toCaps [ExtMetadata]) $ do
350 infodict <- getMetadata
351 liftIO $ putMVar var infodict
352 takeMVar var
353
354getTorrent :: GetOpts -> IO ()
355getTorrent GetOpts {..} = do
356 dht (def { optBucketCount = buckets }) thisNode $ do
357 bootstrap [bootNode]
358 DHT.lookup topic $$ C.mapM_ $ \ peers -> do
359 liftIO $ forM_ peers $ \ peer -> do
360 infodict <- exchangeTorrent (IPv4 <$> peer) topic
361 -- TODO add tNodes, tCreated, etc?
362 let torrent = nullTorrent infodict
363 toFile (show topic <.> torrentExt) torrent
364 exitSuccess
365
366{-----------------------------------------------------------------------
300-- Command 367-- Command
301-----------------------------------------------------------------------} 368-----------------------------------------------------------------------}
302 369
@@ -304,6 +371,7 @@ data Command
304 = Amend AmendOpts 371 = Amend AmendOpts
305 | Check CheckOpts 372 | Check CheckOpts
306-- | Create CreateOpts 373-- | Create CreateOpts
374 | Get GetOpts
307 | Magnet MagnetOpts 375 | Magnet MagnetOpts
308 | Show ShowOpts 376 | Show ShowOpts
309 deriving Show 377 deriving Show
@@ -313,6 +381,7 @@ commandOpts = subparser $ mconcat
313 [ command "amend" (Amend <$> amendInfo) 381 [ command "amend" (Amend <$> amendInfo)
314 , command "check" (Check <$> checkInfo) 382 , command "check" (Check <$> checkInfo)
315-- , command "create" (Create <$> createInfo) 383-- , command "create" (Create <$> createInfo)
384 , command "get" (Get <$> getInfo)
316 , command "magnet" (Magnet <$> magnetInfo) 385 , command "magnet" (Magnet <$> magnetInfo)
317 , command "show" (Show <$> showInfo) 386 , command "show" (Show <$> showInfo)
318 ] 387 ]
@@ -396,6 +465,7 @@ run :: Command -> IO ()
396run (Amend opts) = amend opts 465run (Amend opts) = amend opts
397run (Check opts) = checkTorrent opts 466run (Check opts) = checkTorrent opts
398--run (Create opts) = createTorrent opts 467--run (Create opts) = createTorrent opts
468run (Get opts) = getTorrent opts
399run (Magnet opts) = magnet opts 469run (Magnet opts) = magnet opts
400run (Show opts) = putTorrent opts 470run (Show opts) = putTorrent opts
401 471