module Cryptsy.API.Public.Internal where
import Network.Browser (request)
import Network.HTTP.Base (defaultGETRequest_, rspBody, rspCode)
import Data.Aeson (Value(Object), eitherDecode, withObject)
import Data.Aeson.Types (Parser, parseEither)
import Control.Monad.Trans.Either (hoistEither, left, right)
import Data.Either.Combinators (mapLeft)
import Control.Error.Util ((??))
import Network.URI (parseAbsoluteURI)
import Data.Text (Text, pack)
import Control.Monad.Trans.Class (lift)
import qualified Data.HashMap.Strict as HM (lookup)
import Cryptsy.API.Public.Types.Error
import Cryptsy.API.Public.Types.Monad
pubURL :: String
-> String
pubURL = ("http://pubapi.cryptsy.com/api.php?method=" ++)
dataStr :: String
dataStr = "return"
dataKey :: Text
dataKey = pack dataStr
errMsgKey :: Text
errMsgKey = pack "error"
pubCryptsy :: String
-> (Value -> Parser a)
-> PubCryptsy a
pubCryptsy apiurl parser = do
uri <- parseAbsoluteURI apiurl ?? BadURL apiurl
let req = defaultGETRequest_ uri
(_, resp) <- lift $ request req
bodyBytes <- case rspCode resp of
(2, 0, 0) -> right $ rspBody resp
_ -> left $ BadResponse resp
valueJSON <- hoistEither . mapLeft (FailParseResponse bodyBytes)
$ eitherDecode bodyBytes
returnData <- case valueJSON of
Object (HM.lookup dataKey -> Just dat) -> right dat
Object (HM.lookup errMsgKey -> Just errMsg) ->
left $ ErrorResponse errMsg
_ -> left $ UnsuccessfulResponse valueJSON
hoistEither . mapLeft (FailParseReturn returnData)
$ parseEither parser returnData
marketsStr :: String
marketsStr = "markets"
missingMsg :: String
missingMsg = "Missing '" ++ marketsStr ++ "' key."
marketsKey :: Text
marketsKey = pack marketsStr
onMarkets :: (Value -> Parser a) -> Value -> Parser a
onMarkets parser = withObject marketsStr $
maybe (fail missingMsg) parser . HM.lookup marketsKey