Create a gist now

Instantly share code, notes, and snippets.

@adinapoli /progbar.hs Secret
Last active Dec 19, 2015

{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Main where
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C8
import System.IO.Streams (InputStream, OutputStream)
import qualified System.IO.Streams as S
import Network.Http.Client
import Text.Printf (printf)
withProgressBar :: Integer -> InputStream ByteString -> OutputStream ByteString -> IO ()
withProgressBar fileSize inS outS = go (0 :: Int)
where
go blocksRead = do
block <- S.read inS
case block of
(Just d) -> do
let currentBlocks = blocksRead + B.length d
let percentage = fromIntegral (currentBlocks * 100) / fromIntegral fileSize
printf "%10d [%3.2f%%]\r" currentBlocks (percentage :: Double)
S.write (Just d) outS >> go currentBlocks
Nothing -> return ()
-- Note for the Windows user: you need withSocketsDo before get, like
-- withSocketsDo $ get ...
downloadFile :: URL -> FilePath -> IO ()
downloadFile url name = get url $ \response inStream ->
case getStatusCode response of
200 -> let fileSize = maybe 0 (\fs -> read (C8.unpack fs) :: Integer)
(getHeader response "Content-Length")
in S.withFileAsOutput name (withProgressBar fileSize inStream)
code -> error $ "Failed to download " ++ name ++ ": http response returned " ++ show code
main :: IO ()
main = do
let url = "http://audacity.googlecode.com/files/audacity-macosx-ub-2.0.3.dmg"
print $ "Downloading " ++ url
downloadFile (C8.pack url) "audacity.dmg"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment