packages feed

mapquest-api (empty) → 0.1.0.0

raw patch · 6 files changed

+209/−0 lines, 6 filesdep +aesondep +basedep +bytestringsetup-changed

Dependencies added: aeson, base, bytestring, exceptions, req, text

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Marco Zocca (c) 2018++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 Marco Zocca nor the names of other+      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+OWNER 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,5 @@+# mapquest-api++[![Build Status](https://travis-ci.org/ocramz/mapquest-api.png)](https://travis-ci.org/ocramz/mapquest-api)++TODO Description.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ mapquest-api.cabal view
@@ -0,0 +1,51 @@+name:                mapquest-api+version:             0.1.0.0+synopsis:            Bindings to the MapQuest API+description:         This library provides a high-level interface to the MapQuest API. Currently only the "geocoding" API (street address to coordinates) is provided, but the functionality is straightforward to extend.+homepage:            https://github.com/ocramz/mapquest-api+license:             BSD3+license-file:        LICENSE+author:              Marco Zocca+maintainer:          zocca.marco gmail+copyright:           2018 Marco Zocca+category:            Web+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10+tested-with:         GHC == 8.0.1++library+  default-language:    Haskell2010+  ghc-options:         -Wall+  hs-source-dirs:      src+  exposed-modules:     Web.API.Mapquest+                       Web.API.Mapquest.Geocoding+  build-depends:       base >= 4.7 && < 5+                     , req+                     , bytestring+                     , text+                     , aeson+                     , exceptions++-- executable mapquest-api+--   default-language:    Haskell2010+--   ghc-options:         -threaded -rtsopts -with-rtsopts=-N+--   hs-source-dirs:      app+--   main-is:             Main.hs+--   build-depends:       base+--                      , mapquest-api++-- test-suite spec+--   default-language:    Haskell2010+--   ghc-options:         -Wall+--   type:                exitcode-stdio-1.0+--   hs-source-dirs:      test+--   main-is:             Spec.hs+--   build-depends:       base+--                      , mapquest-api+--                      , hspec+--                      , QuickCheck++source-repository head+  type:     git+  location: https://github.com/ocramz/mapquest-api
+ src/Web/API/Mapquest.hs view
@@ -0,0 +1,15 @@+module Web.API.Mapquest (+  -- * Geocoding+  G.request,+  -- ** Parameters+  G.GeoQuery(..),+  -- ** Output+  G.Coords(..)+  ) where++import qualified Web.API.Mapquest.Geocoding as G+++++
+ src/Web/API/Mapquest/Geocoding.hs view
@@ -0,0 +1,106 @@+{-# language OverloadedStrings, DataKinds, DeriveGeneric #-}+module Web.API.Mapquest.Geocoding (request, GeoQuery(..), Coords(..))where++import Data.List (intersperse)+import Data.Monoid (mempty, (<>))++import Network.HTTP.Req+import qualified Data.Text as T+import qualified Data.Text.Encoding as T (encodeUtf8, decodeUtf8)+import qualified Data.ByteString.Lazy as LBS++import GHC.Generics++import Control.Monad.Catch++import Data.Aeson+import Data.Aeson.Types (Parser(..), parseMaybe, parseEither)++-- https://developer.mapquest.com/documentation/geocoding-api/address/get/++apiRootPath :: Url 'Http+apiRootPath = http "www.mapquestapi.com" /: "geocoding" /: "v1" /: "address"+++-- example request :+-- GET http://www.mapquestapi.com/geocoding/v1/address?key=KEY&location=Washington,DC++instance MonadHttp IO where+  handleHttpException = throwM++-- | Call the MapQuest Geocoding API with a given address and extract the coordinates from the parsed result.+--+-- Example usage :+-- assuming the user has bound /key/ to hold the API key string, the following can be run in a GHCi shell :+--+-- >>> request key (GQ "Via Irnerio" "Bologna" "Italy")+-- Just (Coords {lat = 44.49897, long = 11.34503})+--+-- >>> request key (GQFree "Hong Kong")+-- Just (Coords {lat = 22.264412, long = 114.16706})++request ::+     T.Text  -- ^ API key (available for free on mapquestapi.com)+  -> GeoQuery -- ^ Query address+  -> IO (Maybe (Coords Float))+request apikey q = do+  r <- req GET apiRootPath NoReqBody lbsResponse opts'+  return $ decoder1 $ responseBody r where+    opts' = +      ("key" =: apikey) <>+      ("outFormat" =: ("json" :: T.Text)) <>+      ("location" =: renderGeoQuery q)++++decoder1 :: LBS.ByteString -> Maybe (Coords Float)+decoder1 dat = do+  r <- decode dat+  flip parseMaybe r $ \obj -> do +    locp <- decodeLocation obj+    decodeLatLong locp++decodeLocation :: FromJSON a => Object -> Parser a+decodeLocation obj = do+    (res0 : _) <- obj .: "results"+    (loc0 : _) <- res0 .: "locations"+    return loc0++decodeLatLong :: Object -> Parser (Coords Float)+decodeLatLong loc = do+    ll <- loc .: "latLng"+    Coords <$> ll .: "lat" <*> ll .: "lng"+    +-- | Coordinates+data Coords a = Coords {+    lat :: a -- ^ Latitude+  , long :: a -- ^ Longitude+  } deriving (Eq, Show, Generic)++-- instance Functor Coords where+--   fmap f (Coords x y) = Coords (f x) (f y)++-- instance FromJSON a => FromJSON (Coords a)++mkQuery :: T.Text -> T.Text -> T.Text -> GeoQuery+mkQuery = GQ++-- | Geocoding query +data GeoQuery = GQ {+    gqStreet :: T.Text -- ^ Street address (e.g. \"Via Irnerio\")+  , gqCity :: T.Text   -- ^ City (e.g. \"Bologna\")+  , gqCountry :: T.Text -- ^ Country (e.g. \"Italy\")+  }+  | GQFree T.Text -- ^ Free-text query (must be a valid address or location)+  deriving (Eq, Show)++renderGeoQuery :: GeoQuery -> T.Text+renderGeoQuery q = case q of+  (GQ addr city country) -> T.concat $ intersperse ", " [addr, city, country]+  (GQFree t) -> t ++-- options :: Foldable t => t (T.Text, T.Text) -> Option 'Http+-- options = foldr (\(k, v) acc  -> (k =: v) <> acc ) mempty+++