diff --git a/cointop/cointop.go b/cointop/cointop.go index 35c2238..6af281b 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -99,6 +99,7 @@ type State struct { favoritesCompactNotation bool portfolioCompactNotation bool enableMouse bool + altCoinLink string } // Cointop cointop @@ -199,6 +200,9 @@ var DefaultCompactNotation = false // DefaultEnableMouse ... var DefaultEnableMouse = true +// DefaultAltCoinLink ... +var DefaultAltCoinLink = "" + // DefaultMaxChartWidth ... var DefaultMaxChartWidth = 175 @@ -305,6 +309,7 @@ func NewCointop(config *Config) (*Cointop, error) { }, compactNotation: DefaultCompactNotation, enableMouse: DefaultEnableMouse, + altCoinLink: DefaultAltCoinLink, tableCompactNotation: DefaultCompactNotation, favoritesCompactNotation: DefaultCompactNotation, portfolioCompactNotation: DefaultCompactNotation, diff --git a/cointop/config.go b/cointop/config.go index a2bbb8a..10e42ce 100644 --- a/cointop/config.go +++ b/cointop/config.go @@ -49,12 +49,11 @@ type ConfigFileConfig struct { RefreshRate interface{} `toml:"refresh_rate"` CoinStructHash interface{} `toml:"coin_struct_version"` CacheDir interface{} `toml:"cache_dir"` - - CompactNotation interface{} `toml:"compact_notation"` - EnableMouse interface{} `toml:"enable_mouse"` - - Table map[string]interface{} `toml:"table"` - Chart map[string]interface{} `toml:"chart"` + CompactNotation interface{} `toml:"compact_notation"` + EnableMouse interface{} `toml:"enable_mouse"` + AltCoinLink interface{} `toml:"alt_coin_link"` // TODO: should really be in API-specific section + Table map[string]interface{} `toml:"table"` + Chart map[string]interface{} `toml:"chart"` } // SetupConfig loads config file @@ -77,6 +76,7 @@ func (ct *Cointop) SetupConfig() error { ct.loadCacheDirFromConfig, ct.loadCompactNotationFromConfig, ct.loadEnableMouseFromConfig, + ct.loadAltCoinLinkFromConfig, ct.loadPriceAlertsFromConfig, ct.loadPortfolioFromConfig, } @@ -301,6 +301,7 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) { CoinStructHash: currentCoinHash, CompactNotation: ct.State.compactNotation, EnableMouse: ct.State.enableMouse, + AltCoinLink: ct.State.altCoinLink, } var b bytes.Buffer @@ -528,6 +529,16 @@ func (ct *Cointop) loadEnableMouseFromConfig() error { return nil } +// loadAltCoinLinkFromConfig loads AltCoinLink setting from config file to struct +func (ct *Cointop) loadAltCoinLinkFromConfig() error { + log.Debug("loadAltCoinLinkFromConfig()") + if altCoinLink, ok := ct.config.AltCoinLink.(string); ok { + ct.State.altCoinLink = altCoinLink + } + + return nil +} + // LoadAPIChoiceFromConfig loads API choices from config file to struct func (ct *Cointop) loadAPIChoiceFromConfig() error { log.Debug("loadAPIKeysFromConfig()") diff --git a/cointop/default_shortcuts.go b/cointop/default_shortcuts.go index e18988d..5c7cc21 100644 --- a/cointop/default_shortcuts.go +++ b/cointop/default_shortcuts.go @@ -20,6 +20,7 @@ func DefaultShortcuts() map[string]string { "ctrl+d": "page_down", "ctrl+f": "open_search", "ctrl+n": "next_page", + "ctrl+o": "open_alt_link", "ctrl+p": "previous_page", "ctrl+r": "refresh", "ctrl+R": "refresh", diff --git a/cointop/keybindings.go b/cointop/keybindings.go index 0c4abc5..c1f1616 100644 --- a/cointop/keybindings.go +++ b/cointop/keybindings.go @@ -132,6 +132,8 @@ func (ct *Cointop) SetKeybindingAction(shortcutKey string, action string) error fn = ct.Keyfn(ct.NavigateLastLine) case "open_link": fn = ct.Keyfn(ct.OpenLink) + case "open_alt_link": + fn = ct.Keyfn(ct.OpenAltLink) case "refresh": fn = ct.Keyfn(ct.Refresh) case "sort_column_asc": diff --git a/cointop/table.go b/cointop/table.go index 225178a..d5a1d86 100644 --- a/cointop/table.go +++ b/cointop/table.go @@ -3,6 +3,7 @@ package cointop import ( "fmt" "net/url" + "strconv" "strings" "github.com/cointop-sh/cointop/pkg/ui" @@ -203,6 +204,17 @@ func (ct *Cointop) RowLink() string { return ct.api.CoinLink(coin.Slug) } +// RowLink returns the row url link +func (ct *Cointop) RowAltLink() string { + log.Debug("RowAltLink()") + coin := ct.HighlightedRowCoin() + if coin == nil { + return "" + } + + return ct.GetAltCoinLink(coin) +} + // RowLinkShort returns a shortened version of the row url link func (ct *Cointop) RowLinkShort() string { log.Debug("RowLinkShort()") @@ -227,6 +239,20 @@ func (ct *Cointop) RowLinkShort() string { return "" } +func (ct *Cointop) GetAltCoinLink(coin *Coin) string { + if ct.State.altCoinLink == "" { + return ct.api.CoinLink(coin.Slug) + } + + url := ct.State.altCoinLink + url = strings.Replace(url, "{{ID}}", coin.ID, -1) + url = strings.Replace(url, "{{NAME}}", coin.Name, -1) + url = strings.Replace(url, "{{RANK}}", strconv.Itoa(coin.Rank), -1) + url = strings.Replace(url, "{{SLUG}}", coin.Slug, -1) + url = strings.Replace(url, "{{SYMBOL}}", coin.Symbol, -1) + return url +} + // ToggleTableFullscreen toggles the table fullscreen mode func (ct *Cointop) ToggleTableFullscreen() error { log.Debug("ToggleTableFullscreen()") diff --git a/cointop/util.go b/cointop/util.go index 81cd714..5031cad 100644 --- a/cointop/util.go +++ b/cointop/util.go @@ -20,6 +20,13 @@ func (ct *Cointop) OpenLink() error { return nil } +// OpenLink opens the alternate url in a browser +func (ct *Cointop) OpenAltLink() error { + log.Debug("OpenAltLink()") + open.URL(ct.RowAltLink()) + return nil +} + // GetBytes returns the interface in bytes form func GetBytes(key interface{}) ([]byte, error) { var buf bytes.Buffer diff --git a/pkg/eval/eval.go b/pkg/eval/eval.go index be9f205..810cece 100644 --- a/pkg/eval/eval.go +++ b/pkg/eval/eval.go @@ -43,3 +43,23 @@ func EvaluateExpressionToFloat64(input string, env interface{}) (float64, error) } return f64, nil } + +func EvaluateExpressionToString(input string, env interface{}) (string, error) { + input = strings.TrimSpace(input) + if input == "" { + return "", nil + } + program, err := expr.Compile(input, expr.Env(env)) + if err != nil { + return "", err + } + result, err := expr.Run(program, env) + if err != nil { + return "", err + } + s, ok := result.(string) + if !ok { + return "", errors.New("expression did not return string type") + } + return s, nil +}