diff options
Diffstat (limited to 'src/Network/Torrent/Tracker')
-rw-r--r-- | src/Network/Torrent/Tracker/Scrape.hs | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/src/Network/Torrent/Tracker/Scrape.hs b/src/Network/Torrent/Tracker/Scrape.hs index 2d1dec07..6bfb488f 100644 --- a/src/Network/Torrent/Tracker/Scrape.hs +++ b/src/Network/Torrent/Tracker/Scrape.hs | |||
@@ -1,8 +1,62 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
1 | module Network.Torrent.Tracker.Scrape | 2 | module Network.Torrent.Tracker.Scrape |
2 | ( | 3 | ( ScrapeInfo(..), Scrape |
4 | , scrapeURL | ||
3 | ) where | 5 | ) where |
4 | 6 | ||
7 | import Control.Applicative | ||
8 | import Data.BEncode | ||
9 | import Data.ByteString (ByteString) | ||
10 | import qualified Data.ByteString as B | ||
11 | import qualified Data.ByteString.Char8 as BC | ||
12 | import Data.Map (Map) | ||
13 | import qualified Data.Map as M | ||
14 | import Data.Monoid | ||
15 | import Data.Torrent.InfoHash | ||
5 | import Network.URI | 16 | import Network.URI |
6 | 17 | ||
7 | scrapeURL :: URI -> Maybe URI | 18 | data ScrapeInfo = ScrapeInfo { |
8 | scrapeURL = undefined | 19 | siComplete :: Int -- ^ Number of seeders. |
20 | , siDownloaded :: Int | ||
21 | -- ^ Total number of times the tracker has registered a completion. | ||
22 | , siIncomplete :: Int -- ^ Number of leechers | ||
23 | , siName :: Maybe ByteString -- ^ | ||
24 | } deriving (Show, Eq) | ||
25 | |||
26 | type Scrape = Map InfoHash ScrapeInfo | ||
27 | |||
28 | instance BEncodable ScrapeInfo where | ||
29 | toBEncode si = fromAssocs | ||
30 | [ "complete" --> siComplete si | ||
31 | , "downloaded" --> siDownloaded si | ||
32 | , "incomplete" --> siIncomplete si | ||
33 | , "name" -->? siName si | ||
34 | ] | ||
35 | |||
36 | fromBEncode (BDict d) = | ||
37 | ScrapeInfo <$> d >-- "complete" | ||
38 | <*> d >-- "downloaded" | ||
39 | <*> d >-- "incomplete" | ||
40 | <*> d >--? "name" | ||
41 | fromBEncode _ = decodingError "ScrapeInfo" | ||
42 | |||
43 | -- TODO: encode info hash | ||
44 | -- | Trying to convert /announce/ URL to /scrape/ URL. If 'scrapeURL' | ||
45 | -- gives 'Nothing' then tracker do not support scraping. The info hash | ||
46 | -- list is used to restrict the tracker's report to that particular | ||
47 | -- torrents. Note that scrapping of multiple torrents may not be | ||
48 | -- supported. (Even if scrapping convention is supported) | ||
49 | -- | ||
50 | scrapeURL :: URI -> [InfoHash] -> Maybe URI | ||
51 | scrapeURL uri ihs = do | ||
52 | newPath <- replace (BC.pack (uriPath uri)) | ||
53 | let newURI = uri { uriPath = BC.unpack newPath } | ||
54 | return (foldl addHashToURI newURI ihs) | ||
55 | where | ||
56 | replace :: ByteString -> Maybe ByteString | ||
57 | replace p | ||
58 | | ps <- BC.splitWith (== '/') p | ||
59 | , "announce" `B.isPrefixOf` last ps | ||
60 | = let newSuff = "scrape" <> B.drop (B.length "announce") (last ps) | ||
61 | in Just (B.intercalate "/" (init ps ++ [newSuff])) | ||
62 | | otherwise = Nothing | ||