module Geography.Geocoding.Google.Get (get, maybeGet, eitherGet, timeoutGet) where
import Data.Char (intToDigit)
import Control.Concurrent ( threadDelay, newEmptyMVar, myThreadId
, forkIO, putMVar, killThread, takeMVar )
import Network.HTTP ( simpleHTTP, insertHeaders, Header (..), HeaderName (..)
, Request (..), RequestMethod (..), rspBody )
import Network.URI (parseURI, URI)
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (hPutStrLn, stderr)
import Control.Exception (catch, SomeException)
err :: String -> IO a
err msg = do
hPutStrLn stderr msg
exitFailure
get :: URI -> IO String
get uri = do
eresp <- simpleHTTP $ insertHeaders [Header HdrAccept "*/*"]
(Request uri GET [] "")
case eresp of
Left er -> fail $ show er
Right res -> return $ rspBody res
maybeGet :: URI -> IO (Maybe String)
maybeGet uri = either (const Nothing) Just `fmap` eitherGet uri
eitherGet :: URI -> IO (Either String String)
eitherGet uri = timeoutGet uri
waitTimeout = 10000000
timeoutGet :: URI -> IO (Either String String)
timeoutGet uri = do
mv <- newEmptyMVar
mid <- myThreadId
tid1 <- forkIO $ do
x <- get uri
putMVar mv $ Right x
`catch` (\ e -> putMVar mv . Left . show $ (e :: SomeException))
tid2 <- forkIO $ do
threadDelay waitTimeout
killThread tid1
putMVar mv (Left "timeout")
takeMVar mv