8
8
{-# LANGUAGE RankNTypes #-}
9
9
{-# LANGUAGE GADTs #-}
10
10
{-# LANGUAGE StandaloneDeriving #-}
11
+ {-# LANGUAGE TemplateHaskell #-}
11
12
module Network.HTTP.Download.Verified
12
13
( verifiedDownload
13
14
, recoveringHttp
@@ -19,38 +20,41 @@ module Network.HTTP.Download.Verified
19
20
, VerifiedDownloadException (.. )
20
21
) where
21
22
22
- import qualified Data.List as List
23
- import qualified Data.ByteString as ByteString
24
- import qualified Data.ByteString.Base64 as B64
25
- import qualified Data.Conduit.Binary as CB
26
- import qualified Data.Conduit.List as CL
27
- import qualified Data.Text as Text
28
- import qualified Data.Text.Encoding as Text
23
+ import qualified Data.List as List
24
+ import qualified Data.ByteString as ByteString
25
+ import qualified Data.ByteString.Base64 as B64
26
+ import qualified Data.Conduit.Binary as CB
27
+ import qualified Data.Conduit.List as CL
28
+ import qualified Data.Text as Text
29
+ import qualified Data.Text.Encoding as Text
29
30
30
- import Control.Monad
31
- import Control.Monad.Catch
32
- import Control.Monad.IO.Class
33
- import Control.Monad.Reader
34
- import Control.Retry (recovering ,limitRetries ,RetryPolicy ,constantDelay )
35
- import Control.Applicative
31
+ import Control.Applicative
32
+ import Control.Monad
33
+ import Control.Monad.Catch
34
+ import Control.Monad.IO.Class
35
+ import Control.Monad.Logger (logDebug , MonadLogger )
36
+ import Control.Monad.Reader
37
+ import Control.Retry (recovering ,limitRetries ,RetryPolicy ,constantDelay )
36
38
import "cryptohash" Crypto.Hash
37
- import Crypto.Hash.Conduit (sinkHash )
38
- import Data.ByteString (ByteString )
39
- import Data.ByteString.Char8 (readInteger )
40
- import Data.Conduit
41
- import Data.Conduit.Binary (sourceHandle , sinkHandle )
42
- import Data.Foldable (traverse_ ,for_ )
43
- import Data.Monoid
44
- import Data.String
45
- import Data.Typeable (Typeable )
46
- import GHC.IO.Exception (IOException (.. ),IOErrorType (.. ))
47
- import Network.HTTP.Client.Conduit
48
- import Network.HTTP.Types.Header (hContentLength , hContentMD5 )
49
- import Path
50
- import Prelude -- Fix AMP warning
51
- import System.FilePath ((<.>) )
52
- import System.Directory
53
- import System.IO
39
+ import Crypto.Hash.Conduit (sinkHash )
40
+ import Data.ByteString (ByteString )
41
+ import Data.ByteString.Char8 (readInteger )
42
+ import Data.Conduit
43
+ import Data.Conduit.Binary (sourceHandle , sinkHandle )
44
+ import Data.Foldable (traverse_ ,for_ )
45
+ import Data.Monoid
46
+ import Data.String
47
+ import Data.Text.Encoding (decodeUtf8With )
48
+ import Data.Text.Encoding.Error (lenientDecode )
49
+ import Data.Typeable (Typeable )
50
+ import GHC.IO.Exception (IOException (.. ),IOErrorType (.. ))
51
+ import Network.HTTP.Client.Conduit
52
+ import Network.HTTP.Types.Header (hContentLength , hContentMD5 )
53
+ import Path
54
+ import Prelude -- Fix AMP warning
55
+ import System.Directory
56
+ import System.FilePath ((<.>) )
57
+ import System.IO
54
58
55
59
-- | A request together with some checks to perform.
56
60
data DownloadRequest = DownloadRequest
@@ -215,21 +219,23 @@ recoveringHttp retryPolicy =
215
219
-- Throws VerifiedDownloadException.
216
220
-- Throws IOExceptions related to file system operations.
217
221
-- Throws HttpException.
218
- verifiedDownload :: (MonadReader env m , HasHttpManager env , MonadIO m )
222
+ verifiedDownload :: (MonadReader env m , HasHttpManager env , MonadIO m , MonadLogger m )
219
223
=> DownloadRequest
220
224
-> Path Abs File -- ^ destination
221
225
-> (Maybe Integer -> Sink ByteString (ReaderT env IO ) () ) -- ^ custom hook to observe progress
222
226
-> m Bool -- ^ Whether a download was performed
223
227
verifiedDownload DownloadRequest {.. } destpath progressSink = do
224
228
let req = drRequest
225
229
env <- ask
226
- liftIO $ whenM' getShouldDownload $ do
227
- createDirectoryIfMissing True dir
228
- withBinaryFile fptmp WriteMode $ \ h ->
229
- recoveringHttp drRetryPolicy $
230
- flip runReaderT env $
231
- withResponse req (go h)
232
- renameFile fptmp fp
230
+ whenM' (liftIO getShouldDownload) $ do
231
+ $ logDebug $ " Downloading " <> decodeUtf8With lenientDecode (path req)
232
+ liftIO $ do
233
+ createDirectoryIfMissing True dir
234
+ withBinaryFile fptmp WriteMode $ \ h ->
235
+ recoveringHttp drRetryPolicy $
236
+ flip runReaderT env $
237
+ withResponse req (go h)
238
+ renameFile fptmp fp
233
239
where
234
240
whenM' mp m = do
235
241
p <- mp
0 commit comments