api-monobank 0.1.0.0 → 0.1.0.1
raw patch · 8 files changed
+208/−210 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Api: getCurrencies :: IO [CurrencyPair]
- Api: getPersonalInfo :: () => a
- Api: getPersonalStatement :: () => a
- Api: getPersonalStatementFull :: () => a
- Types: Account :: Text -> Int -> Int -> Currency -> Text -> Account
- Types: Currency :: String -> Int -> Int -> String -> String -> Currency
- Types: CurrencyPair :: Currency -> Currency -> Int -> Maybe Float -> Maybe Float -> Maybe Float -> CurrencyPair
- Types: Statement :: String -> String -> String -> String -> Bool -> Int -> Int -> Currency -> Int -> Int -> Int -> Statement
- Types: User :: String -> [Account] -> User
- Types: [acBalance] :: Account -> Int
- Types: [acCashbackType] :: Account -> Text
- Types: [acCreditLimit] :: Account -> Int
- Types: [acCurrency] :: Account -> Currency
- Types: [acId] :: Account -> Text
- Types: [balance] :: Statement -> Int
- Types: [cpCurrencyCodeA] :: CurrencyPair -> Currency
- Types: [cpCurrencyCodeB] :: CurrencyPair -> Currency
- Types: [cpDate] :: CurrencyPair -> Int
- Types: [cpRateBuy] :: CurrencyPair -> Maybe Float
- Types: [cpRateCross] :: CurrencyPair -> Maybe Float
- Types: [cpRateSell] :: CurrencyPair -> Maybe Float
- Types: [decimalDigits] :: Currency -> Int
- Types: [isoCode] :: Currency -> String
- Types: [isoNumericCode] :: Currency -> Int
- Types: [name] :: Currency -> String
- Types: [stAmount] :: Statement -> Int
- Types: [stCashbackAmount] :: Statement -> Int
- Types: [stComissionRate] :: Statement -> Int
- Types: [stCurrency] :: Statement -> Currency
- Types: [stDescription] :: Statement -> String
- Types: [stHold] :: Statement -> Bool
- Types: [stId] :: Statement -> String
- Types: [stMCC] :: Statement -> String
- Types: [stOperationAmount] :: Statement -> Int
- Types: [stTime] :: Statement -> String
- Types: [symbol] :: Currency -> String
- Types: [uAccounts] :: User -> [Account]
- Types: [uName] :: User -> String
- Types: convertCurrencyFromCode :: Int -> Currency
- Types: data Account
- Types: data Currency
- Types: data CurrencyPair
- Types: data Statement
- Types: data User
- Types: instance Data.Aeson.Types.FromJSON.FromJSON Types.CurrencyPair
- Types: instance GHC.Classes.Eq Types.Account
- Types: instance GHC.Classes.Eq Types.Currency
- Types: instance GHC.Classes.Eq Types.Statement
- Types: instance GHC.Classes.Eq Types.User
- Types: instance GHC.Show.Show Types.Account
- Types: instance GHC.Show.Show Types.Currency
- Types: instance GHC.Show.Show Types.CurrencyPair
- Types: instance GHC.Show.Show Types.Statement
- Types: instance GHC.Show.Show Types.User
- Types: showCurrencyPair :: CurrencyPair -> IO ()
- Types: type Token = Text
- Utils: uncapFst :: String -> String
+ Monobank.Api: getCurrencies :: IO [CurrencyPair]
+ Monobank.Api: getPersonalInfo :: () => a
+ Monobank.Api: getPersonalStatement :: () => a
+ Monobank.Api: getPersonalStatementFull :: () => a
+ Monobank.Types: Account :: Text -> Int -> Int -> Currency -> Text -> Account
+ Monobank.Types: Currency :: String -> Int -> Int -> String -> String -> Currency
+ Monobank.Types: CurrencyPair :: Currency -> Currency -> Int -> Maybe Float -> Maybe Float -> Maybe Float -> CurrencyPair
+ Monobank.Types: Statement :: String -> String -> String -> String -> Bool -> Int -> Int -> Currency -> Int -> Int -> Int -> Statement
+ Monobank.Types: User :: String -> [Account] -> User
+ Monobank.Types: [acBalance] :: Account -> Int
+ Monobank.Types: [acCashbackType] :: Account -> Text
+ Monobank.Types: [acCreditLimit] :: Account -> Int
+ Monobank.Types: [acCurrency] :: Account -> Currency
+ Monobank.Types: [acId] :: Account -> Text
+ Monobank.Types: [balance] :: Statement -> Int
+ Monobank.Types: [cpCurrencyCodeA] :: CurrencyPair -> Currency
+ Monobank.Types: [cpCurrencyCodeB] :: CurrencyPair -> Currency
+ Monobank.Types: [cpDate] :: CurrencyPair -> Int
+ Monobank.Types: [cpRateBuy] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [cpRateCross] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [cpRateSell] :: CurrencyPair -> Maybe Float
+ Monobank.Types: [decimalDigits] :: Currency -> Int
+ Monobank.Types: [isoCode] :: Currency -> String
+ Monobank.Types: [isoNumericCode] :: Currency -> Int
+ Monobank.Types: [name] :: Currency -> String
+ Monobank.Types: [stAmount] :: Statement -> Int
+ Monobank.Types: [stCashbackAmount] :: Statement -> Int
+ Monobank.Types: [stComissionRate] :: Statement -> Int
+ Monobank.Types: [stCurrency] :: Statement -> Currency
+ Monobank.Types: [stDescription] :: Statement -> String
+ Monobank.Types: [stHold] :: Statement -> Bool
+ Monobank.Types: [stId] :: Statement -> String
+ Monobank.Types: [stMCC] :: Statement -> String
+ Monobank.Types: [stOperationAmount] :: Statement -> Int
+ Monobank.Types: [stTime] :: Statement -> String
+ Monobank.Types: [symbol] :: Currency -> String
+ Monobank.Types: [uAccounts] :: User -> [Account]
+ Monobank.Types: [uName] :: User -> String
+ Monobank.Types: convertCurrencyFromCode :: Int -> Currency
+ Monobank.Types: data Account
+ Monobank.Types: data Currency
+ Monobank.Types: data CurrencyPair
+ Monobank.Types: data Statement
+ Monobank.Types: data User
+ Monobank.Types: instance Data.Aeson.Types.FromJSON.FromJSON Monobank.Types.CurrencyPair
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Account
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Currency
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.Statement
+ Monobank.Types: instance GHC.Classes.Eq Monobank.Types.User
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Account
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Currency
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.CurrencyPair
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.Statement
+ Monobank.Types: instance GHC.Show.Show Monobank.Types.User
+ Monobank.Types: showCurrencyPair :: CurrencyPair -> IO ()
+ Monobank.Types: type Token = Text
+ Monobank.Utils: uncapFst :: String -> String
Files
- api-monobank.cabal +4/−4
- app/Main.hs +2/−2
- src/Api.hs +0/−57
- src/Monobank/Api.hs +56/−0
- src/Monobank/Types.hs +135/−0
- src/Monobank/Utils.hs +11/−0
- src/Types.hs +0/−135
- src/Utils.hs +0/−12
api-monobank.cabal view
@@ -1,5 +1,5 @@ name: api-monobank-version: 0.1.0.0+version: 0.1.0.1 -- synopsis: description: Api client for popular Ukrainian bank - Monobank homepage: https://github.com/sigrlami/api-monobank#readme@@ -15,9 +15,9 @@ library hs-source-dirs: src- exposed-modules: Api- , Types- , Utils+ exposed-modules: Monobank.Api+ , Monobank.Types+ , Monobank.Utils build-depends: base >= 4.7 && < 5 , aeson , text
app/Main.hs view
@@ -9,8 +9,8 @@ import Data.Time.Clock import System.Environment -import qualified Api as MBApi-import qualified Types as MBApi+import qualified Monobank.Api as MBApi+import qualified Monobank.Types as MBApi --------------------------------------------------------------------------------
− src/Api.hs
@@ -1,57 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Api- ( getCurrencies- , getPersonalInfo- , getPersonalStatement- , getPersonalStatementFull- ) where--import Data.Aeson-import qualified Data.ByteString.Char8 as B-import qualified Data.ByteString.Lazy.Char8 as BL-import qualified Data.Text as T-import Network.HTTP.Conduit (simpleHttp)--import Types-import Utils-------------------------------------------------------------------------------------endpoint :: T.Text-endpoint = "https://api.monobank.ua"---- Get a basic list of monobank currency rates.--- Information is cached and updated no more than once every 5 minutes.------ GET /bank/currency-getCurrencies :: IO [CurrencyPair]-getCurrencies = do- let path = T.concat [endpoint, "/bank/currency"]- -- results <- fmap decodeEither $ simpleHttp (T.unpack path)- resp <- simpleHttp (T.unpack path)- --putStrLn $ show $ resp- let res = eitherDecode resp- case res of- Left err -> do- putStrLn err- return $ []- Right val -> do- return $ val---- GET /personal/client-info-getPersonalInfo = undefined----- Receive an extract for the time from {to} to {to} time in seconds Unix time format.--- The maximum time for which it is possible to extract an extract is 31 days--- (2678400 seconds) Limit on the use of the function no more than 1 time in 60 seconds.------ GET /personal/statement/{account}/{from}/{to}-getPersonalStatement = undefined----- Get Personal Statement from beginning--- 12 months will take 12 minutes-getPersonalStatementFull = undefined
+ src/Monobank/Api.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE OverloadedStrings #-}++module Monobank.Api+ ( getCurrencies+ , getPersonalInfo+ , getPersonalStatement+ , getPersonalStatementFull+ ) where++import Data.Aeson+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy.Char8 as BL+import qualified Data.Text as T+import Network.HTTP.Conduit (simpleHttp)++import Monobank.Types+import Monobank.Utils++--------------------------------------------------------------------------------++endpoint :: T.Text+endpoint = "https://api.monobank.ua"++-- Get a basic list of monobank currency rates.+-- Information is cached and updated no more than once every 5 minutes.+--+-- GET /bank/currency+getCurrencies :: IO [CurrencyPair]+getCurrencies = do+ let path = T.concat [endpoint, "/bank/currency"]+ -- results <- fmap decodeEither $ simpleHttp (T.unpack path)+ resp <- simpleHttp (T.unpack path)+ --putStrLn $ show $ resp+ let res = eitherDecode resp+ case res of+ Left err -> do+ putStrLn err+ return $ []+ Right val -> do+ return $ val++-- GET /personal/client-info+getPersonalInfo = undefined+++-- Receive an extract for the time from {to} to {to} time in seconds Unix time format.+-- The maximum time for which it is possible to extract an extract is 31 days+-- (2678400 seconds) Limit on the use of the function no more than 1 time in 60 seconds.+--+-- GET /personal/statement/{account}/{from}/{to}+getPersonalStatement = undefined+++-- Get Personal Statement from beginning+-- 12 months will take 12 minutes+getPersonalStatementFull = undefined
+ src/Monobank/Types.hs view
@@ -0,0 +1,135 @@+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeSynonymInstances #-}++module Monobank.Types where++import Data.Aeson+import Data.Aeson.TH+import Data.Maybe+import qualified Data.Text as T+import Data.Time+import GHC.Generics++import Monobank.Utils++-----------------------------------------------------------------++-- | Wrapper for user token from Developer's Dashboard, https://api.monobank.ua/+type Token = T.Text++-----------------------------------------------------------------++data Currency =+ Currency+ { isoCode :: String+ , isoNumericCode :: Int+ , decimalDigits :: Int+ , symbol :: String+ , name :: String+ } deriving (Eq, Show)++convertCurrencyFromCode :: Int -> Currency+convertCurrencyFromCode val =+ case val of+ 840 -> Currency { isoCode = "USD", isoNumericCode= 840, decimalDigits= 2, symbol= "$", name="Dollar"}+ 978 -> Currency { isoCode = "EUR", isoNumericCode= 978, decimalDigits= 2, symbol= "€", name="Euro"}+ 980 -> Currency { isoCode = "UAH", isoNumericCode= 980, decimalDigits= 2, symbol= "₴", name="Hrivnya"}+ 643 -> Currency { isoCode = "RUB", isoNumericCode= 643, decimalDigits= 2, symbol= "", name="Ruble"}+ 826 -> Currency { isoCode = "GBP", isoNumericCode= 826, decimalDigits= 2, symbol= "", name="Pound Sterling"}+ 949 -> Currency { isoCode = "TRY", isoNumericCode= 949, decimalDigits= 2, symbol= "", name="Lira"}+ 985 -> Currency { isoCode = "PLN", isoNumericCode= 985, decimalDigits= 2, symbol= "", name="Zloty"}+ 348 -> Currency { isoCode = "HUF", isoNumericCode= 348, decimalDigits= 2, symbol= "", name="Forint"}+ 208 -> Currency { isoCode = "DKK", isoNumericCode= 208, decimalDigits= 2, symbol= "", name="Danish Krone"}+ 203 -> Currency { isoCode = "CZK", isoNumericCode= 203, decimalDigits= 2, symbol= "", name="Czech Koruna"}+ 124 -> Currency { isoCode = "CAD", isoNumericCode= 124, decimalDigits= 2, symbol= "", name="Canadian Dollar"}+ 933 -> Currency { isoCode = "BYN", isoNumericCode= 933, decimalDigits= 2, symbol= "", name="Belarussian Ruble"}+ 756 -> Currency { isoCode = "CHF", isoNumericCode= 756, decimalDigits= 2, symbol= "", name="Swiss Franc"}+ otherwise -> Currency { isoCode = "NA" , isoNumericCode= 0 , decimalDigits= 2, symbol= "", name="Uknown"}++-------------------------------------------------------------------------------------------++-- | Data type that represents currency pair from Monobank+-- at spicific time+data CurrencyPair =+ CurrencyPair+ { cpCurrencyCodeA :: Currency -- ^ Currency derived from international identificator+ , cpCurrencyCodeB :: Currency -- ^ Currency derived from international identificator+ , cpDate :: Int -- ^ Timestamp for the currency pair information+ , cpRateSell :: Maybe Float -- ^ Rate to sell currency+ , cpRateBuy :: Maybe Float -- ^ Rate to buy currency+ , cpRateCross :: Maybe Float -- ^ Rate+ } deriving (Show)++instance FromJSON CurrencyPair where+ parseJSON =+ withObject "object" $ \o -> do+ currA' <- o .: "currencyCodeA"+ currB' <- o .: "currencyCodeB"+ date' <- o .: "date" -- TODO: convert to UTCTime+ rateSell' <- o .:? "rateSell"+ rateBuy' <- o .:? "rateBuy"+ rateCross' <- o .:? "rateCross"++ let currA = convertCurrencyFromCode currA'+ currB = convertCurrencyFromCode currB'+ --date =++ return $+ CurrencyPair currA currB date' rateSell' rateBuy' rateCross'++showCurrencyPair :: CurrencyPair -> IO ()+showCurrencyPair cp = do+ putStrLn $ (isoCode $ cpCurrencyCodeA cp) ++ "/" ++ (isoCode $ cpCurrencyCodeB cp)+ case (cpRateBuy cp) of+ Nothing -> do+ putStrLn $ " - Cross: " ++ (show $ fromMaybe 0 $ cpRateCross cp) ++ (symbol $ cpCurrencyCodeB cp)+ putStrLn $ ""+ Just buy -> do+ putStrLn $ " - Buy: " ++ (show $ buy) ++ " " ++ (symbol $ cpCurrencyCodeB cp)+ putStrLn $ " - Sell: " ++ (show $ fromMaybe 0 $ cpRateSell cp) ++ (symbol $ cpCurrencyCodeB cp)+ putStrLn $ ""++-- Simplified version for one-to-one conversion+--+-- instance FromJSON CurrencyPair where+-- parseJSON = genericParseJSON opts+-- where+-- opts = defaultOptions { fieldLabelModifier = uncapFst . drop 2}++--------------------------------------------------------------------------------++data Account =+ Account+ { acId :: T.Text -- ^+ , acBalance :: Int -- ^ Current balance+ , acCreditLimit :: Int -- ^ Current credit limit available to user+ , acCurrency :: Currency -- ^ Currency of the account+ , acCashbackType :: T.Text -- ^+ } deriving (Eq, Show)++data User =+ User+ { uName :: String -- ^ User's full name+ , uAccounts :: [Account] -- ^ List of user accounts, by currency type+ } deriving (Eq, Show)++data Statement =+ Statement+ { stId :: String -- ^+ , stTime :: String -- ^+ , stDescription :: String -- ^+ , stMCC :: String -- ^+ , stHold :: Bool -- ^+ , stAmount :: Int -- ^+ , stOperationAmount :: Int -- ^+ , stCurrency :: Currency -- ^+ , stComissionRate :: Int -- ^+ , stCashbackAmount :: Int -- ^+ , balance :: Int -- ^+ } deriving (Eq, Show)
+ src/Monobank/Utils.hs view
@@ -0,0 +1,11 @@+module Monobank.Utils where+++import qualified Data.Char as Char+import Data.Text as T++-------------------------------------------------------------------++uncapFst :: String -> String+uncapFst (head:tail) = Char.toLower head : tail+uncapFst [] = []
− src/Types.hs
@@ -1,135 +0,0 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeSynonymInstances #-}--module Types where--import Data.Aeson-import Data.Aeson.TH-import Data.Maybe-import qualified Data.Text as T-import Data.Time-import GHC.Generics--import Utils----------------------------------------------------------------------- | Wrapper for user token from Developer's Dashboard, https://api.monobank.ua/-type Token = T.Text---------------------------------------------------------------------data Currency =- Currency- { isoCode :: String- , isoNumericCode :: Int- , decimalDigits :: Int- , symbol :: String- , name :: String- } deriving (Eq, Show)--convertCurrencyFromCode :: Int -> Currency-convertCurrencyFromCode val =- case val of- 840 -> Currency { isoCode = "USD", isoNumericCode= 840, decimalDigits= 2, symbol= "$", name="Dollar"}- 978 -> Currency { isoCode = "EUR", isoNumericCode= 978, decimalDigits= 2, symbol= "€", name="Euro"}- 980 -> Currency { isoCode = "UAH", isoNumericCode= 980, decimalDigits= 2, symbol= "₴", name="Hrivnya"}- 643 -> Currency { isoCode = "RUB", isoNumericCode= 643, decimalDigits= 2, symbol= "", name="Ruble"}- 826 -> Currency { isoCode = "GBP", isoNumericCode= 826, decimalDigits= 2, symbol= "", name="Pound Sterling"}- 949 -> Currency { isoCode = "TRY", isoNumericCode= 949, decimalDigits= 2, symbol= "", name="Lira"}- 985 -> Currency { isoCode = "PLN", isoNumericCode= 985, decimalDigits= 2, symbol= "", name="Zloty"}- 348 -> Currency { isoCode = "HUF", isoNumericCode= 348, decimalDigits= 2, symbol= "", name="Forint"}- 208 -> Currency { isoCode = "DKK", isoNumericCode= 208, decimalDigits= 2, symbol= "", name="Danish Krone"}- 203 -> Currency { isoCode = "CZK", isoNumericCode= 203, decimalDigits= 2, symbol= "", name="Czech Koruna"}- 124 -> Currency { isoCode = "CAD", isoNumericCode= 124, decimalDigits= 2, symbol= "", name="Canadian Dollar"}- 933 -> Currency { isoCode = "BYN", isoNumericCode= 933, decimalDigits= 2, symbol= "", name="Belarussian Ruble"}- 756 -> Currency { isoCode = "CHF", isoNumericCode= 756, decimalDigits= 2, symbol= "", name="Swiss Franc"}- otherwise -> Currency { isoCode = "NA" , isoNumericCode= 0 , decimalDigits= 2, symbol= "", name="Uknown"}------------------------------------------------------------------------------------------------- | Data type that represents currency pair from Monobank--- at spicific time-data CurrencyPair =- CurrencyPair- { cpCurrencyCodeA :: Currency -- ^ Currency derived from international identificator- , cpCurrencyCodeB :: Currency -- ^ Currency derived from international identificator- , cpDate :: Int -- ^ Timestamp for the currency pair information- , cpRateSell :: Maybe Float -- ^ Rate to sell currency- , cpRateBuy :: Maybe Float -- ^ Rate to buy currency- , cpRateCross :: Maybe Float -- ^ Rate- } deriving (Show)--instance FromJSON CurrencyPair where- parseJSON =- withObject "object" $ \o -> do- currA' <- o .: "currencyCodeA"- currB' <- o .: "currencyCodeB"- date' <- o .: "date" -- TODO: convert to UTCTime- rateSell' <- o .:? "rateSell"- rateBuy' <- o .:? "rateBuy"- rateCross' <- o .:? "rateCross"-- let currA = convertCurrencyFromCode currA'- currB = convertCurrencyFromCode currB'- --date =-- return $- CurrencyPair currA currB date' rateSell' rateBuy' rateCross'--showCurrencyPair :: CurrencyPair -> IO ()-showCurrencyPair cp = do- putStrLn $ (isoCode $ cpCurrencyCodeA cp) ++ "/" ++ (isoCode $ cpCurrencyCodeB cp)- case (cpRateBuy cp) of- Nothing -> do- putStrLn $ " - Cross: " ++ (show $ fromMaybe 0 $ cpRateCross cp) ++ (symbol $ cpCurrencyCodeB cp)- putStrLn $ ""- Just buy -> do- putStrLn $ " - Buy: " ++ (show $ buy) ++ " " ++ (symbol $ cpCurrencyCodeB cp)- putStrLn $ " - Sell: " ++ (show $ fromMaybe 0 $ cpRateSell cp) ++ (symbol $ cpCurrencyCodeB cp)- putStrLn $ ""---- Simplified version for one-to-one conversion------ instance FromJSON CurrencyPair where--- parseJSON = genericParseJSON opts--- where--- opts = defaultOptions { fieldLabelModifier = uncapFst . drop 2}------------------------------------------------------------------------------------data Account =- Account- { acId :: T.Text -- ^- , acBalance :: Int -- ^ Current balance- , acCreditLimit :: Int -- ^ Current credit limit available to user- , acCurrency :: Currency -- ^ Currency of the account- , acCashbackType :: T.Text -- ^- } deriving (Eq, Show)--data User =- User- { uName :: String -- ^ User's full name- , uAccounts :: [Account] -- ^ List of user accounts, by currency type- } deriving (Eq, Show)--data Statement =- Statement- { stId :: String -- ^- , stTime :: String -- ^- , stDescription :: String -- ^- , stMCC :: String -- ^- , stHold :: Bool -- ^- , stAmount :: Int -- ^- , stOperationAmount :: Int -- ^- , stCurrency :: Currency -- ^- , stComissionRate :: Int -- ^- , stCashbackAmount :: Int -- ^- , balance :: Int -- ^- } deriving (Eq, Show)
− src/Utils.hs
@@ -1,12 +0,0 @@-module Utils where---import qualified Data.Char as Char-import Data.Text as T------------------------------------------------------------------------uncapFst :: String -> String-uncapFst (head:tail) = Char.toLower head : tail-uncapFst [] = []