-
Notifications
You must be signed in to change notification settings - Fork 1
/
sync.go
122 lines (111 loc) · 3.92 KB
/
sync.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
package main
import (
"errors"
"regexp"
"strings"
"github.com/pelletier/go-toml"
"github.com/pelletier/go-toml/query"
"github.com/will7200/go-crypto-sync/internal/common"
"github.com/will7200/go-crypto-sync/internal/pc"
"github.com/will7200/go-crypto-sync/internal/providers"
_ "github.com/will7200/go-crypto-sync/internal/providers/bscscan"
_ "github.com/will7200/go-crypto-sync/internal/providers/coinbase"
_ "github.com/will7200/go-crypto-sync/internal/providers/coinbasepro"
_ "github.com/will7200/go-crypto-sync/internal/providers/etherscan"
"github.com/will7200/go-crypto-sync/pkg/personalcapital"
)
var (
personCapitalValues, _ = query.Compile("$.destinations.personalcapital")
)
type SyncCmd struct {
Destination string `help:"Sync to Destination"`
Holdings []string `arg name:"holding-accounts" help:"Holdings to fetch from"`
TokenPatterns []string `name:"token-pattern" help:"Only sync specific tokens"`
FilterTokensBy string `name:"filter-by" help:"filter property" default:"symbol"`
AddHoldings bool `name:"holdings-addition" help:"Allow adding new holdings in destination" default:"true"`
UpdateHoldings bool `name:"holdings-update" help:"Allows updating holdings in destination" default:"true"`
SkipZeroQuantities bool `name:"skip-zero-quantities" help:"Skip updates/removals for zero quantity holdings use this if you are filtering tokens" default:"false"`
}
func (s *SyncCmd) holdingOperations() common.HoldingOperation {
ao := common.HoldingOperation(0)
if s.AddHoldings {
ao |= common.AddHolding
}
if s.UpdateHoldings {
ao |= common.UpdateHolding
}
if s.SkipZeroQuantities {
ao |= common.SkipZeroQuantity
}
return ao
}
func (s *SyncCmd) Run(ctx *Context) error {
log := ctx.SugaredLogger.Named("sync")
switch s.Destination {
case "personalcapital":
case "pc":
s.Destination = "personalcapital"
default:
return errors.New("unknown destination for " + s.Destination)
}
var (
pricingData providers.Price
)
allHoldings := make(providers.Holdings, 0, 2)
if len(s.Holdings) == 1 && s.Holdings[0] == "all" {
s.Holdings = []string{}
for key, _ := range ctx.Config.Holdings {
s.Holdings = append(s.Holdings, key)
}
}
for _, holding := range s.Holdings {
log.Info("Fetching holdings from ", strings.Trim(holding, ""))
holdingsProvider, err := providers.GetAccountProvider(holding)
if err != nil {
log.Warnf("Skipping holding %s since provider doesn't exist", holding)
continue
}
provider, err := holdingsProvider.Open(providers.Config{Logger: ctx.Logger.Named("provider").Named(holding)}, ctx.Config.Holdings[holding])
if err != nil {
return err
}
account := provider.(providers.Account)
uHolding, err := account.GetHoldings()
if err != nil {
return err
}
allHoldings = append(allHoldings, uHolding...)
}
log.Infof("setting pricing data provider to %s", ctx.Config.PriceDataSource)
pricingData = getPricingProvider(ctx)
allHoldings = allHoldings.MapReduce()
if len(s.TokenPatterns) > 0 {
log.Infof("Filtering holdings with property %s matching [%s]", s.FilterTokensBy, strings.Join(s.TokenPatterns, ","))
pats := make([]*regexp.Regexp, len(s.TokenPatterns))
for index, pattern := range s.TokenPatterns {
rex, err := regexp.Compile(pattern)
if err != nil {
log.Fatal(err)
}
pats[index] = rex
}
allHoldings = allHoldings.FilterTokens(s.FilterTokensBy, pats...)
}
switch s.Destination {
case "personalcapital":
raw := personCapitalValues.Execute(ctx.Tree)
email := raw.Values()[0].(*toml.Tree).Get("email").(string)
password := raw.Values()[0].(*toml.Tree).Get("password").(string)
accountName := raw.Values()[0].(*toml.Tree).Get("accountName").(string)
cfg := personalcapital.NewConfiguration()
cfg.Debug = ctx.Debug
cfg.Logger = ctx.Logger
pc.Sync(pc.SyncParams{
Email: email,
Password: password,
Operations: s.holdingOperations(),
AccountName: accountName,
}, cfg, allHoldings, pricingData)
}
return nil
}