packages feed

weather-api (empty) → 0.0

raw patch · 5 files changed

+196/−0 lines, 5 filesdep +HTTPdep +basedep +hxtsetup-changed

Dependencies added: HTTP, base, hxt, network, resource-pool

Files

+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2012 Formal Methods+Copyright (c) 2012 Tim, Max++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies+of the Software, and to permit persons to whom the Software is furnished to do+so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ WeatherApi.hs view
@@ -0,0 +1,79 @@+-- | Usage:+--+-- required imports+--+-- > import WeatherApi+-- > import WeatherApi.Google+--+-- With handler in case server will alow you to make+-- few requests with one connection+--+-- >>> let h = mkWeatherHandler $ initApi "en" "utf-8"+-- >>> getWeather h "moscow"+-- Right (Weather { tempF = 75.0+--                , tempC = 24.0+--                , humidity = "Humidity: 25%"+--                , windCondition = "Wind: S at 16 mph"+--                , condition = "Clear"+--                })+--+-- Simple case+--+-- >>> getWeather' (initApi "en" "utf-8") "moscow"+-- Right (Weather { tempF = 75.0+--                , tempC = 24.0+--                , humidity = "Humidity: 25%"+--                , windCondition = "Wind: S at 16 mph"+--                , condition = "Clear"+--                })++module WeatherApi (WeatherApiHandler(..)+                  ,Config(..)+                  ,Weather(..)+                  ,getWeather+                  ,getWeather'+                  ,mkWeatherHandler+                  ,isHandlerAlive+                  ,closeHandler) where++import Network.HTTP+import Network.URI++data Config = Config { apiHost  :: String+                     , apiPort  :: Int+                     , queryFun :: HandleStream String ->+                                  String              ->+                                      IO (Either String Weather)+                     }++data WeatherApiHandler = WeatherApiHandler+    { stream :: IO (HandleStream String)+    , config :: Config+    }++data Weather = Weather { tempF, tempC  :: Double+                       , humidity      :: String+                       , windCondition :: String+                       , condition     :: String+                       } deriving (Eq, Show)++mkWeatherHandler c@(Config apiHost apiPort queryFun) =+  WeatherApiHandler { stream = openStream apiHost apiPort+                    , config = c+                    }++isHandlerAlive (WeatherApiHandler stream (Config h p _)) =+    stream >>= \s -> isTCPConnectedTo s (EndPoint h p)++closeHandler (WeatherApiHandler stream _) = stream >>= closeQuick++-- | Retrieve weather using existing handler+getWeather (WeatherApiHandler stream c) city =+    stream >>= \s -> queryFun c s city++-- | Retrieve weather using just config+-- It's usefull when you don't need one connection for few requests+getWeather' (Config apiHost apiPort queryFun) city =+    openStream apiHost apiPort >>= \s -> queryFun s city++
+ WeatherApi/Google.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE Arrows, NoMonomorphismRestriction #-}+module WeatherApi.Google (initApi) where++import Text.XML.HXT.Core+import Network.HTTP+import Network.URI+import WeatherApi+import Control.Monad (liftM)+apiUrl  = "http://www.google.com/ig/api?"++type Lang = String+type Enc  = String++-- | Make config for use with WeatherApi functions+initApi :: Lang -> Enc -> Config+initApi   lang   enc =+    let params = [("hl", lang), ("oe", enc)]+        urn c  = urlEncodeVars $ params ++ [("weather", c)]+    in Config { apiHost  = "www.google.com"+              , apiPort  = 80+              , queryFun = makeQueryFun urn+              }++retrieve s urn =+    case parseURI $ apiUrl ++ urn of+      Nothing  -> return $ Left "Invalid URL"+      Just uri -> get s uri++get s uri =+    do+      eresp <- sendHTTP s (Request uri GET [] "")+      case eresp of+        Left err  -> return $ Left $ show err+        Right res -> return $ Right $ rspBody res++atTag tag = deep (isElem >>> hasName tag)+dataAtTag tag = atTag tag >>> getAttrValue "data"++parseWeather = atTag "current_conditions" >>>+  proc x -> do+    tempF'         <- dataAtTag "temp_f"         -< x+    tempC'         <- dataAtTag "temp_c"         -< x+    humidity'      <- dataAtTag "humidity"       -< x+    windCondition' <- dataAtTag "wind_condition" -< x+    condition'     <- dataAtTag "condition"      -< x+    returnA -< Weather+      { tempF         = read tempF'+      , tempC         = read tempC'+      , humidity      = humidity'+      , windCondition = windCondition'+      , condition     = condition'+      }++parseXML = readString [ withValidate no+                      , withRemoveWS yes+                      ]++-- | This return function witch will actualy retrieve and parse weather from stream+makeQueryFun q stream city =+    do+      resp <- retrieve stream $ q city+      case liftM parseXML resp of+        Left a  -> return $ Left a+        Right a -> do+          r <- runX(a >>> parseWeather)+          case r of+            []     -> return $ Left "can't retrieve weather"+            (x:xs) -> return $ Right x
+ weather-api.cabal view
@@ -0,0 +1,27 @@+Name:              weather-api+Version:           0.0+Synopsis:          Weather api implemented in haskell+Description:+        This library implement generic api for retrieving weather+        by http, and has google weather api as example.++Homepage: https://github.com/cvb/hs-weather-api.git+License:           MIT+License-file:      LICENSE+Author:            Peter+Maintainer:        peter@standalone.su+Build-type:        Simple+Category:          API++Cabal-version:     >= 1.6+Library+  Exposed-modules: WeatherApi, WeatherApi.Google+  Build-depends:   base          == 4.*+                  ,network       == 2.3.*+                  ,hxt           == 9.2.*+                  ,HTTP          == 4000.2.*+                  ,resource-pool == 0.2.1.*++source-repository head+  type:     git+  location: git://github.com/cvb/hs-weather-api.git