From 0a5f6f69c65918afb8a3d6f41fad063419ac7e58 Mon Sep 17 00:00:00 2001 From: JmPotato Date: Mon, 19 Aug 2024 01:02:42 +0800 Subject: [PATCH] Deprecate the use of bean-report Signed-off-by: JmPotato --- script/bql.go | 28 +++++++++++++++++++++++----- script/config.go | 14 ++++++++------ script/utils.go | 9 ++++++++- service/stats.go | 29 +---------------------------- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/script/bql.go b/script/bql.go index 9f951eb..17b6815 100644 --- a/script/bql.go +++ b/script/bql.go @@ -104,13 +104,31 @@ func BQLQueryListByCustomSelect(ledgerConfig *Config, selectBql string, queryPar return nil } -func BeanReportAllPrices(ledgerConfig *Config) string { +func BeanReportAllPrices(ledgerConfig *Config) []CommodityPrice { beanFilePath := GetLedgerPriceFilePath(ledgerConfig.DataPath) - - LogInfo(ledgerConfig.Mail, "bean-report "+beanFilePath+" all_prices") - cmd := exec.Command("bean-report", beanFilePath, "all_prices") + var ( + command string + useBeanReport = checkCommandExists("bean-report") + ) + // `bean-report` had been deprecated since https://github.com/beancount/beancount/commit/a7c4f14f083de63e8d4e5a8d3664209daf95e1ec, + // we use `bean-query` instead. Here we add a check to use `bean-report` if `bean-query` is not installed for better compatibility. + if useBeanReport { + command = fmt.Sprintf("bean-report %s all_prices", beanFilePath) + } else { + // 'price' column works as a column placeholder to be consistent with the output of `bean-report`. + command = fmt.Sprintf(`bean-query %s "SELECT date, 'price', currency, price FROM account ~ 'Assets' WHERE price is not NULL"`, beanFilePath) + } + LogInfo(ledgerConfig.Mail, command) + cmd := exec.Command(command) output, _ := cmd.Output() - return string(output) + outputStr := string(output) + lines := strings.Split(outputStr, "\n") + LogInfo(ledgerConfig.Mail, outputStr) + // Remove the first two lines of the output since they are the header and separator with BQL output. + if !useBeanReport && len(lines) > 2 { + lines = lines[2:] + } + return newCommodityPriceListFromString(lines) } func bqlRawQuery(ledgerConfig *Config, selectBql string, queryParamsPtr *QueryParams, queryResultPtr interface{}) (string, error) { diff --git a/script/config.go b/script/config.go index 4c21e55..8d70c92 100644 --- a/script/config.go +++ b/script/config.go @@ -484,11 +484,8 @@ type CommodityPrice struct { Value string `json:"value"` } -func RefreshLedgerCurrency(ledgerConfig *Config) []LedgerCurrency { - // 查询货币获取当前汇率 - output := BeanReportAllPrices(ledgerConfig) - statsPricesResultList := make([]CommodityPrice, 0) - lines := strings.Split(output, "\n") +func newCommodityPriceListFromString(lines []string) []CommodityPrice { + commodityPriceList := make([]CommodityPrice, 0, len(lines)) // foreach lines for _, line := range lines { if strings.Trim(line, " ") == "" { @@ -496,14 +493,19 @@ func RefreshLedgerCurrency(ledgerConfig *Config) []LedgerCurrency { } // split line by " " words := strings.Fields(line) - statsPricesResultList = append(statsPricesResultList, CommodityPrice{ + commodityPriceList = append(commodityPriceList, CommodityPrice{ Date: words[0], Commodity: words[2], Value: words[3], Currency: words[4], }) } + return commodityPriceList +} +func RefreshLedgerCurrency(ledgerConfig *Config) []LedgerCurrency { + // 查询货币获取当前汇率 + statsPricesResultList := BeanReportAllPrices(ledgerConfig) // statsPricesResultList 转为 map existCurrencyMap := make(map[string]CommodityPrice) for _, statsPricesResult := range statsPricesResultList { diff --git a/script/utils.go b/script/utils.go index 0b45bc0..ff80f54 100644 --- a/script/utils.go +++ b/script/utils.go @@ -4,9 +4,16 @@ import ( "bytes" "math/rand" "net" + "os/exec" "time" ) +func checkCommandExists(command string) bool { + cmd := exec.Command(command, "--version") + _, err := cmd.Output() + return err == nil +} + func GetIpAddress() string { addrs, _ := net.InterfaceAddrs() for _, value := range addrs { @@ -53,7 +60,7 @@ func getTimeStamp(str_date string) Timestamp { return Timestamp(the_time.Unix()) } -//获取1到2个日期字符串中更大的日期 +// 获取1到2个日期字符串中更大的日期 func getMaxDate(str_date1 string, str_date2 string) string { var max_date string if str_date1 != "" && str_date2 == "" { diff --git a/service/stats.go b/service/stats.go index 0165029..399ec57 100644 --- a/service/stats.go +++ b/service/stats.go @@ -480,33 +480,6 @@ func StatsPayee(c *gin.Context) { OK(c, result) } -type StatsPricesResult struct { - Date string `json:"date"` - Commodity string `json:"commodity"` - Currency string `json:"operatingCurrency"` - Value string `json:"value"` -} - func StatsCommodityPrice(c *gin.Context) { - ledgerConfig := script.GetLedgerConfigFromContext(c) - output := script.BeanReportAllPrices(ledgerConfig) - script.LogInfo(ledgerConfig.Mail, output) - - statsPricesResultList := make([]StatsPricesResult, 0) - lines := strings.Split(output, "\n") - // foreach lines - for _, line := range lines { - if strings.Trim(line, " ") == "" { - continue - } - // split line by " " - words := strings.Fields(line) - statsPricesResultList = append(statsPricesResultList, StatsPricesResult{ - Date: words[0], - Commodity: words[2], - Value: words[3], - Currency: words[4], - }) - } - OK(c, statsPricesResultList) + OK(c, script.BeanReportAllPrices(script.GetLedgerConfigFromContext(c))) }