diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-08-28 02:38:21 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-08-28 02:38:21 +0400 |
commit | 54b20f9ac462105cd3857b9c8102954a725ef308 (patch) | |
tree | f4c66aef69be9ece2e37a21c206186feb15be5d0 /src/Network/BitTorrent/Peer.hs | |
parent | 20db22d1b09079b88e95e5054df2589fa956fc01 (diff) |
~ Group AnnounceQuery progress fields to Progress.
Diffstat (limited to 'src/Network/BitTorrent/Peer.hs')
-rw-r--r-- | src/Network/BitTorrent/Peer.hs | 88 |
1 files changed, 85 insertions, 3 deletions
diff --git a/src/Network/BitTorrent/Peer.hs b/src/Network/BitTorrent/Peer.hs index a4d026dc..d951a1cd 100644 --- a/src/Network/BitTorrent/Peer.hs +++ b/src/Network/BitTorrent/Peer.hs | |||
@@ -28,6 +28,7 @@ | |||
28 | -- capabilities (such as supported enchancements), this should be | 28 | -- capabilities (such as supported enchancements), this should be |
29 | -- done using 'Network.BitTorrent.Extension'! | 29 | -- done using 'Network.BitTorrent.Extension'! |
30 | -- | 30 | -- |
31 | {-# LANGUAGE ViewPatterns #-} | ||
31 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | 32 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} |
32 | {-# LANGUAGE StandaloneDeriving #-} | 33 | {-# LANGUAGE StandaloneDeriving #-} |
33 | {-# LANGUAGE TemplateHaskell #-} | 34 | {-# LANGUAGE TemplateHaskell #-} |
@@ -56,6 +57,19 @@ module Network.BitTorrent.Peer | |||
56 | , connectToPeer | 57 | , connectToPeer |
57 | , ppPeer | 58 | , ppPeer |
58 | 59 | ||
60 | -- * Peer progress | ||
61 | , Progress (..) | ||
62 | , left | ||
63 | , uploaded | ||
64 | , downloaded | ||
65 | |||
66 | , startProgress | ||
67 | |||
68 | , downloadedProgress | ||
69 | , enqueuedProgress | ||
70 | , uploadedProgress | ||
71 | , dequeuedProgress | ||
72 | |||
59 | -- * Client version detection | 73 | -- * Client version detection |
60 | -- ** Info | 74 | -- ** Info |
61 | , ClientInfo(..), clientInfo, ppClientInfo, unknownClient | 75 | , ClientInfo(..), clientInfo, ppClientInfo, unknownClient |
@@ -70,18 +84,19 @@ module Network.BitTorrent.Peer | |||
70 | 84 | ||
71 | 85 | ||
72 | import Control.Applicative | 86 | import Control.Applicative |
87 | import Control.Lens | ||
73 | import Data.Aeson | 88 | import Data.Aeson |
74 | import Data.Aeson.TH | 89 | import Data.Aeson.TH |
75 | import Data.BEncode | 90 | import Data.BEncode |
76 | import Data.Bits | 91 | import Data.Bits |
77 | import Data.Char | ||
78 | import Data.List as L | ||
79 | import Data.Word | ||
80 | import Data.ByteString (ByteString) | 92 | import Data.ByteString (ByteString) |
81 | import qualified Data.ByteString as B | 93 | import qualified Data.ByteString as B |
82 | import qualified Data.ByteString.Char8 as BC | 94 | import qualified Data.ByteString.Char8 as BC |
83 | import qualified Data.ByteString.Lazy as BL | 95 | import qualified Data.ByteString.Lazy as BL |
84 | import qualified Data.ByteString.Lazy.Builder as B | 96 | import qualified Data.ByteString.Lazy.Builder as B |
97 | import Data.Char | ||
98 | import Data.List as L | ||
99 | import Data.Word | ||
85 | import Data.Foldable (foldMap) | 100 | import Data.Foldable (foldMap) |
86 | import Data.Monoid ((<>)) | 101 | import Data.Monoid ((<>)) |
87 | import Data.Serialize | 102 | import Data.Serialize |
@@ -577,3 +592,70 @@ ppPeer p @ PeerAddr {..} = case peerID of | |||
577 | Nothing -> paddr | 592 | Nothing -> paddr |
578 | where | 593 | where |
579 | paddr = text (show (peerSockAddr p)) | 594 | paddr = text (show (peerSockAddr p)) |
595 | |||
596 | {----------------------------------------------------------------------- | ||
597 | Progress | ||
598 | -----------------------------------------------------------------------} | ||
599 | |||
600 | -- TODO: Use Word64? | ||
601 | -- TODO: Use atomic bits? | ||
602 | |||
603 | -- | 'Progress' contains upload/download/left stats about | ||
604 | -- current client state and used to notify the tracker. | ||
605 | -- | ||
606 | -- Progress data is considered as dynamic within one client | ||
607 | -- session. This data also should be shared across client application | ||
608 | -- sessions (e.g. files), otherwise use 'startProgress' to get initial | ||
609 | -- 'Progress'. | ||
610 | -- | ||
611 | data Progress = Progress | ||
612 | { _downloaded :: !Integer -- ^ Total amount of bytes downloaded; | ||
613 | , _left :: !Integer -- ^ Total amount of bytes left; | ||
614 | , _uploaded :: !Integer -- ^ Total amount of bytes uploaded. | ||
615 | } deriving (Show, Read, Eq) | ||
616 | |||
617 | $(makeLenses ''Progress) | ||
618 | $(deriveJSON (L.tail) ''Progress) | ||
619 | |||
620 | instance Serialize Progress where | ||
621 | put Progress {..} = do | ||
622 | putWord64be $ fromIntegral _downloaded | ||
623 | putWord64be $ fromIntegral _left | ||
624 | putWord64be $ fromIntegral _uploaded | ||
625 | |||
626 | get = Progress | ||
627 | <$> (fromIntegral <$> getWord64be) | ||
628 | <*> (fromIntegral <$> getWord64be) | ||
629 | <*> (fromIntegral <$> getWord64be) | ||
630 | |||
631 | -- | Initial progress is used when there are no session before. | ||
632 | -- | ||
633 | -- Please note that tracker might penalize client some way if the do | ||
634 | -- not accumulate progress. If possible and save 'Progress' between | ||
635 | -- client sessions to avoid that. | ||
636 | -- | ||
637 | startProgress :: Integer -> Progress | ||
638 | startProgress = Progress 0 0 | ||
639 | |||
640 | -- | Used when the client download some data from /any/ peer. | ||
641 | downloadedProgress :: Int -> Progress -> Progress | ||
642 | downloadedProgress (fromIntegral -> amount) | ||
643 | = (left -~ amount) | ||
644 | . (downloaded +~ amount) | ||
645 | {-# INLINE downloadedProgress #-} | ||
646 | |||
647 | -- | Used when the client upload some data to /any/ peer. | ||
648 | uploadedProgress :: Int -> Progress -> Progress | ||
649 | uploadedProgress (fromIntegral -> amount) = uploaded +~ amount | ||
650 | {-# INLINE uploadedProgress #-} | ||
651 | |||
652 | -- | Used when leecher join client session. | ||
653 | enqueuedProgress :: Integer -> Progress -> Progress | ||
654 | enqueuedProgress amount = left +~ amount | ||
655 | {-# INLINE enqueuedProgress #-} | ||
656 | |||
657 | -- | Used when leecher leave client session. | ||
658 | -- (e.g. user deletes not completed torrent) | ||
659 | dequeuedProgress :: Integer -> Progress -> Progress | ||
660 | dequeuedProgress amount = left -~ amount | ||
661 | {-# INLINE dequeuedProgress #-} | ||