From e41d720867f4ed68f5710cfe7ee8ebce28adab79 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 7 Jul 2023 14:52:25 +0800 Subject: [PATCH] service/google: support reflect conversion --- pkg/service/google/sheets.go | 66 ++++++++++++++++++++++++++++++++ utils/google-spreadsheet/main.go | 24 +++++++----- 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/pkg/service/google/sheets.go b/pkg/service/google/sheets.go index c0d6e5381..495100418 100644 --- a/pkg/service/google/sheets.go +++ b/pkg/service/google/sheets.go @@ -2,9 +2,13 @@ package google import ( "fmt" + "reflect" + "time" "github.com/sirupsen/logrus" "google.golang.org/api/sheets/v4" + + "github.com/c9s/bbgo/pkg/fixedpoint" ) func ReadSheetValuesRange(srv *sheets.Service, spreadsheetId, readRange string) (*sheets.ValueRange, error) { @@ -43,6 +47,12 @@ func ValuesToCellData(values []interface{}) (cells []*sheets.CellData) { cells = append(cells, &sheets.CellData{ UserEnteredValue: &sheets.ExtendedValue{NumberValue: &typedValue}, }) + case int: + v := float64(typedValue) + cells = append(cells, &sheets.CellData{UserEnteredValue: &sheets.ExtendedValue{NumberValue: &v}}) + case int64: + v := float64(typedValue) + cells = append(cells, &sheets.CellData{UserEnteredValue: &sheets.ExtendedValue{NumberValue: &v}}) case bool: cells = append(cells, &sheets.CellData{ UserEnteredValue: &sheets.ExtendedValue{BoolValue: &typedValue}, @@ -57,6 +67,62 @@ func GetSpreadSheetURL(spreadsheetId string) string { return fmt.Sprintf("https://docs.google.com/spreadsheets/d/%s/edit#gid=0", spreadsheetId) } +func WriteStructHeader(srv *sheets.Service, spreadsheetId string, sheetId int64, structTag string, st interface{}) (*sheets.BatchUpdateSpreadsheetResponse, error) { + typeOfSt := reflect.TypeOf(st) + typeOfSt = typeOfSt.Elem() + + var headerTexts []interface{} + for i := 0; i < typeOfSt.NumField(); i++ { + tag := typeOfSt.Field(i).Tag + tagValue := tag.Get(structTag) + if len(tagValue) == 0 { + continue + } + + headerTexts = append(headerTexts, tagValue) + } + + return AppendRow(srv, spreadsheetId, sheetId, headerTexts) +} + +func WriteStructValues(srv *sheets.Service, spreadsheetId string, sheetId int64, structTag string, st interface{}) (*sheets.BatchUpdateSpreadsheetResponse, error) { + typeOfSt := reflect.TypeOf(st) + typeOfSt = typeOfSt.Elem() + + valueOfSt := reflect.ValueOf(st) + valueOfSt = valueOfSt.Elem() + + var texts []interface{} + for i := 0; i < typeOfSt.NumField(); i++ { + tag := typeOfSt.Field(i).Tag + tagValue := tag.Get(structTag) + if len(tagValue) == 0 { + continue + } + + valueInf := valueOfSt.Field(i).Interface() + + switch typedValue := valueInf.(type) { + case string: + texts = append(texts, typedValue) + case float64: + texts = append(texts, typedValue) + case int64: + texts = append(texts, typedValue) + case *float64: + texts = append(texts, typedValue) + case fixedpoint.Value: + texts = append(texts, typedValue.String()) + case *fixedpoint.Value: + texts = append(texts, typedValue.String()) + case time.Time: + texts = append(texts, typedValue.Format(time.RFC3339)) + } + } + + return AppendRow(srv, spreadsheetId, sheetId, texts) +} + func AppendRow(srv *sheets.Service, spreadsheetId string, sheetId int64, values []interface{}) (*sheets.BatchUpdateSpreadsheetResponse, error) { row := &sheets.RowData{} row.Values = ValuesToCellData(values) diff --git a/utils/google-spreadsheet/main.go b/utils/google-spreadsheet/main.go index 97812831f..d48a4f63d 100644 --- a/utils/google-spreadsheet/main.go +++ b/utils/google-spreadsheet/main.go @@ -13,7 +13,9 @@ import ( "google.golang.org/api/option" "google.golang.org/api/sheets/v4" + "github.com/c9s/bbgo/pkg/fixedpoint" googleservice "github.com/c9s/bbgo/pkg/service/google" + "github.com/c9s/bbgo/pkg/types" ) // Retrieve a token, saves the token, then returns the generated client. @@ -100,20 +102,24 @@ func main() { googleservice.DebugBatchUpdateSpreadsheetResponse(batchUpdateResp) - appendCellsResp, err := googleservice.AppendRow(srv, spreadsheetId, 0, []interface{}{ - "Date", - "Net Profit", - "Profit", - "Gross Profit", - "Gross Loss", - "Total Profit", - "Total Loss", + stats := types.NewProfitStats(types.Market{ + Symbol: "BTCUSDT", + BaseCurrency: "BTC", + QuoteCurrency: "USDT", }) + stats.TodayNetProfit = fixedpoint.NewFromFloat(100.0) + stats.TodayPnL = fixedpoint.NewFromFloat(100.0) + stats.TodayGrossLoss = fixedpoint.NewFromFloat(-100.0) + + _, err = googleservice.WriteStructHeader(srv, spreadsheetId, 0, "json", stats) if err != nil { log.Fatal(err) } - logrus.Infof("appendCellsResp: %+v", appendCellsResp) + _, err = googleservice.WriteStructValues(srv, spreadsheetId, 0, "json", stats) + if err != nil { + log.Fatal(err) + } readRange := "Sheet1!A2:E" resp, err := googleservice.ReadSheetValuesRange(srv, spreadsheetId, readRange)