aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2020-04-19 12:26:49 +0200
committerIgor Pashev <pashev.igor@gmail.com>2020-04-19 16:30:08 +0200
commit0b1981ef40404802a828f2a91ecadba3c2453034 (patch)
tree4471665b7598940cf75b954e78d49cfcce8d4453 /lib
parent3f86e251e8566c36e75bb5b6f8657ad5e0d120dd (diff)
downloadopenweathermap-0b1981ef40404802a828f2a91ecadba3c2453034.tar.gz
Add forecast weather API
Diffstat (limited to 'lib')
-rw-r--r--lib/Web/OpenWeatherMap/API.hs26
-rw-r--r--lib/Web/OpenWeatherMap/Client.hs22
-rw-r--r--lib/Web/OpenWeatherMap/Types/City.hs21
-rw-r--r--lib/Web/OpenWeatherMap/Types/Coord.hs4
-rw-r--r--lib/Web/OpenWeatherMap/Types/Forecast.hs23
-rw-r--r--lib/Web/OpenWeatherMap/Types/ForecastWeather.hs20
6 files changed, 105 insertions, 11 deletions
diff --git a/lib/Web/OpenWeatherMap/API.hs b/lib/Web/OpenWeatherMap/API.hs
index 8a1690e..6d06421 100644
--- a/lib/Web/OpenWeatherMap/API.hs
+++ b/lib/Web/OpenWeatherMap/API.hs
@@ -8,6 +8,8 @@ For API key (a.k.a appid) refer to <http://openweathermap.org/appid>.
module Web.OpenWeatherMap.API
( weatherByName
, weatherByCoord
+ , forecastByName
+ , forecastByCoord
) where
import Data.Proxy (Proxy(..))
@@ -16,14 +18,22 @@ import Servant.API ((:<|>)(..), (:>), Get, JSON, QueryParam)
import Servant.Client (ClientM, client)
import Web.OpenWeatherMap.Types.CurrentWeather (CurrentWeather)
+import Web.OpenWeatherMap.Types.ForecastWeather (ForecastWeather)
type GetCurrentWeather = AppId :> Get '[ JSON] CurrentWeather
+type GetForecastWeather = AppId :> Get '[ JSON] ForecastWeather
+
type AppId = QueryParam "appid" String
-type API
+type Current
= "weather" :> QueryParam "q" String :> GetCurrentWeather :<|> "weather" :> QueryParam "lat" Double :> QueryParam "lon" Double :> GetCurrentWeather
+type Forecast
+ = "forecast" :> QueryParam "q" String :> GetForecastWeather :<|> "forecast" :> QueryParam "lat" Double :> QueryParam "lon" Double :> GetForecastWeather
+
+type API = Current :<|> Forecast
+
-- | Request current weather in the city.
weatherByName ::
Maybe String -- ^ City name, e. g. \"Moscow\" or \"Moscow,ru\".
@@ -35,4 +45,16 @@ weatherByCoord ::
-> Maybe Double -- ^ Longitude, e. g. 37.6155600 for Moscow.
-> Maybe String -- ^ API key.
-> ClientM CurrentWeather
-weatherByName :<|> weatherByCoord = client (Proxy :: Proxy API)
+-- | Request forecast weather in the city.
+forecastByName ::
+ Maybe String -- ^ City name, e. g. \"Moscow\" or \"Moscow,ru\".
+ -> Maybe String -- ^ API key.
+ -> ClientM ForecastWeather
+-- | Request current weather at the geographic coordinates (in decimal degrees).
+forecastByCoord ::
+ Maybe Double -- ^ Latitude, e. g. 55.7522200 for Moscow.
+ -> Maybe Double -- ^ Longitude, e. g. 37.6155600 for Moscow.
+ -> Maybe String -- ^ API key.
+ -> ClientM ForecastWeather
+(weatherByName :<|> weatherByCoord) :<|> (forecastByName :<|> forecastByCoord) =
+ client (Proxy :: Proxy API)
diff --git a/lib/Web/OpenWeatherMap/Client.hs b/lib/Web/OpenWeatherMap/Client.hs
index c7ad7b6..445e2a4 100644
--- a/lib/Web/OpenWeatherMap/Client.hs
+++ b/lib/Web/OpenWeatherMap/Client.hs
@@ -4,6 +4,7 @@ High-level client functions perfoming requests to OpenWeatherMap API.
module Web.OpenWeatherMap.Client
( Location(..)
, getWeather
+ , getForecast
) where
import Network.HTTP.Client (defaultManagerSettings, newManager)
@@ -11,7 +12,6 @@ import Servant.Client
( BaseUrl(BaseUrl)
, ClientEnv
, ClientError
- , ClientM
, Scheme(Http)
, mkClientEnv
, runClientM
@@ -19,6 +19,7 @@ import Servant.Client
import qualified Web.OpenWeatherMap.API as API
import Web.OpenWeatherMap.Types.CurrentWeather (CurrentWeather)
+import Web.OpenWeatherMap.Types.ForecastWeather (ForecastWeather)
-- | Various way to specify location.
data Location
@@ -33,13 +34,20 @@ getWeather ::
-> Location
-> IO (Either ClientError CurrentWeather)
getWeather appid loc = defaultEnv >>= runClientM (api loc appid)
+ where
+ api (Name city) = API.weatherByName (Just city) . Just
+ api (Coord lat lon) = API.weatherByCoord (Just lat) (Just lon) . Just
-api ::
- Location
- -> String -- ^ API key.
- -> ClientM CurrentWeather
-api (Name city) = API.weatherByName (Just city) . Just
-api (Coord lat lon) = API.weatherByCoord (Just lat) (Just lon) . Just
+-- | Make a request to OpenWeatherMap API
+-- and return forecast weather in given location.
+getForecast ::
+ String -- ^ API key.
+ -> Location
+ -> IO (Either ClientError ForecastWeather)
+getForecast appid loc = defaultEnv >>= runClientM (api loc appid)
+ where
+ api (Name city) = API.forecastByName (Just city) . Just
+ api (Coord lat lon) = API.forecastByCoord (Just lat) (Just lon) . Just
defaultEnv :: IO ClientEnv
defaultEnv = do
diff --git a/lib/Web/OpenWeatherMap/Types/City.hs b/lib/Web/OpenWeatherMap/Types/City.hs
new file mode 100644
index 0000000..bb6cd6d
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/City.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.City
+ ( City(..)
+ ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.Coord (Coord)
+
+data City = City
+ { name :: String
+ , country :: Maybe String
+ , coord :: Coord
+ , timezone :: Int
+ , sunset :: Int
+ , sunrise :: Int
+ } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/Coord.hs b/lib/Web/OpenWeatherMap/Types/Coord.hs
index 517c532..0751964 100644
--- a/lib/Web/OpenWeatherMap/Types/Coord.hs
+++ b/lib/Web/OpenWeatherMap/Types/Coord.hs
@@ -10,6 +10,6 @@ import GHC.Generics (Generic)
import Data.Aeson (FromJSON)
data Coord = Coord
- { lon :: Double
- , lat :: Double
+ { lon :: Maybe Double
+ , lat :: Maybe Double
} deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/Forecast.hs b/lib/Web/OpenWeatherMap/Types/Forecast.hs
new file mode 100644
index 0000000..3434930
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/Forecast.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.Forecast
+ ( Forecast(..)
+ ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.Clouds (Clouds)
+import Web.OpenWeatherMap.Types.Main (Main)
+import Web.OpenWeatherMap.Types.Weather (Weather)
+import Web.OpenWeatherMap.Types.Wind (Wind)
+
+data Forecast = Forecast
+ { dt :: Int
+ , clouds :: Clouds
+ , main :: Main
+ , weather :: [Weather]
+ , wind :: Wind
+ } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs b/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs
new file mode 100644
index 0000000..fa8e50a
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.ForecastWeather
+ ( ForecastWeather(..)
+ ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.City (City)
+import Web.OpenWeatherMap.Types.Forecast (Forecast)
+
+-- | Response to requests for forecast weather.
+-- Refer to <https://openweathermap.org/forecast5>.
+data ForecastWeather = ForecastWeather
+ { list :: [Forecast]
+ , city :: City
+ } deriving (Show, Generic, FromJSON)