diff --git a/main.go b/main.go index b823d77..5ebfb2e 100644 --- a/main.go +++ b/main.go @@ -30,15 +30,21 @@ type Quote struct { const API = "https://query1.finance.yahoo.com/v7/finance/spark?symbols=%s&range=1m" +type Price struct { + Commodity string + Currency string + Price float64 +} + func main() { - apiToken := flag.String("a", "demo", "Alpha Vantage API Token") ledgerBinary := flag.String("b", "ledger", "Ledger Binary") ledgerFile := flag.String("f", "ledger.ledger", "Ledger File") priceDbFile := flag.String("p", "prices.db", "Price Database File") mappingFile := flag.String("m", "mapping", "Commodities Name Mapping File") flag.Parse() - commodities := GetCommodities(*ledgerFile, *ledgerBinary, *mappingFile) + mappings := GetMapping(*mappingFile) + commodities := GetCommodities(*ledgerFile, *ledgerBinary) pricedb, err := os.OpenFile(*priceDbFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -46,6 +52,10 @@ func main() { } defer pricedb.Close() + currency := mappings["$"] + log.Println("Currency", currency) + prices := make(map[string]Price) + start := time.Now() for i, c := range commodities { if i+1%5 == 0 { @@ -56,45 +66,73 @@ func main() { } start = time.Now() } + if c == "$" { + continue + } - priceString, err := GetPriceString(c, *apiToken) + ticker := c + if value, ok := mappings[c]; ok { + ticker = value + } + price, err := GetPriceString(c, ticker) if err != nil { log.Println("Skipped " + c) continue } - pricedb.WriteString("P " + GetTimeString() + " " + c + " " + priceString[:len(priceString)-2] + "\n") + prices[c] = price + } + + for c, p := range prices { + result := fmt.Sprintf("P %s %s $%f\n", GetTimeString(), c, p.GetPrice(currency, prices)) + pricedb.WriteString(result) } log.Println("Stock price update complete") } -func GetPriceString(ticker string, apiToken string) (string, error) { +func (p Price) GetPrice(currency string, prices map[string]Price) float64 { + if p.Commodity == currency { + return 1 + } + if p.Currency == currency { + return p.Price + } + if altCurrency, ok := prices[p.Currency]; ok { + return p.Price * altCurrency.GetPrice(currency, prices) + } + return 0 +} + +func GetPriceString(commodity, ticker string) (price Price, err error) { resp, err := http.Get(fmt.Sprintf(API, ticker)) if err != nil { - return "", err + return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { - return "", err + return } var f Quote err = json.Unmarshal(body, &f) if err != nil { - return "", err + return } - log.Println(f) - - return fmt.Sprintf("$%f", f.Spark.Result[0].Response[0].Meta.RegularMarketPrice), nil + price = Price{ + Commodity: commodity, + Price: f.Spark.Result[0].Response[0].Meta.RegularMarketPrice, + Currency: f.Spark.Result[0].Response[0].Meta.Currency, + } + return } func GetTimeString() string { return time.Now().Format("2006-01-02 15:04:05") } -func GetCommodities(ledger string, binary string, mappingFile string) []string { +func GetCommodities(ledger string, binary string) []string { cmd := exec.Command(binary, "-f", ledger, "commodities") out, err := cmd.Output() if err != nil { @@ -102,17 +140,12 @@ func GetCommodities(ledger string, binary string, mappingFile string) []string { } a := strings.Split(string(out), "\n") sliceOut := a[:len(a)-1] - mapping := GetMapping(mappingFile) commodities := make([]string, 0) for _, e := range sliceOut { e = strings.Trim(e, `"`) - if value, ok := mapping[e]; ok { - e = value - } commodities = append(commodities, e) } - log.Println(commodities) return commodities } @@ -132,7 +165,6 @@ func GetMapping(mappingFile string) map[string]string { result[arr[0]] = strings.Trim(arr[1], "\n") } } - log.Println(result) return result }