{-# LANGUAGE OverloadedStrings #-} -- | Internal helper functions for performing actions. module Scurry.Actions.Internal ( buildRequest , decodeResponse , get , makeRequest , paginate ) where import Data.Aeson (FromJSON, eitherDecode) import Data.ByteString.Char8 (pack, unpack) import Data.ByteString.Lazy (ByteString) import Data.Maybe (catMaybes) import Network.HTTP.Conduit (Request, Response, httpLbs, parseUrl, responseBody) import Network.HTTP.Types.URI (SimpleQuery, renderSimpleQuery) import Scurry.Client (Client (accessToken, httpManager)) import qualified Scurry.Types as Types -- | Build a request by constructing the URL and appending the access token. buildRequest :: Client -> Types.Resource -> SimpleQuery -> IO Request buildRequest client resource query = parseUrl url where url = concat [endpoint, resource, queryString] endpoint = "https://www.strava.com/api/v3/" queryString = unpack (renderSimpleQuery True query') query' = ("access_token", pack (accessToken client)) : query -- | Decode a response by parsing its body as JSON. decodeResponse :: FromJSON a => Response ByteString -> Either String a decodeResponse response = eitherDecode (responseBody response) -- | Get the given resource. get :: FromJSON a => Client -> Types.Resource -> SimpleQuery -> IO (Either String a) get client resource query = do request <- buildRequest client resource query response <- makeRequest client request return (decodeResponse response) -- | Make an HTTP request using the client's manager. makeRequest :: Client -> Request -> IO (Response ByteString) makeRequest client request = httpLbs request (httpManager client) -- | Convert pagination parameters into a query. paginate :: Types.Page -> Types.PerPage -> SimpleQuery paginate maybePage maybePerPage = catMaybes [ itemize "page" maybePage , itemize "per_page" maybePerPage ] where itemize key value = maybe Nothing (go key) value go key value = Just (key, pack (show value))