1 module FuncTorrent.Metainfo
8 import Prelude hiding (lookup)
9 import Data.ByteString.Char8 (ByteString, unpack)
10 import Data.Map as M ((!), lookup)
11 import Data.Maybe (maybeToList)
13 import FuncTorrent.Bencode (BVal(..), bstrToString)
15 -- only single file mode supported for the time being.
16 data Info = Info { pieceLength :: !Integer
17 , pieces :: !ByteString
18 , private :: !(Maybe Integer)
20 , lengthInBytes :: !Integer
21 , md5sum :: !(Maybe String)
24 data Metainfo = Metainfo { info :: !Info
25 , announceList :: ![String]
26 , creationDate :: !(Maybe String)
27 , comment :: !(Maybe String)
28 , createdBy :: !(Maybe String)
29 , encoding :: !(Maybe String)
32 mkInfo :: BVal -> Maybe Info
33 mkInfo (Bdict m) = let (Bint pieceLength') = m ! "piece length"
34 (Bstr pieces') = m ! "pieces"
36 (Bstr name') = m ! "name"
37 (Bint length') = m ! "length"
39 in Just Info { pieceLength = pieceLength'
43 , lengthInBytes = length'
47 maybeBstrToString :: Maybe BVal -> Maybe String
48 maybeBstrToString (Just (Bstr bs)) = Just $ unpack bs
49 maybeBstrToString _ = Nothing
51 mkMetaInfo :: BVal -> Maybe Metainfo
52 mkMetaInfo (Bdict m) = let (Just info') = mkInfo $ m ! "info"
53 announce' = lookup "announce" m
54 announceList' = lookup "announce-list" m
55 -- creationDate = lookup (Bstr (pack "creation date")) m
56 creationDate' = Nothing
57 comment' = lookup "comment" m
58 createdBy' = lookup "created by" m
59 encoding' = lookup "encoding" m
60 in Just Metainfo { info = info'
61 , announceList = maybeToList (announce' >>= bstrToString)
62 ++ getAnnounceList announceList'
63 , creationDate = creationDate'
64 , comment = maybeBstrToString comment'
65 , createdBy = maybeBstrToString createdBy'
66 , encoding = maybeBstrToString encoding'
68 mkMetaInfo _ = Nothing
70 getAnnounceList :: Maybe BVal -> [String]
71 getAnnounceList Nothing = []
72 getAnnounceList (Just (Bint _)) = []
73 getAnnounceList (Just (Bstr _)) = []
74 getAnnounceList (Just (Blist l)) = map (\s -> case s of
75 (Bstr s') -> unpack s'
76 (Blist s') -> case s' of
77 [Bstr s''] -> unpack s''
81 getAnnounceList (Just (Bdict _)) = []