module Text.Hastily.Network (
getFrom,
getFromUrlAndDo
) where
import Control.Concurrent.Thread.Delay (delay)
import Control.Exception
import Control.Monad.Catch hiding (try)
import Data.ByteString.Char8 hiding (putStrLn)
import qualified Data.ByteString.Lazy as LZ
import Data.String.Conversions
import Data.Text (Text)
import Network.HTTP.Client
makeGetRequestObject :: Control.Monad.Catch.MonadThrow m => String -> [(Text, Text)] -> m Request
makeGetRequestObject url query_pairs = do
r <- parseUrl url
return $ setQueryString (makeBST query_pairs) r
where
makeBST :: [(Text, Text)] -> [(ByteString, Maybe ByteString)]
makeBST st = fmap makeBST' st
where
makeBST' :: (Text, Text) -> (ByteString, Maybe ByteString)
makeBST' (a1, a2) = (pack $ (cs a1::String), Just $ pack $ (cs a2::String))
getFrom :: String -> [(Text, Text)] -> IO (Either SomeException LZ.ByteString)
getFrom url query_pairs =
getFrom' url query_pairs 0
where
getFrom' :: String -> [(Text, Text)] -> Integer -> IO (Either SomeException LZ.ByteString)
getFrom' url query_pairs attempt_count = do
manager <- newManager defaultManagerSettings
request <- makeGetRequestObject url query_pairs
either_response <- try $ httpLbs request manager :: IO (Either SomeException (Response LZ.ByteString))
case either_response of
Left err -> do
showErr err
if attempt_count < 5
then getFrom' url query_pairs (attempt_count + 1)
else return $ Left err
Right response -> return $ Right $ responseBody response
getFromUrlAndDo :: String -> [(Text, Text)] -> (Response BodyReader -> IO b) -> IO (Either SomeException b)
getFromUrlAndDo url query_pairs func = getFromUrlAndDo' url query_pairs func 0
where
getFromUrlAndDo' :: String -> [(Text, Text)] -> (Response BodyReader -> IO b) -> Integer -> IO (Either SomeException b)
getFromUrlAndDo' url query_pairs func attempt_count = do
manager <- newManager defaultManagerSettings
request <- makeGetRequestObject url query_pairs
either_result <- try $ withResponse request manager func
case either_result of
Left err -> do
showErr err
if attempt_count < 5
then getFromUrlAndDo' url query_pairs func (attempt_count + 1)
else return $ Left err
Right result -> return $ Right result
showErr :: SomeException -> IO ()
showErr err = do
putStrLn $ show err
putStrLn "Retrying in 5 seconds.."
delay 5000000