Weather (empty) → 0.1.0.0
raw patch · 6 files changed
+204/−0 lines, 6 filesdep +HTTPdep +aesondep +basesetup-changed
Dependencies added: HTTP, aeson, base, bytestring, text, unordered-containers
Files
- LICENSE +28/−0
- README.md +45/−0
- Setup.hs +2/−0
- Weather.cabal +30/−0
- Weather.cabal~ +31/−0
- src/Web/Weather.hs +68/−0
+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2015, Bryan St. Amour+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++* Neither the name of weather nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ README.md view
@@ -0,0 +1,45 @@+# weather+Haskell library for working with the Weather Underground JSON API.++Currently only supports querying for conditions for US-based cities.++Example usage:++```haskell+{-# LANGUAGE RecordWildCards #-}++module Main where++import Web.Weather++mykey :: APIKey+mykey = "top-secret"++mycity, mystate :: String+mycity = "Detroit"+mystate = "MI"++main :: IO ()+main = do+ resp <- getConditions mykey mycity mystate+ case resp of+ Nothing -> putStrLn "No data for that city/state"+ Just (Observation{..}) -> do+ putStrLn $ "Observation time: " ++ obsTime+ putStrLn $ "Weather conditions: " ++ obsWeather+ putStrLn $ "Temp: " ++ show obsTemp+ putStrLn $ "Rel humidity: " ++ show obsRelHumidity+ putStrLn $ "Wind: " ++ obsWind+ putStrLn $ "Feels like: " ++ obsFeelsLike+```++Output:++```+Observation time: Last Updated on April 10, 2:09 PM EDT+Weather conditions: Partly Cloudy+Temp: 52.9+Rel humidity: "60%"+Wind: From the West at 4.7 MPH+Feels like: 52.9 F (11.6 C)+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Weather.cabal view
@@ -0,0 +1,30 @@+-- Initial weather.cabal generated by cabal init. For further+-- documentation, see http://haskell.org/cabal/users-guide/++name: Weather+version: 0.1.0.0+synopsis: Library for interacting with the Weather Underground JSON API.+description: Weather is a simple library for interacting with the Weather Underground JSON API. It is not complete, but it may be useful still.+homepage: http://bryanstamour.com+license: BSD3+license-file: LICENSE+author: Bryan St. Amour+maintainer: bryan@bryanstamour.com+-- copyright:+category: Web+build-type: Simple+-- extra-source-files:+cabal-version: >=1.10++library+ exposed-modules: Web.Weather+ -- other-modules:+ -- other-extensions:+ build-depends: base >= 4.7.0.2 && < 5+ , HTTP >= 4000.2.12+ , text >= 1.1.0.1+ , unordered-containers >= 0.2.5.1+ , aeson >= 0.8.0.2+ , bytestring >= 0.10.4.0+ hs-source-dirs: src+ default-language: Haskell2010
+ Weather.cabal~ view
@@ -0,0 +1,31 @@+-- Initial weather.cabal generated by cabal init. For further+-- documentation, see http://haskell.org/cabal/users-guide/++name: Weather+version: 0.1.0.0+synopsis: Library for interacting with the Weather Underground JSON API.+description: Weather is a simple library for interacting with the Weather Underground \+JSON API. It is not complete, but it may be useful still.+homepage: http://bryanstamour.com+license: BSD3+license-file: LICENSE+author: Bryan St. Amour+maintainer: bryan@bryanstamour.com+-- copyright:+category: Web+build-type: Simple+-- extra-source-files:+cabal-version: >=1.10++library+ exposed-modules: Web.Weather+ -- other-modules:+ -- other-extensions:+ build-depends: base >= 4.7.0.2 && < 5+ , HTTP >= 4000.2.12+ , text >= 1.1.0.1+ , unordered-containers >= 0.2.5.1+ , aeson >= 0.8.0.2+ , bytestring >= 0.10.4.0+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Web/Weather.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE OverloadedStrings #-}++module Web.Weather+ ( Observation(..)+ , APIKey+ , getConditions+ ) where++import Control.Monad+import Control.Applicative++import Data.Text (Text)+import Data.Aeson+import Data.ByteString.Lazy.Char8 (pack)+import Network.HTTP (getResponseBody, simpleHTTP, getRequest)++import qualified Data.HashMap.Strict as H++-- | Observation data.+data Observation =+ Observation { obsTime :: String -- ^ The time the observation was taken.+ , obsWeather :: String -- ^ Description of the weather.+ , obsTemp :: Float -- ^ Temperature (F).+ , obsRelHumidity :: String -- ^ Relative humidity (%).+ , obsWind :: String -- ^ Wind condition.+ , obsFeelsLike :: String -- ^ What it feels like.+ } deriving (Show)++instance FromJSON Observation where+ parseJSON (Object v) = Observation+ <$> v .: "observation_time"+ <*> v .: "weather"+ <*> v .: "temp_f"+ <*> v .: "relative_humidity"+ <*> v .: "wind_string"+ <*> v .: "feelslike_string"+ parseJSON _ = mzero++-- | API key. Obtain yours at http://wunderground.com.+type APIKey = String++-- | Get the current weather conditions of a city.+getConditions :: APIKey -> String -> String -> IO (Maybe Observation)+getConditions key city state = do+ obj <- evalJSONRequest $ conditionsQuery key city state+ return $ obj >>= getProperty "current_observation"++-- Fetch a property from a JSON object.+getProperty :: FromJSON a => Text -> Value -> Maybe a+getProperty property (Object v) = do+ val <- H.lookup property v+ case fromJSON val of+ Error _ -> Nothing+ Success x -> Just x+getProperty _ _ = Nothing++-- Evaluate a JSON request and return the parsed object.+evalJSONRequest :: FromJSON a => String -> IO (Maybe a)+evalJSONRequest request = do+ body <- getResponseBody <=< simpleHTTP $ getRequest request+ return . decode $ pack body++-- The query used to get weather conditions.+conditionsQuery :: String -> String -> String -> String+conditionsQuery key city state =+ "http://api.wunderground.com/api/" ++ key+ ++ "/conditions/q/" ++ state+ ++ "/" ++ city ++ ".json"