multi-file torrent metainfo tests
authorRamakrishnan Muthukrishnan <ram@rkrishnan.org>
Sun, 17 Jul 2016 07:50:43 +0000 (13:20 +0530)
committerRamakrishnan Muthukrishnan <ram@rkrishnan.org>
Sun, 17 Jul 2016 07:50:43 +0000 (13:20 +0530)
src/FuncTorrent/Bencode.hs
src/FuncTorrent/Metainfo.hs
test/MetainfoSpec.hs

index 294ad892d1e9ba17c974f1b0ecd066377ba2f65f..4703084be6fc467ab3f1b6c1fb8d13db4d993662 100644 (file)
@@ -95,3 +95,4 @@ encode (Bdict d) = concat ["d", concat kvlist, "e"]
       kvlist :: [ByteString]
       kvlist = [encPair kv | kv <- toList d]
       encPair (k, v) = concat [encode . Bstr . pack $ k, encode v]
+
index 596ad68def10b461ee04f52b78152fb2ed9bf694..ec65294d852fca3125d0f1ec5db08e27ddbfcc01 100644 (file)
@@ -23,12 +23,14 @@ module FuncTorrent.Metainfo
     (Info(..)
     , Metainfo(..)
     , DynamicInfo(..)
+    , FileInfo(..)
     , torrentToMetainfo
     ) where
 
 import Prelude hiding (lookup)
 import Data.ByteString.Char8 (ByteString, unpack)
 import Data.Map as M ((!), lookup)
+import Data.List (intercalate)
 import Crypto.Hash.SHA1 (hash)
 import Data.Maybe (maybeToList)
 
@@ -41,10 +43,7 @@ data Info = Info { pieceLength :: !Integer
                  , dyninfo :: !DynamicInfo
                  } deriving (Eq, Show)
 
-data DynamicInfo = SingleFileInfo { name :: String
-                                  , lengthInBytes :: Integer
-                                  , md5sum :: Maybe String
-                                  }
+data DynamicInfo = SingleFileInfo { file :: FileInfo }
                  | MultiFileInfo { dname :: String
                                  , files :: [FileInfo]
                                  }
@@ -64,6 +63,9 @@ data Metainfo = Metainfo { info :: !Info
                          , infoHash :: !ByteString
                          } deriving (Eq, Show)
 
+mkPath :: [BVal] -> String
+mkPath xs = intercalate "/" $ map (\b -> let (Just s) = bstrToString b in s) xs
+
 mkInfo :: BVal -> Maybe Info
 mkInfo (Bdict m) = let (Bint pieceLength') = m ! "piece length"
                        (Bstr pieces') = m ! "pieces"
@@ -82,11 +84,12 @@ mkInfo (Bdict m) = let (Bint pieceLength') = m ! "piece length"
                                                   files =
                                                       map (\(Bdict f) ->
                                                             let (Just len') = bValToInteger (f ! "length")
-                                                                (Bstr s') = f ! "path"
+                                                                (Blist ds) = f ! "path"
+                                                                path' = mkPath ds
                                                             in
                                                               FileInfo { lengthInBytes = len',
                                                                          md5sum = Nothing,
-                                                                         path = unpack s'
+                                                                         path = path'
                                                                      })
                                                       files' }
                                               }
@@ -98,9 +101,12 @@ mkInfo (Bdict m) = let (Bint pieceLength') = m ! "piece length"
                                               , pieces = pieces'
                                               , private = private'
                                               , dyninfo = SingleFileInfo {
-                                                  name = unpack name',
-                                                  lengthInBytes = length',
-                                                  md5sum = md5sum'}
+                                                  file = FileInfo {
+                                                      path = unpack name',
+                                                      lengthInBytes = length',
+                                                      md5sum = md5sum'
+                                                      }
+                                                  }
                                               }
 
 mkInfo _ = Nothing
index 93bf9ab3bf628d18c8bdf78acb9f6e19d33dc992..060bf9fbd888c071e53b4351cb11b8dbedc84b71 100644 (file)
@@ -23,7 +23,7 @@ module MetainfoSpec where
 
 import Test.Hspec
 
-import FuncTorrent.Metainfo (Info(..), Metainfo(..), DynamicInfo(..), torrentToMetainfo)
+import FuncTorrent.Metainfo (Info(..), Metainfo(..), DynamicInfo(..), FileInfo(..), torrentToMetainfo)
 import qualified Data.ByteString.Lazy.Char8 as BC (readFile, toStrict)
 import qualified Data.ByteString as B
 
@@ -36,11 +36,25 @@ spec =
       length (announceList m) `shouldBe` 1
       pieceLength (info m) `shouldBe` 524288
       pieces (info m) `shouldSatisfy` (\p -> B.length p `mod` 20 == 0)
-      let (SingleFileInfo name' _ _) = dyninfo $ info m
+      let (SingleFileInfo file') = dyninfo $ info m
+          (FileInfo _ _ name') = file'
+      name' `shouldNotBe` ""
+    it "torrent-file-2" $ do
+      c <- BC.readFile "data/test2.torrent"
+      let (Right m) = torrentToMetainfo (BC.toStrict c)
+          (SingleFileInfo file') = dyninfo $ info m
+          (FileInfo _ _ name') = file'
+      name' `shouldNotBe` ""
+    it "torrent-file-3" $ do
+      c <- BC.readFile "data/test3.torrent"
+      let (Right m) = torrentToMetainfo (BC.toStrict c)
+          (SingleFileInfo file') = dyninfo $ info m
+          (FileInfo _ _ name') = file'
       name' `shouldNotBe` ""
     it "torrent-file-4" $ do
       c <- BC.readFile "data/test4.torrent"
       let (Right m) = torrentToMetainfo (BC.toStrict c)
       length (announceList m) `shouldBe` 3
-      let (MultiFileInfo _ files') = dyninfo $ info m
-      length files' `shouldNotBe` 1
+      let (MultiFileInfo dname' files') = dyninfo $ info m
+      length files' `shouldBe` 9 -- 9 files in the torrent
+      dname' `shouldBe` "NASA_NTRS_Archive_19740027163"