1
0
Fork 0

[haskell] Add a SpaceTradersT and handle server reset api message

This commit is contained in:
Julien Dessaux 2023-07-16 23:31:00 +02:00
parent 7bd1c116c2
commit e084d260ff
Signed by: adyxax
GPG key ID: F92E51B86E07177E
6 changed files with 110 additions and 31 deletions

View file

@ -3,36 +3,19 @@
module Main (main) where module Main (main) where
import Control.Exception import Control.Exception
import qualified Database.SQLite.Simple as S
import qualified Data.Text as T
import SpaceTraders.APIClient.Agent import SpaceTraders
import SpaceTraders.Automation.Init
import SpaceTraders.APIClient.Agent(myAgent)
import SpaceTraders.APIClient.Systems import SpaceTraders.APIClient.Systems
import SpaceTraders.Database
import SpaceTraders.Database.Agents
import SpaceTraders.Database.Contracts
import SpaceTraders.Database.Ships
import SpaceTraders.Database.Tokens
main :: IO () main :: IO ()
main = do main = do
conn <- open config <- initST
t <- getToken conn `catch` registerNow conn ma <- runSpaceTradersT myAgent config
ma <- myAgent t
print ma print ma
s <- listSystems t conn s <- listSystems (token config) (conn config)
print s case s of
close conn Left e -> throwIO e
where Right s' -> print $ length s'
registerNow :: S.Connection -> SomeException -> IO (T.Text) deinitST config
registerNow conn _ = do
r <- register "ADYXAX" "COSMIC"
case r of
Right r' -> do
setAgent conn $ agent r'
addContract conn $ contract r'
addShip conn $ ship r'
let t = token r'
setToken conn $ t
return t
Left e' -> throwIO e'

View file

@ -19,12 +19,14 @@ dependencies:
- aeson - aeson
- base >= 4.7 && < 5 - base >= 4.7 && < 5
- bytestring - bytestring
- directory
- http-conduit - http-conduit
- http-types - http-types
- raw-strings-qq
- sqlite-simple - sqlite-simple
- text - text
- time - time
- raw-strings-qq - transformers
ghc-options: ghc-options:
- -Wall - -Wall

View file

@ -0,0 +1,23 @@
{-# LANGUAGE OverloadedStrings #-}
module SpaceTraders
( SpaceTradersT
, runSpaceTradersT
, Config(..)
, ask
, liftIO
) where
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import qualified Database.SQLite.Simple as S
import qualified Data.Text as T
type SpaceTradersT a = ReaderT Config IO a
runSpaceTradersT :: SpaceTradersT a -> Config -> IO a
runSpaceTradersT = runReaderT
data Config = Config { conn :: S.Connection
, token :: T.Text
}

View file

@ -13,14 +13,17 @@ import GHC.Generics
import qualified Data.Text as T import qualified Data.Text as T
import Network.HTTP.Simple import Network.HTTP.Simple
import qualified SpaceTraders as ST
import SpaceTraders.APIClient.Client import SpaceTraders.APIClient.Client
import SpaceTraders.Model.Agent(Agent) import SpaceTraders.Model.Agent(Agent)
import SpaceTraders.Model.Ship(Ship) import SpaceTraders.Model.Ship(Ship)
import SpaceTraders.Model.Contract import SpaceTraders.Model.Contract
myAgent :: T.Text -> IO (APIResponse Agent) myAgent :: ST.SpaceTradersT (APIResponse Agent)
myAgent t = send $ setRequestPath "/v2/my/agent" myAgent = do
$ tokenReq t c <- ST.ask
ST.liftIO $ send $ setRequestPath "/v2/my/agent"
$ tokenReq (ST.token c)
data RegisterRequest = RegisterRequest { faction :: T.Text data RegisterRequest = RegisterRequest { faction :: T.Text
, symbol :: T.Text , symbol :: T.Text

View file

@ -1,17 +1,22 @@
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module SpaceTraders.APIClient.Errors module SpaceTraders.APIClient.Errors
( APIError(..) ( APIError(..)
, RateLimit(..) , RateLimit(..)
, ResetHappened(..)
) where ) where
import Control.Exception import Control.Exception
import Data.Aeson import Data.Aeson
import Data.Time import Data.Time
import qualified Data.Text as T import qualified Data.Text as T
import GHC.Generics
data APIError = APIError Int T.Text Value data APIError = APIError Int T.Text Value
| APIRateLimit RateLimit | APIRateLimit RateLimit
| APIResetHappened ResetHappened
deriving Show deriving Show
instance Exception APIError instance Exception APIError
instance FromJSON APIError where instance FromJSON APIError where
@ -20,6 +25,7 @@ instance FromJSON APIError where
code <- e .: "code" code <- e .: "code"
d <- e .: "data" d <- e .: "data"
case code of case code of
401 -> APIResetHappened <$> parseJSON d
429 -> APIRateLimit <$> parseJSON d 429 -> APIRateLimit <$> parseJSON d
_ -> APIError <$> pure code _ -> APIError <$> pure code
<*> e .: "message" <*> e .: "message"
@ -40,3 +46,7 @@ instance FromJSON RateLimit where
<*> o .: "remaining" <*> o .: "remaining"
<*> o .: "reset" <*> o .: "reset"
<*> o .: "retryAfter" <*> o .: "retryAfter"
data ResetHappened = ResetHappened { actual :: T.Text
, expected :: T.Text
} deriving (FromJSON, Generic, Show, ToJSON)

View file

@ -0,0 +1,58 @@
{-# LANGUAGE OverloadedStrings #-}
module SpaceTraders.Automation.Init
( deinitST
, initST
) where
import Control.Exception
import qualified Database.SQLite.Simple as S
import qualified Data.Text as T
import System.Directory
import SpaceTraders
import qualified SpaceTraders.APIClient.Agent as STAA
import SpaceTraders.APIClient.Errors
import SpaceTraders.Database
import SpaceTraders.Database.Agents
import SpaceTraders.Database.Contracts
import SpaceTraders.Database.Ships
import SpaceTraders.Database.Tokens
deinitST :: Config -> IO ()
deinitST config = do
close $ conn config
initST :: IO Config
initST = do
c <- open
t <- getToken c `catch` handleNoToken c
ma <- runSpaceTradersT STAA.myAgent (Config c t)
case ma of
Left (APIResetHappened _) -> wipe c
Left e -> throwIO e
_ -> return $ Config c t
where
handleNoToken :: S.Connection -> SomeException -> IO T.Text
handleNoToken c _ = register c
register :: S.Connection -> IO (T.Text)
register c = do
r <- STAA.register "ADYXAX" "COSMIC"
case r of
Right r' -> do
setAgent c $ STAA.agent r'
addContract c $ STAA.contract r'
addShip c $ STAA.ship r'
let t = STAA.token r'
setToken c $ t
return t
Left e' -> throwIO e'
wipe :: S.Connection -> IO Config
wipe c = do
close c
removeFile "spacetraders.db"
conn' <- open
t <- register conn'
return $ Config conn' t