From 63462ac8efda2d9b966e41a0bd8641fc4cfd07ca Mon Sep 17 00:00:00 2001 From: Jade Date: Fri, 16 Oct 2020 23:18:02 +0100 Subject: [PATCH 1/8] add finnhub modules --- go.mod | 1 + modules/finnhub/finnhub.go | 37 +++++++++++++ modules/finnhub/settings.go | 52 +++++++++++++++++++ modules/finnhub/widget.go | 100 ++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 modules/finnhub/finnhub.go create mode 100644 modules/finnhub/settings.go create mode 100644 modules/finnhub/widget.go diff --git a/go.mod b/go.mod index dce822ff..ad5f6090 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/google/go-github/v32 v32.1.0 github.com/gophercloud/gophercloud v0.5.0 // indirect + github.com/gorilla/websocket v1.4.0 github.com/hekmon/cunits v2.0.1+incompatible // indirect github.com/hekmon/transmissionrpc v0.0.0-20190525133028-1d589625bacd github.com/imdario/mergo v0.3.8 // indirect diff --git a/modules/finnhub/finnhub.go b/modules/finnhub/finnhub.go new file mode 100644 index 00000000..c4f5d98a --- /dev/null +++ b/modules/finnhub/finnhub.go @@ -0,0 +1,37 @@ +package finnhub + +import ( + "fmt" + "encoding/json" + "github.com/gorilla/websocket" +) + + +func FetchExchangeRates(settings *Settings) (map[string]map[string]float64, error) { + out := map[string]map[string]float64{} + + for base, rates := range settings.rates { + resp, err := http.Get(fmt.Sprintf("https://api.exchangeratesapi.io/latest?base=%s", base)) + if err != nil { + return nil, err + } + defer func() { _ = resp.Body.Close() }() + + var data Response + err = utils.ParseJSON(&data, resp.Body) + if err != nil { + return nil, err + } + + out[base] = map[string]float64{} + + for _, currency := range rates { + rate, ok := data.Rates[currency] + if ok { + out[base][currency] = rate + } + } + } + + return out, nil +} diff --git a/modules/finnhub/settings.go b/modules/finnhub/settings.go new file mode 100644 index 00000000..330ac912 --- /dev/null +++ b/modules/finnhub/settings.go @@ -0,0 +1,52 @@ +package finnhub + +import ( + "github.com/olebedev/config" + "github.com/wtfutil/wtf/cfg" +) + +const ( + defaultFocusable = false + defaultTitle = "Exchange rates" +) + +// Settings defines the configuration properties for this module +type Settings struct { + common *cfg.Common + + precision int `help:"How many decimal places to display." optional:"true"` + + rates map[string][]string `help:"Defines what currency rates we want to know about"` + order []string +} + +// NewSettingsFromYAML creates a new settings instance from a YAML config block +func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { + settings := Settings{ + common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), + + precision: ymlConfig.UInt("precision", 7), + + rates: map[string][]string{}, + order: []string{}, + } + + raw := ymlConfig.UMap("rates", map[string]interface{}{}) + for key, value := range raw { + settings.order = append(settings.order, key) + settings.rates[key] = []string{} + switch value := value.(type) { + case string: + settings.rates[key] = []string{value} + case []interface{}: + for _, currency := range value { + str, ok := currency.(string) + if ok { + settings.rates[key] = append(settings.rates[key], str) + } + } + } + } + + return &settings +} diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go new file mode 100644 index 00000000..1ce623ca --- /dev/null +++ b/modules/finnhub/widget.go @@ -0,0 +1,100 @@ +package finnhub + +import ( + "fmt" + "regexp" + "sort" + + "github.com/rivo/tview" + "github.com/wtfutil/wtf/view" + "github.com/wtfutil/wtf/wtf" +) + +type Widget struct { + view.ScrollableWidget + + settings *Settings + rates map[string]map[string]float64 + err error +} + +func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { + widget := Widget{ + ScrollableWidget: view.NewScrollableWidget(app, settings.common), + + settings: settings, + } + + widget.SetRenderFunction(widget.Render) + + return &widget +} + +/* -------------------- Exported Functions -------------------- */ + +func (widget *Widget) Refresh() { + + rates, err := FetchExchangeRates(widget.settings) + if err != nil { + widget.err = err + } else { + widget.rates = rates + } + + // The last call should always be to the display function + widget.Render() +} + +func (widget *Widget) Render() { + widget.Redraw(widget.content) +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) content() (string, string, bool) { + if widget.err != nil { + widget.View.SetWrap(true) + return widget.CommonSettings().Title, widget.err.Error(), false + } + + // Sort the bases alphabetically to ensure consistent display ordering + bases := []string{} + for base := range widget.settings.rates { + bases = append(bases, base) + } + sort.Strings(bases) + + out := "" + + for idx, base := range bases { + rates := widget.settings.rates[base] + + rowColor := widget.CommonSettings().RowColor(idx) + + for _, cur := range rates { + rate := widget.rates[base][cur] + + out += fmt.Sprintf( + "[%s]1 %s = %s %s[white]\n", + rowColor, + base, + widget.formatConversionRate(rate), + cur, + ) + + idx++ + } + } + + widget.View.SetWrap(false) + return widget.CommonSettings().Title, out, false +} + +// formatConversionRate takes the raw conversion float and formats it to the precision the +// user specifies in their config (or to the default value) +func (widget *Widget) formatConversionRate(rate float64) string { + rate = wtf.TruncateFloat64(rate, widget.settings.precision) + + r, _ := regexp.Compile(`\.?0*$`) + return r.ReplaceAllString(fmt.Sprintf("%10.7f", rate), "") +} From 4d3e9506e4c1a9de5cbf06b244838e5f33f01598 Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 00:03:07 +0100 Subject: [PATCH 2/8] added finnhub mod --- modules/finnhub/client.go | 77 ++++++++++++++++++++++++++++++ modules/finnhub/client_test.go | 24 ++++++++++ modules/finnhub/finnhub.go | 37 --------------- modules/finnhub/quote.go | 12 +++++ modules/finnhub/settings.go | 36 ++++---------- modules/finnhub/widget.go | 86 ++++++++++------------------------ 6 files changed, 149 insertions(+), 123 deletions(-) create mode 100644 modules/finnhub/client.go create mode 100644 modules/finnhub/client_test.go delete mode 100644 modules/finnhub/finnhub.go create mode 100644 modules/finnhub/quote.go diff --git a/modules/finnhub/client.go b/modules/finnhub/client.go new file mode 100644 index 00000000..320a048d --- /dev/null +++ b/modules/finnhub/client.go @@ -0,0 +1,77 @@ +package finnhub + +import ( + "fmt" + "net/http" + "net/url" + "encoding/json" + //"github.com/wtfutil/wtf/utils" +) + +// Client .. +type Client struct { + symbols []string + apiKey string +} + +// NewClient .. +func NewClient(symbols []string, apiKey string) *Client { + client := Client{ + symbols: symbols, + apiKey: apiKey, + } + + return &client +} + +// Getquote .. +func (client *Client) Getquote() ([]Quote, error) { + quotes := []Quote{} + + for _, s := range client.symbols { + resp, err := client.finnhubRequest(s) + if err != nil { + return quotes, err + } + + var quote Quote + quote.Stock = s + json.NewDecoder(resp.Body).Decode("e) + quotes = append(quotes, quote) + } + + return quotes, nil +} + +/* -------------------- Unexported Functions -------------------- */ + +var ( + finnhubURL = &url.URL{Scheme: "https", Host: "finnhub.io", Path: "/api/v1/quote"} +) + +func (client *Client) finnhubRequest(symbol string) (*http.Response, error) { + params := url.Values{} + params.Add("symbol", symbol) + params.Add("token", client.apiKey) + + url := finnhubURL.ResolveReference(&url.URL{RawQuery: params.Encode()}) + + req, err := http.NewRequest("GET", url.String(), nil) + req.Header.Add("Accept", "application/json") + req.Header.Add("Content-Type", "application/json") + if err != nil { + return nil, err + } + + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + + if resp.StatusCode < 200 || resp.StatusCode > 299 { + return nil, fmt.Errorf(resp.Status) + } + + return resp, nil +} diff --git a/modules/finnhub/client_test.go b/modules/finnhub/client_test.go new file mode 100644 index 00000000..91647ee7 --- /dev/null +++ b/modules/finnhub/client_test.go @@ -0,0 +1,24 @@ +package finnhub + +import ( + "fmt" + "testing" +) +func TestFinnhubClient(t *testing.T){ + testClient := &Client { + symbols: []string{ + "AAPL", + "MSFT", + }, + apiKey: "", + } + + r, err := testClient.Getquote() + if err != nil { + fmt.Println(err) + } + + fmt.Println(r[0].Stock, r[0].C) + fmt.Println(r[1].Stock, r[1].C) + +} \ No newline at end of file diff --git a/modules/finnhub/finnhub.go b/modules/finnhub/finnhub.go deleted file mode 100644 index c4f5d98a..00000000 --- a/modules/finnhub/finnhub.go +++ /dev/null @@ -1,37 +0,0 @@ -package finnhub - -import ( - "fmt" - "encoding/json" - "github.com/gorilla/websocket" -) - - -func FetchExchangeRates(settings *Settings) (map[string]map[string]float64, error) { - out := map[string]map[string]float64{} - - for base, rates := range settings.rates { - resp, err := http.Get(fmt.Sprintf("https://api.exchangeratesapi.io/latest?base=%s", base)) - if err != nil { - return nil, err - } - defer func() { _ = resp.Body.Close() }() - - var data Response - err = utils.ParseJSON(&data, resp.Body) - if err != nil { - return nil, err - } - - out[base] = map[string]float64{} - - for _, currency := range rates { - rate, ok := data.Rates[currency] - if ok { - out[base][currency] = rate - } - } - } - - return out, nil -} diff --git a/modules/finnhub/quote.go b/modules/finnhub/quote.go new file mode 100644 index 00000000..b8e9af86 --- /dev/null +++ b/modules/finnhub/quote.go @@ -0,0 +1,12 @@ +package finnhub + +type Quote struct { + C float64 `json:"c"` + H float64 `json:"h"` + L float64 `json:"l"` + O float64 `json:"o"` + Pc float64 `json:"pc"` + T int `json:"t"` + + Stock string +} \ No newline at end of file diff --git a/modules/finnhub/settings.go b/modules/finnhub/settings.go index 330ac912..20832e1a 100644 --- a/modules/finnhub/settings.go +++ b/modules/finnhub/settings.go @@ -3,50 +3,34 @@ package finnhub import ( "github.com/olebedev/config" "github.com/wtfutil/wtf/cfg" + "github.com/wtfutil/wtf/utils" + "os" ) const ( - defaultFocusable = false - defaultTitle = "Exchange rates" + defaultFocusable = true + defaultTitle = "Stocks" ) // Settings defines the configuration properties for this module type Settings struct { common *cfg.Common - precision int `help:"How many decimal places to display." optional:"true"` - - rates map[string][]string `help:"Defines what currency rates we want to know about"` - order []string + apiKey string `help:"Your finnhub API token."` + symbols []string `help:"An array of stocks symbols (i.e. AAPL, MSFT)"` } // NewSettingsFromYAML creates a new settings instance from a YAML config block func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { + settings := Settings{ common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), - precision: ymlConfig.UInt("precision", 7), - - rates: map[string][]string{}, - order: []string{}, + apiKey: ymlConfig.UString("apiKey", ymlConfig.UString("apikey", os.Getenv("WTF_FINNHUB_API_KEY"))), + symbols: utils.ToStrs(ymlConfig.UList("symbols")), } - raw := ymlConfig.UMap("rates", map[string]interface{}{}) - for key, value := range raw { - settings.order = append(settings.order, key) - settings.rates[key] = []string{} - switch value := value.(type) { - case string: - settings.rates[key] = []string{value} - case []interface{}: - for _, currency := range value { - str, ok := currency.(string) - if ok { - settings.rates[key] = append(settings.rates[key], str) - } - } - } - } + cfg.ModuleSecret(name, globalConfig, &settings.apiKey).Load() return &settings } diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go index 1ce623ca..fd6fdad1 100644 --- a/modules/finnhub/widget.go +++ b/modules/finnhub/widget.go @@ -2,99 +2,65 @@ package finnhub import ( "fmt" - "regexp" - "sort" "github.com/rivo/tview" "github.com/wtfutil/wtf/view" - "github.com/wtfutil/wtf/wtf" ) +// Widget .. type Widget struct { - view.ScrollableWidget + view.TextWidget + *Client settings *Settings - rates map[string]map[string]float64 - err error } -func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) *Widget { +// NewWidget .. +func NewWidget(app *tview.Application, settings *Settings) *Widget { widget := Widget{ - ScrollableWidget: view.NewScrollableWidget(app, settings.common), + TextWidget: view.NewTextWidget(app, settings.common), + Client: NewClient(settings.symbols, settings.apiKey), settings: settings, } - widget.SetRenderFunction(widget.Render) - return &widget } /* -------------------- Exported Functions -------------------- */ func (widget *Widget) Refresh() { - - rates, err := FetchExchangeRates(widget.settings) - if err != nil { - widget.err = err - } else { - widget.rates = rates + if widget.Disabled() { + return } - // The last call should always be to the display function - widget.Render() -} - -func (widget *Widget) Render() { widget.Redraw(widget.content) } /* -------------------- Unexported Functions -------------------- */ func (widget *Widget) content() (string, string, bool) { - if widget.err != nil { - widget.View.SetWrap(true) - return widget.CommonSettings().Title, widget.err.Error(), false - } + quotes, err := widget.Client.Getquote() - // Sort the bases alphabetically to ensure consistent display ordering - bases := []string{} - for base := range widget.settings.rates { - bases = append(bases, base) - } - sort.Strings(bases) + title := fmt.Sprintf("%s - from finnhub api", widget.CommonSettings().Title) + var str string + wrap := false + if err != nil { + wrap = true + str = err.Error() + } else { + for idx, q := range quotes { + if idx > 10 { + break + } - out := "" - - for idx, base := range bases { - rates := widget.settings.rates[base] - - rowColor := widget.CommonSettings().RowColor(idx) - - for _, cur := range rates { - rate := widget.rates[base][cur] - - out += fmt.Sprintf( - "[%s]1 %s = %s %s[white]\n", - rowColor, - base, - widget.formatConversionRate(rate), - cur, + str += fmt.Sprintf( + "[%s]: %s \n", + q.Stock, + q.C, ) - - idx++ } } - widget.View.SetWrap(false) - return widget.CommonSettings().Title, out, false -} - -// formatConversionRate takes the raw conversion float and formats it to the precision the -// user specifies in their config (or to the default value) -func (widget *Widget) formatConversionRate(rate float64) string { - rate = wtf.TruncateFloat64(rate, widget.settings.precision) - - r, _ := regexp.Compile(`\.?0*$`) - return r.ReplaceAllString(fmt.Sprintf("%10.7f", rate), "") + return title, str, wrap } From 1ff75dd4cfc1bd4cabf33d6d17328c64c810f395 Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 00:15:29 +0100 Subject: [PATCH 3/8] update --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index ad5f6090..dce822ff 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,6 @@ require ( github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/google/go-github/v32 v32.1.0 github.com/gophercloud/gophercloud v0.5.0 // indirect - github.com/gorilla/websocket v1.4.0 github.com/hekmon/cunits v2.0.1+incompatible // indirect github.com/hekmon/transmissionrpc v0.0.0-20190525133028-1d589625bacd github.com/imdario/mergo v0.3.8 // indirect From 5c6833a0dfed8055cbe6cb742b43c723d2fc3382 Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 00:42:03 +0100 Subject: [PATCH 4/8] add the module to the widget_maker.go --- app/widget_maker.go | 4 ++++ modules/finnhub/client.go | 1 - modules/finnhub/settings.go | 2 +- modules/finnhub/widget.go | 5 +++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/widget_maker.go b/app/widget_maker.go index e787e2a2..ca81445a 100644 --- a/app/widget_maker.go +++ b/app/widget_maker.go @@ -73,6 +73,7 @@ import ( "github.com/wtfutil/wtf/modules/weatherservices/weather" "github.com/wtfutil/wtf/modules/zendesk" "github.com/wtfutil/wtf/wtf" + "github.com/wtfutil/wtf/modules/finnhub" ) // MakeWidget creates and returns instances of widgets @@ -308,6 +309,9 @@ func MakeWidget( case "exchangerates": settings := exchangerates.NewSettingsFromYAML(moduleName, moduleConfig, config) widget = exchangerates.NewWidget(app, pages, settings) + case "finnhub": + settings := finnhub.NewSettingsFromYAML(moduleName, moduleConfig, config) + widget = finnhub.NewWidget(app, settings) default: settings := unknown.NewSettingsFromYAML(moduleName, moduleConfig, config) widget = unknown.NewWidget(app, settings) diff --git a/modules/finnhub/client.go b/modules/finnhub/client.go index 320a048d..44c518b7 100644 --- a/modules/finnhub/client.go +++ b/modules/finnhub/client.go @@ -5,7 +5,6 @@ import ( "net/http" "net/url" "encoding/json" - //"github.com/wtfutil/wtf/utils" ) // Client .. diff --git a/modules/finnhub/settings.go b/modules/finnhub/settings.go index 20832e1a..80b258fe 100644 --- a/modules/finnhub/settings.go +++ b/modules/finnhub/settings.go @@ -9,7 +9,7 @@ import ( const ( defaultFocusable = true - defaultTitle = "Stocks" + defaultTitle = "Finnhub Stock Price" ) // Settings defines the configuration properties for this module diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go index fd6fdad1..f39aed37 100644 --- a/modules/finnhub/widget.go +++ b/modules/finnhub/widget.go @@ -42,7 +42,7 @@ func (widget *Widget) Refresh() { func (widget *Widget) content() (string, string, bool) { quotes, err := widget.Client.Getquote() - title := fmt.Sprintf("%s - from finnhub api", widget.CommonSettings().Title) + title := fmt.Sprintf("%s", widget.CommonSettings().Title) var str string wrap := false if err != nil { @@ -55,7 +55,8 @@ func (widget *Widget) content() (string, string, bool) { } str += fmt.Sprintf( - "[%s]: %s \n", + "[%d]: %s %.2f\n", + idx, q.Stock, q.C, ) From d152a8beee624388fbd6635da3a7d6ab6b4569d2 Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 01:07:04 +0100 Subject: [PATCH 5/8] fix go lint --- modules/finnhub/client.go | 7 +++++-- modules/finnhub/client_test.go | 9 +++++---- modules/finnhub/quote.go | 2 +- modules/finnhub/widget.go | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/finnhub/client.go b/modules/finnhub/client.go index 44c518b7..45dd7c7c 100644 --- a/modules/finnhub/client.go +++ b/modules/finnhub/client.go @@ -1,10 +1,10 @@ package finnhub import ( + "encoding/json" "fmt" "net/http" "net/url" - "encoding/json" ) // Client .. @@ -35,7 +35,10 @@ func (client *Client) Getquote() ([]Quote, error) { var quote Quote quote.Stock = s - json.NewDecoder(resp.Body).Decode("e) + err = json.NewDecoder(resp.Body).Decode("e) + if err != nil { + return quotes, err + } quotes = append(quotes, quote) } diff --git a/modules/finnhub/client_test.go b/modules/finnhub/client_test.go index 91647ee7..c73be5ad 100644 --- a/modules/finnhub/client_test.go +++ b/modules/finnhub/client_test.go @@ -1,11 +1,12 @@ package finnhub import ( - "fmt" + "fmt" "testing" ) -func TestFinnhubClient(t *testing.T){ - testClient := &Client { + +func TestFinnhubClient(t *testing.T) { + testClient := &Client{ symbols: []string{ "AAPL", "MSFT", @@ -21,4 +22,4 @@ func TestFinnhubClient(t *testing.T){ fmt.Println(r[0].Stock, r[0].C) fmt.Println(r[1].Stock, r[1].C) -} \ No newline at end of file +} diff --git a/modules/finnhub/quote.go b/modules/finnhub/quote.go index b8e9af86..36704b28 100644 --- a/modules/finnhub/quote.go +++ b/modules/finnhub/quote.go @@ -9,4 +9,4 @@ type Quote struct { T int `json:"t"` Stock string -} \ No newline at end of file +} diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go index f39aed37..378d11d3 100644 --- a/modules/finnhub/widget.go +++ b/modules/finnhub/widget.go @@ -42,7 +42,7 @@ func (widget *Widget) Refresh() { func (widget *Widget) content() (string, string, bool) { quotes, err := widget.Client.Getquote() - title := fmt.Sprintf("%s", widget.CommonSettings().Title) + title := widget.CommonSettings().Title var str string wrap := false if err != nil { From 64fa5acccb9bb3ba704eb61f2f9a6af3d043aec0 Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 01:18:40 +0100 Subject: [PATCH 6/8] gofmt --- app/widget_maker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/widget_maker.go b/app/widget_maker.go index ca81445a..12abc86d 100644 --- a/app/widget_maker.go +++ b/app/widget_maker.go @@ -23,6 +23,7 @@ import ( "github.com/wtfutil/wtf/modules/docker" "github.com/wtfutil/wtf/modules/exchangerates" "github.com/wtfutil/wtf/modules/feedreader" + "github.com/wtfutil/wtf/modules/finnhub" "github.com/wtfutil/wtf/modules/football" "github.com/wtfutil/wtf/modules/gcal" "github.com/wtfutil/wtf/modules/gerrit" @@ -73,7 +74,6 @@ import ( "github.com/wtfutil/wtf/modules/weatherservices/weather" "github.com/wtfutil/wtf/modules/zendesk" "github.com/wtfutil/wtf/wtf" - "github.com/wtfutil/wtf/modules/finnhub" ) // MakeWidget creates and returns instances of widgets From a728d448cb93ca9094a4ebc1c6e5757e024b3e5d Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 20:51:39 +0100 Subject: [PATCH 7/8] update the views --- go.mod | 2 ++ go.sum | 14 ++++++++++++++ modules/finnhub/settings.go | 8 ++++---- modules/finnhub/widget.go | 20 ++++++++------------ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index dce822ff..61023202 100644 --- a/go.mod +++ b/go.mod @@ -25,12 +25,14 @@ require ( github.com/dustin/go-humanize v1.0.0 github.com/gdamore/tcell v1.4.0 github.com/go-ole/go-ole v1.2.4 // indirect + github.com/go-openapi/strfmt v0.19.6 // indirect github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/google/go-github/v32 v32.1.0 github.com/gophercloud/gophercloud v0.5.0 // indirect github.com/hekmon/cunits v2.0.1+incompatible // indirect github.com/hekmon/transmissionrpc v0.0.0-20190525133028-1d589625bacd github.com/imdario/mergo v0.3.8 // indirect + github.com/jedib0t/go-pretty v4.3.0+incompatible github.com/jessevdk/go-flags v1.4.0 github.com/lib/pq v1.2.0 // indirect github.com/logrusorgru/aurora v0.0.0-20190803045625-94edacc10f9b diff --git a/go.sum b/go.sum index a1f8e60d..6f083925 100644 --- a/go.sum +++ b/go.sum @@ -106,6 +106,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.19.11 h1:tqaTGER6Byw3QvsjGW0p018U2UOqaJPeJuzoaF7jjoQ= github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -229,10 +231,15 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/strfmt v0.19.6 h1:epWc+q5qSgsy7A7+/HYyxLF37vLEYdPSkNB9G8mRqjw= +github.com/go-openapi/strfmt v0.19.6/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= @@ -388,6 +395,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itsjamie/gin-cors v0.0.0-20160420130702-97b4a9da7933/go.mod h1:AYdLvrSBFloDBNt7Y8xkQ6gmhCODGl8CPikjyIOnNzA= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo= +github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= @@ -655,6 +664,7 @@ github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8 h1:l6epF6yBwuejBfhG github.com/streadway/amqp v0.0.0-20180528204448-e5adc2ada8b8/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -667,6 +677,8 @@ github.com/studio-b12/gowebdav v0.0.0-20200303150724-9380631c29a1/go.mod h1:gCcf github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -711,6 +723,8 @@ github.com/zorkian/go-datadog-api v2.29.0+incompatible/go.mod h1:PkXwHX9CUQa/FpB go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= diff --git a/modules/finnhub/settings.go b/modules/finnhub/settings.go index 80b258fe..289f895c 100644 --- a/modules/finnhub/settings.go +++ b/modules/finnhub/settings.go @@ -1,21 +1,21 @@ package finnhub import ( + "os" + "github.com/olebedev/config" "github.com/wtfutil/wtf/cfg" "github.com/wtfutil/wtf/utils" - "os" ) const ( defaultFocusable = true - defaultTitle = "Finnhub Stock Price" + defaultTitle = "📈 Stocks Price" ) // Settings defines the configuration properties for this module type Settings struct { - common *cfg.Common - + common *cfg.Common apiKey string `help:"Your finnhub API token."` symbols []string `help:"An array of stocks symbols (i.e. AAPL, MSFT)"` } diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go index 378d11d3..df457fe5 100644 --- a/modules/finnhub/widget.go +++ b/modules/finnhub/widget.go @@ -3,6 +3,7 @@ package finnhub import ( "fmt" + "github.com/jedib0t/go-pretty/table" "github.com/rivo/tview" "github.com/wtfutil/wtf/view" ) @@ -43,25 +44,20 @@ func (widget *Widget) content() (string, string, bool) { quotes, err := widget.Client.Getquote() title := widget.CommonSettings().Title - var str string + t := table.NewWriter() + t.AppendHeader(table.Row{"#", "Stock", "Current Price", "Open Price", "Change"}) wrap := false if err != nil { wrap = true - str = err.Error() } else { for idx, q := range quotes { - if idx > 10 { - break - } - - str += fmt.Sprintf( - "[%d]: %s %.2f\n", - idx, - q.Stock, - q.C, - ) + t.AppendRows([]table.Row{ + {idx, q.Stock, q.C, q.O, fmt.Sprintf("%.4f", (q.C-q.O)/q.C)}, + }) } } + str := fmt.Sprintf(t.Render()) + return title, str, wrap } From fd8298dfd1f6b099bd4c8e25d5ccb39ba6b15e7a Mon Sep 17 00:00:00 2001 From: Jade Date: Mon, 19 Oct 2020 20:59:26 +0100 Subject: [PATCH 8/8] go lint fix --- modules/finnhub/widget.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/finnhub/widget.go b/modules/finnhub/widget.go index df457fe5..e86563bb 100644 --- a/modules/finnhub/widget.go +++ b/modules/finnhub/widget.go @@ -57,7 +57,5 @@ func (widget *Widget) content() (string, string, bool) { } } - str := fmt.Sprintf(t.Render()) - - return title, str, wrap + return title, t.Render(), wrap }