module FuncTorrent.Bencode
(BVal(..),
InfoDict,
+ bstrToString,
encode,
decode
) where
encode (Bint i) = pack $ "i" ++ show i ++ "e"
encode (Blist xs) = pack $ "l" ++ unpack (concat $ map encode xs) ++ "e"
encode (Bdict d) = concat [concat ["d", encode . Bstr . pack $ k , encode (d ! k) , "e"] | k <- keys d]
+
+-- getters
+bstrToString :: BVal -> Maybe String
+bstrToString (Bstr s) = Just $ unpack s
+bstrToString _ = Nothing
module FuncTorrent.Metainfo
(Info,
Metainfo,
+ announceList,
mkMetaInfo,
mkInfo,
- announce,
lengthInBytes,
info,
name,
- getTrackers
) where
import Prelude hiding (lookup)
import Data.ByteString.Char8 (ByteString, unpack)
import Data.Map as M ((!), lookup)
-import FuncTorrent.Bencode (BVal(..))
+import FuncTorrent.Bencode (BVal(..), bstrToString)
-- only single file mode supported for the time being.
data Info = Info { pieceLength :: !Integer
} deriving (Eq, Show)
data Metainfo = Metainfo { info :: !Info
- , announce :: !(Maybe String)
, announceList :: ![String]
, creationDate :: !(Maybe String)
, comment :: !(Maybe String)
createdBy' = lookup "created by" m
encoding' = lookup "encoding" m
in Just Metainfo { info = info'
- , announce = announce'
- >>= (\(Bstr a) ->
- Just (unpack a))
- , announceList = getAnnounceList announceList'
+ , announceList = maybeToList (announce' >>= bstrToString)
+ ++ getAnnounceList announceList'
, creationDate = creationDate'
, comment = maybeBstrToString comment'
, createdBy = maybeBstrToString createdBy'
}
mkMetaInfo _ = Nothing
+maybeToList :: Maybe a -> [a]
+maybeToList Nothing = []
+maybeToList (Just x) = [x]
+
getAnnounceList :: Maybe BVal -> [String]
getAnnounceList Nothing = []
getAnnounceList (Just (Bint _)) = []
_ -> "") l
getAnnounceList (Just (Bdict _)) = []
-
-getTrackers :: Metainfo -> [String]
-getTrackers m = case announce m of
- Nothing -> announceList m
- Just a -> a : announceList m
import FuncTorrent.Bencode (decode, BVal(..))
import FuncTorrent.Logger (initLogger, logMessage, logStop)
-import FuncTorrent.Metainfo (lengthInBytes, mkMetaInfo, info, name, getTrackers)
+import FuncTorrent.Metainfo (lengthInBytes, mkMetaInfo, info, name, announceList)
import FuncTorrent.Peer (peers, mkPeerResp, handShakeMsg)
import FuncTorrent.Tracker (connect, prepareRequest)
let len = lengthInBytes $ info m
(Bdict d') = d
- trackers = getTrackers m
+ trackers = announceList m
logMsg "Trying to fetch peers: "
response <- connect (head trackers) (prepareRequest d' peerId len)