1 {-# LANGUAGE OverloadedStrings #-}
4 import Prelude hiding (length, readFile, writeFile)
5 import Data.ByteString.Char8 (ByteString, readFile, writeFile, length, unpack)
6 import System.Environment (getArgs)
7 import System.Exit (exitSuccess)
8 import System.Directory (doesFileExist)
9 import Text.ParserCombinators.Parsec (ParseError)
11 import FuncTorrent.Bencode (decode, BVal(..))
12 import FuncTorrent.Logger (initLogger, logMessage, logStop)
13 import FuncTorrent.Metainfo (announce, lengthInBytes, mkMetaInfo, info, name)
14 import FuncTorrent.Peer (peers, mkPeerResp, handShakeMsg)
15 import FuncTorrent.Tracker (connect, prepareRequest)
17 logError :: ParseError -> (String -> IO ()) -> IO ()
18 logError e logMsg = logMsg $ "parse error: \n" ++ show e
21 peerId = "-HS0001-*-*-20150215"
27 usage = putStrLn "usage: functorrent torrent-file"
29 parse :: [String] -> IO ByteString
30 parse [] = usage >> exit
32 fileExist <- doesFileExist a
35 else error "file does not exist"
42 let logMsg = logMessage logR
43 logMsg $ "Parsing input file: " ++ concat args
44 torrentStr <- parse args
45 case decode torrentStr of
48 Nothing -> logMsg "parse error"
50 logMsg "Input File OK"
52 let len = lengthInBytes $ info m
55 logMsg "Trying to fetch peers: "
56 response <- connect (announce m) (prepareRequest d' peerId len)
58 let hsMsgLen = show $ length $ handShakeMsg d' peerId
59 logMsg $ "Hand-shake message length : " ++ hsMsgLen
61 -- TODO: Write to ~/.functorrent/caches
62 writeFile (name (info m) ++ ".cache") response
64 case decode response of
66 case mkPeerResp trackerInfo of
68 logMsg $ "Peers List : " ++ (show . peers $ peerResp)
69 Left e -> logMsg $ "Error" ++ unpack e
70 Left e -> logError e logMsg
72 Left e -> logError e logMsg