{-# LANGUAGE OverloadedStrings #-} --needed for ByteString arguments import Network.HTTP.Simple import System.Environment (lookupEnv) import Plot import Data.ByteString.UTF8 (fromString) --to convert acquired API key to ByteString import Data.Time data WhichDay = Yesterday | Today | Tomorrow deriving (Show, Eq) main :: IO () main = do apiKey <- getWeatherKey generatePlot 20 35 25 --example putStrLn "Enter a city name: " city <- getLine let cityRequest = apiRequestCity apiKey city cityResponse <- httpLBS cityRequest if getResponseBody cityResponse == "[]" || getResponseStatusCode cityResponse /= 200 then error "City not found!" else do currentDate <- getCurrentDate let yesterdayDate = formatDate $ addDays (-1) currentDate let todayDate = formatDate currentDate let tomorrowDate = formatDate $ addDays 1 currentDate let yesterdayRequest = apiRequestBuilder apiKey Yesterday city yesterdayDate yesterdayResponse <- httpLBS yesterdayRequest putStrLn $ show yesterdayRequest putStrLn $ show $ getResponseStatusCode yesterdayResponse let todayRequest = apiRequestBuilder apiKey Today city todayDate todayResponse <- httpLBS todayRequest putStrLn $ show todayRequest putStrLn $ show $ getResponseStatusCode todayResponse let tomorrowRequest = apiRequestBuilder apiKey Tomorrow city tomorrowDate tomorrowResponse <- httpLBS tomorrowRequest putStrLn $ show tomorrowRequest putStrLn $ show $ getResponseStatusCode tomorrowResponse --apiResponse <- httpJSON "http://httpbin.org/get" :: IO (Response ()) -- specifying type as httpJSON return value is ambigious --apiKey is stored in an env variable, not something that should be pushed onto git getWeatherKey :: IO String getWeatherKey = do result <- lookupEnv "WEATHER_API_KEY" case result of Just a -> return a Nothing -> error "API key not set in environmental variables!" -- exception thrown (but not handled) per project requirement apiRequestCity :: String -> String -> Request apiRequestCity apiKey city = setRequestHost "api.weatherapi.com" $ setRequestPath "/v1/search.json" $ setRequestMethod "GET" $ setRequestQueryString [("key", Just (fromString apiKey)), ("q", Just (fromString city))] $ setRequestPort 443 $ setRequestSecure True $ defaultRequest apiRequestBuilder :: String -> WhichDay -> String -> String -> Request apiRequestBuilder apiKey day city date = setRequestHost "api.weatherapi.com" $ setRequestPath path $ setRequestMethod "GET" $ setRequestQueryString query $ setRequestPort 443 $ setRequestSecure True $ defaultRequest where { path | day == Yesterday = "/v1/history.json" | day == Today = "/v1/current.json" | day == Tomorrow = "/v1/forecast.json" | otherwise = error "Invalid day argument!"; query | day == Yesterday = [("key", Just (fromString apiKey)), ("q", Just (fromString city)), ("dt", Just (fromString date))] | day == Today = [("key", Just (fromString apiKey)), ("q", Just (fromString city))] | day == Tomorrow = [("key", Just (fromString apiKey)), ("q", Just (fromString city)), ("dt", Just (fromString date)), ("days", Just (fromString "1"))] | otherwise = error "Invalid day argument!"; } getCurrentDate :: IO Day getCurrentDate = do currentTime <- getCurrentTime timeZone <- getCurrentTimeZone let localTime = utcToLocalTime timeZone currentTime let currentDate = localDay localTime return currentDate formatDate :: Day -> String formatDate = formatTime defaultTimeLocale "%Y-%m-%d"