diff --git a/comdirect/cmd/account.go b/comdirect/cmd/account.go index 82bcfc7..4749476 100644 --- a/comdirect/cmd/account.go +++ b/comdirect/cmd/account.go @@ -1,11 +1,11 @@ package cmd import ( + "log" + "github.com/jsattler/go-comdirect/pkg/comdirect" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "log" - "os" ) var ( @@ -27,7 +27,7 @@ func Account(cmd *cobra.Command, args []string) { } switch formatFlag { case "json": - printJSON(balances) + writeJSON(balances) case "markdown": printAccountTable(balances) default: @@ -36,7 +36,7 @@ func Account(cmd *cobra.Command, args []string) { } func printAccountTable(account *comdirect.AccountBalances) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader([]string{"ID", "TYPE", "IBAN", "CREDIT LIMIT"}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") diff --git a/comdirect/cmd/balance.go b/comdirect/cmd/balance.go index d8a97d7..c4137a6 100644 --- a/comdirect/cmd/balance.go +++ b/comdirect/cmd/balance.go @@ -2,11 +2,11 @@ package cmd import ( "encoding/csv" + "log" + "github.com/jsattler/go-comdirect/pkg/comdirect" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "log" - "os" ) var ( @@ -28,7 +28,7 @@ func balance(cmd *cobra.Command, args []string) { switch formatFlag { case "json": - printJSON(balances) + writeJSON(balances) case "markdown": printBalanceTable(balances) case "csv": @@ -39,7 +39,7 @@ func balance(cmd *cobra.Command, args []string) { } func printBalanceCSV(balances *comdirect.AccountBalances) { - table := csv.NewWriter(os.Stdout) + table := csv.NewWriter(getOutputBuffer()) table.Write([]string{"ID", "TYPE", "IBAN", "BALANCE"}) for _, a := range balances.Values { table.Write([]string{a.AccountId, a.Account.AccountType.Text, a.Account.Iban, a.Balance.Value}) @@ -48,7 +48,7 @@ func printBalanceCSV(balances *comdirect.AccountBalances) { } func printBalanceTable(account *comdirect.AccountBalances) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader([]string{"ID", "TYPE", "IBAN", "BALANCE"}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") diff --git a/comdirect/cmd/depot.go b/comdirect/cmd/depot.go index 87176ba..86115b6 100644 --- a/comdirect/cmd/depot.go +++ b/comdirect/cmd/depot.go @@ -2,10 +2,10 @@ package cmd import ( "encoding/csv" + "github.com/jsattler/go-comdirect/pkg/comdirect" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "os" ) var ( @@ -27,7 +27,7 @@ func depot(cmd *cobra.Command, args []string) { } switch formatFlag { case "json": - printJSON(depots) + writeJSON(depots) case "markdown": printDepotsTable(depots) case "csv": @@ -38,15 +38,16 @@ func depot(cmd *cobra.Command, args []string) { } func printDepotsCSV(depots *comdirect.Depots) { - table := csv.NewWriter(os.Stdout) + table := csv.NewWriter(getOutputBuffer()) table.Write([]string{"DEPOT ID", "DISPLAY ID", "HOLDER NAME", "CLIENT ID"}) for _, d := range depots.Values { table.Write([]string{d.DepotId, d.DepotDisplayId, d.HolderName, d.ClientId}) } table.Flush() } + func printDepotsTable(depots *comdirect.Depots) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader([]string{"DEPOT ID", "DISPLAY ID", "HOLDER NAME", "CLIENT ID"}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") diff --git a/comdirect/cmd/document.go b/comdirect/cmd/document.go index 8078ad3..d3036b2 100644 --- a/comdirect/cmd/document.go +++ b/comdirect/cmd/document.go @@ -2,13 +2,13 @@ package cmd import ( "fmt" - "github.com/jsattler/go-comdirect/pkg/comdirect" - "github.com/olekukonko/tablewriter" - "github.com/spf13/cobra" "log" - "os" "strings" "time" + + "github.com/jsattler/go-comdirect/pkg/comdirect" + "github.com/olekukonko/tablewriter" + "github.com/spf13/cobra" ) var ( @@ -49,7 +49,7 @@ func document(cmd *cobra.Command, args []string) { } else { switch formatFlag { case "json": - printJSON(filtered) + writeJSON(filtered) case "markdown": printDocumentTable(filtered) default: @@ -68,7 +68,7 @@ func download(client *comdirect.Client, documents *comdirect.Documents) { log.Fatal("failed to download document: ", err) } // TODO: think about a better solution to limit download requests to 10/sec - if i % 10 == 0 && i != 0{ + if i%10 == 0 && i != 0 { time.Sleep(900 * time.Millisecond) } fmt.Printf("Download complete for document with ID %s\n", d.DocumentID) @@ -76,7 +76,7 @@ func download(client *comdirect.Client, documents *comdirect.Documents) { } func printDocumentTable(documents *comdirect.Documents) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader([]string{"ID", "NAME", "DATE", "OPENED", "TYPE"}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") diff --git a/comdirect/cmd/io.go b/comdirect/cmd/io.go new file mode 100644 index 0000000..8335d37 --- /dev/null +++ b/comdirect/cmd/io.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "encoding/json" + "io" + "log" + "os" + + "github.com/spf13/cobra" +) + +// Format JSON input and write to global output file which might be stdout. +func writeJSON(v interface{}) { + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + log.Fatal(err) + } + + getOutputBuffer().Write(b) +} + +func getOutputBuffer() io.Writer { + return &outputBuffer +} + +func writeToOutputFile(cmd *cobra.Command, args []string) { + if fileFlag == "-" { + // We have either no file flag at all or the user explicitly specified "-", so we simply write to stdout + outputBuffer.WriteTo(os.Stdout) + } else { + f, err := os.OpenFile(fileFlag, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal(err.Error()) + } else { + outputBuffer.WriteTo(f) + f.Close() + } + } +} diff --git a/comdirect/cmd/position.go b/comdirect/cmd/position.go index ec82e70..0dc07e7 100644 --- a/comdirect/cmd/position.go +++ b/comdirect/cmd/position.go @@ -2,10 +2,10 @@ package cmd import ( "encoding/csv" + "github.com/jsattler/go-comdirect/pkg/comdirect" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "os" ) var ( @@ -28,7 +28,7 @@ func position(cmd *cobra.Command, args []string) { } switch formatFlag { case "json": - printJSON(positions) + writeJSON(positions) case "markdown": printPositionsTable(positions) case "csv": @@ -39,7 +39,7 @@ func position(cmd *cobra.Command, args []string) { } func printPositionsCSV(positions *comdirect.DepotPositions) { - table := csv.NewWriter(os.Stdout) + table := csv.NewWriter(getOutputBuffer()) table.Write([]string{"POSITION ID", "WKN", "QUANTITY", "CURRENT PRICE", "PREVDAY %", "PURCHASE %", "PURCHASE", "CURRENT"}) for _, d := range positions.Values { table.Write([]string{d.PositionId, d.Wkn, d.Quantity.Value, d.CurrentPrice.Price.Value, d.ProfitLossPrevDayRel, d.ProfitLossPurchaseRel, d.PurchaseValue.Value, d.CurrentValue.Value}) @@ -48,7 +48,7 @@ func printPositionsCSV(positions *comdirect.DepotPositions) { } func printPositionsTable(depots *comdirect.DepotPositions) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader([]string{"POSITION ID", "WKN", "QUANTITY", "CURRENT PRICE", "PREVDAY %", "PURCHASE %", "PURCHASE", "CURRENT"}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) table.SetCenterSeparator("|") diff --git a/comdirect/cmd/report.go b/comdirect/cmd/report.go index 8b00f67..f4a9700 100644 --- a/comdirect/cmd/report.go +++ b/comdirect/cmd/report.go @@ -2,10 +2,10 @@ package cmd import ( "encoding/csv" + "github.com/jsattler/go-comdirect/pkg/comdirect" "github.com/olekukonko/tablewriter" "github.com/spf13/cobra" - "os" ) var ( @@ -28,7 +28,7 @@ func report(cmd *cobra.Command, args []string) { } switch formatFlag { case "json": - printJSON(reports) + writeJSON(reports) case "markdown": printReportsTable(reports) case "csv": @@ -39,7 +39,7 @@ func report(cmd *cobra.Command, args []string) { } func printReportsCSV(reports *comdirect.Reports) { - table := csv.NewWriter(os.Stdout) + table := csv.NewWriter(getOutputBuffer()) table.Write(reportsHeader) for _, r := range reports.Values { var balance string @@ -54,7 +54,7 @@ func printReportsCSV(reports *comdirect.Reports) { } func printReportsTable(reports *comdirect.Reports) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader(reportsHeader) table.SetColumnAlignment([]int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_RIGHT}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) diff --git a/comdirect/cmd/root.go b/comdirect/cmd/root.go index 2adc3b4..b96e6d6 100644 --- a/comdirect/cmd/root.go +++ b/comdirect/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "bytes" "context" "fmt" "log" @@ -26,10 +27,14 @@ var ( passwordFlag string clientIDFlag string clientSecretFlag string + fileFlag string + + outputBuffer bytes.Buffer rootCmd = &cobra.Command{ - Use: "comdirect", - Short: "comdirect is a CLI tool to interact with the comdirect REST API", + Use: "comdirect", + Short: "comdirect is a CLI tool to interact with the comdirect REST API", + PersistentPostRun: writeToOutputFile, } ) @@ -54,6 +59,7 @@ func init() { rootCmd.PersistentFlags().StringVarP(&formatFlag, "format", "f", "markdown", "output format (markdown, csv or json)") rootCmd.PersistentFlags().IntVarP(&timeoutFlag, "timeout", "t", 30, "timeout in seconds to validate session TAN (default 30sec)") rootCmd.PersistentFlags().StringVar(&excludeFlag, "exclude", "", "exclude field from response") + rootCmd.PersistentFlags().StringVarP(&fileFlag, "output", "o", "-", "file name to write the output to (defaults to stdout)") rootCmd.AddCommand(documentCmd) rootCmd.AddCommand(depotCmd) @@ -106,5 +112,6 @@ func initClient() *comdirect.Client { } return client } + return comdirect.NewWithAuthentication(authentication) } diff --git a/comdirect/cmd/transaction.go b/comdirect/cmd/transaction.go index 51a803b..98aac42 100644 --- a/comdirect/cmd/transaction.go +++ b/comdirect/cmd/transaction.go @@ -2,10 +2,8 @@ package cmd import ( "encoding/csv" - "encoding/json" "fmt" "log" - "os" "strconv" "time" @@ -45,7 +43,7 @@ func transaction(cmd *cobra.Command, args []string) { switch formatFlag { case "json": - printJSON(transactions) + writeJSON(transactions) case "markdown": printTransactionTable(transactions) case "csv": @@ -103,16 +101,8 @@ func getTransactionsSince(since string, client *comdirect.Client, accountID stri return transactions } -func printJSON(v interface{}) { - b, err := json.MarshalIndent(v, "", " ") - if err != nil { - log.Fatal(err) - } - fmt.Println(string(b)) -} - func printTransactionCSV(transactions *comdirect.AccountTransactions) { - table := csv.NewWriter(os.Stdout) + table := csv.NewWriter(getOutputBuffer()) table.Write(transactionHeader) for _, t := range transactions.Values { holderName := t.Remitter.HolderName @@ -126,7 +116,7 @@ func printTransactionCSV(transactions *comdirect.AccountTransactions) { table.Flush() } func printTransactionTable(transactions *comdirect.AccountTransactions) { - table := tablewriter.NewWriter(os.Stdout) + table := tablewriter.NewWriter(getOutputBuffer()) table.SetHeader(transactionHeader) table.SetColumnAlignment([]int{tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_LEFT, tablewriter.ALIGN_RIGHT}) table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})