-
Notifications
You must be signed in to change notification settings - Fork 0
/
contractsAPI.go
142 lines (134 loc) · 4.41 KB
/
contractsAPI.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package s10s
import (
"context"
"errors"
"fmt"
"time"
api "github.com/ruudiRatlos/s10s/openapi"
)
// ListContracts returns a list of all your contracts.
func (c *ContractsAPI) ListContracts(ctx context.Context) ([]*api.Contract, error) {
var (
out []*api.Contract = make([]*api.Contract, 0, 20)
page int32 = 1
limit int32 = 20
)
for {
wait := 1 * time.Second
req := c.c.ContractsAPI.GetContracts(ctx).Page(page).Limit(limit)
redo:
sR, httpR, err := req.Execute() //nolint:bodyclose
err = enhanceErr(err, httpR)
if errors.Is(err, ErrHTTPStatus429) {
c.l.DebugContext(ctx, "hit ratelimit", "ops", "SystemsAPI.ListContracts", "wait", wait)
if err := c.SleepWithJitter(ctx, wait); err != nil {
return nil, err
}
wait = 2 * wait
goto redo
}
if err != nil {
return nil, fmt.Errorf("could not ListContracts: %w", err)
}
for _, contract := range sR.Data {
c.emitContract(ctx, &contract) //nolint:gosec
out = append(out, &contract) //nolint:gosec
}
if limit*page >= sR.Meta.Total {
return out, nil
}
page++
}
}
// GetContract returns data about a contract by ID
func (c *ContractsAPI) GetContract(ctx context.Context, contractID string) (*api.Contract, error) {
wait := 1 * time.Second
req := c.c.ContractsAPI.GetContract(ctx, contractID)
redo:
res, httpR, err := req.Execute() //nolint:bodyclose
err = enhanceErr(err, httpR)
if errors.Is(err, ErrHTTPStatus429) {
c.l.DebugContext(ctx, "hit ratelimit", "ops", "ContractsAPI.GetContract", "wait", wait)
if err := c.SleepWithJitter(ctx, wait); err != nil {
return nil, err
}
wait = 2 * wait
goto redo
}
if err != nil {
return nil, fmt.Errorf("could not GetContract: %w", err)
}
c.emitContract(ctx, &res.Data)
return &res.Data, nil
}
// AcceptContract accepts a contract by ID
// You can only accept contracts that were offered to you, were not accepted yet,
// and whose deadlines has not passed yet.
func (c *ContractsAPI) AcceptContract(ctx context.Context, contract *api.Contract) (*api.AcceptContract200ResponseData, error) {
wait := 1 * time.Second
req := c.c.ContractsAPI.AcceptContract(ctx, contract.Id)
redo:
res, httpR, err := req.Execute() //nolint:bodyclose
err = enhanceErr(err, httpR)
if errors.Is(err, ErrHTTPStatus429) {
c.l.DebugContext(ctx, "hit ratelimit", "ops", "ContractsAPI.AcceptContract", "wait", wait)
if err := c.SleepWithJitter(ctx, wait); err != nil {
return nil, err
}
wait = 2 * wait
goto redo
}
if err != nil {
return nil, fmt.Errorf("could not AcceptContract: %w", err)
}
c.emitContract(ctx, &res.Data.Contract)
c.emitAgentChange(ctx, &res.Data.Agent)
return &res.Data, nil
}
// DeliverCargo returns data about a contract
func (c *ContractsAPI) DeliverContract(ctx context.Context, contract *api.Contract, ship *api.Ship, good api.TradeSymbol, units int32) (*api.DeliverContract200ResponseData, error) {
wait := 1 * time.Second
dcr := api.NewDeliverContractRequest(ship.Symbol, string(good), units)
req := c.c.ContractsAPI.DeliverContract(ctx, contract.Id).DeliverContractRequest(*dcr)
redo:
res, httpR, err := req.Execute() //nolint:bodyclose
err = enhanceErr(err, httpR)
if errors.Is(err, ErrHTTPStatus429) {
c.l.DebugContext(ctx, "hit ratelimit", "ops", "ContractsAPI.DeliverContract", "wait", wait)
if err := c.SleepWithJitter(ctx, wait); err != nil {
return nil, err
}
wait = 2 * wait
goto redo
}
if err != nil {
return nil, fmt.Errorf("could not DeliverContract: %w", err)
}
ship.Cargo = res.Data.Cargo
c.emitShipChange(ctx, ship)
c.emitContract(ctx, &res.Data.Contract)
return &res.Data, nil
}
// FulfillContract fulfills a contract.
// Can only be used on contracts that have all of their delivery terms fulfilled.
func (c *ContractsAPI) FulfillContract(ctx context.Context, contract *api.Contract) (*api.AcceptContract200ResponseData, error) {
wait := 1 * time.Second
req := c.c.ContractsAPI.FulfillContract(ctx, contract.Id)
redo:
res, httpR, err := req.Execute() //nolint:bodyclose
err = enhanceErr(err, httpR)
if errors.Is(err, ErrHTTPStatus429) {
c.l.DebugContext(ctx, "hit ratelimit", "ops", "ContractsAPI.FulfillContract", "wait", wait)
if err := c.SleepWithJitter(ctx, wait); err != nil {
return nil, err
}
wait = 2 * wait
goto redo
}
if err != nil {
return nil, fmt.Errorf("could not FulfillContract: %w", err)
}
c.emitContract(ctx, &res.Data.Contract)
c.emitAgentChange(ctx, &res.Data.Agent)
return &res.Data, nil
}