1 module FuncTorrent.Metainfo
12 import Prelude hiding (lookup)
13 import Data.ByteString.Char8 (ByteString, unpack)
14 import Data.Map as M ((!), lookup)
16 import FuncTorrent.Bencode (BVal(..), bstrToString)
18 -- only single file mode supported for the time being.
19 data Info = Info { pieceLength :: !Integer
20 , pieces :: !ByteString
21 , private :: !(Maybe Integer)
23 , lengthInBytes :: !Integer
24 , md5sum :: !(Maybe String)
27 data Metainfo = Metainfo { info :: !Info
28 , announceList :: ![String]
29 , creationDate :: !(Maybe String)
30 , comment :: !(Maybe String)
31 , createdBy :: !(Maybe String)
32 , encoding :: !(Maybe String)
35 mkInfo :: BVal -> Maybe Info
36 mkInfo (Bdict m) = let (Bint pieceLength') = m ! "piece length"
37 (Bstr pieces') = m ! "pieces"
39 (Bstr name') = m ! "name"
40 (Bint length') = m ! "length"
42 in Just Info { pieceLength = pieceLength'
46 , lengthInBytes = length'
50 maybeBstrToString :: Maybe BVal -> Maybe String
51 maybeBstrToString Nothing = Nothing
52 maybeBstrToString (Just s) = let (Bstr bs) = s
55 mkMetaInfo :: BVal -> Maybe Metainfo
56 mkMetaInfo (Bdict m) = let (Just info') = mkInfo $ m ! "info"
57 announce' = lookup "announce" m
58 announceList' = lookup "announce-list" m
59 -- creationDate = lookup (Bstr (pack "creation date")) m
60 creationDate' = Nothing
61 comment' = lookup "comment" m
62 createdBy' = lookup "created by" m
63 encoding' = lookup "encoding" m
64 in Just Metainfo { info = info'
65 , announceList = maybeToList (announce' >>= bstrToString)
66 ++ getAnnounceList announceList'
67 , creationDate = creationDate'
68 , comment = maybeBstrToString comment'
69 , createdBy = maybeBstrToString createdBy'
70 , encoding = maybeBstrToString encoding'
72 mkMetaInfo _ = Nothing
74 maybeToList :: Maybe a -> [a]
75 maybeToList Nothing = []
76 maybeToList (Just x) = [x]
78 getAnnounceList :: Maybe BVal -> [String]
79 getAnnounceList Nothing = []
80 getAnnounceList (Just (Bint _)) = []
81 getAnnounceList (Just (Bstr _)) = []
82 getAnnounceList (Just (Blist l)) = map (\s -> case s of
83 (Bstr s') -> unpack s'
84 (Blist s') -> case s' of
85 [Bstr s''] -> unpack s''
89 getAnnounceList (Just (Bdict _)) = []