mirror of
https://github.com/miguelmota/cointop
synced 2024-11-05 00:00:14 +00:00
Merge branch 'afh-numeric-monetary-locale'
This commit is contained in:
commit
17fd13f150
@ -120,7 +120,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
Text: symbol,
|
||||
})
|
||||
case "price":
|
||||
text := humanize.Commaf(coin.Price)
|
||||
text := humanize.Monetaryf(coin.Price, 2)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -132,7 +132,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
Text: text,
|
||||
})
|
||||
case "24h_volume":
|
||||
text := humanize.Commaf(coin.Volume24H)
|
||||
text := humanize.Monetaryf(coin.Volume24H, 0)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -151,7 +151,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
if coin.PercentChange1H < 0 {
|
||||
color1h = ct.colorscheme.TableColumnChangeDown
|
||||
}
|
||||
text := fmt.Sprintf("%.2f%%", coin.PercentChange1H)
|
||||
text := fmt.Sprintf("%v%%", humanize.Numericf(coin.PercentChange1H, 2))
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -170,7 +170,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
if coin.PercentChange24H < 0 {
|
||||
color24h = ct.colorscheme.TableColumnChangeDown
|
||||
}
|
||||
text := fmt.Sprintf("%.2f%%", coin.PercentChange24H)
|
||||
text := fmt.Sprintf("%v%%", humanize.Numericf(coin.PercentChange24H, 2))
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -189,7 +189,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
if coin.PercentChange7D < 0 {
|
||||
color7d = ct.colorscheme.TableColumnChangeDown
|
||||
}
|
||||
text := fmt.Sprintf("%.2f%%", coin.PercentChange7D)
|
||||
text := fmt.Sprintf("%v%%", humanize.Numericf(coin.PercentChange7D, 2))
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -208,7 +208,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
if coin.PercentChange30D < 0 {
|
||||
color30d = ct.colorscheme.TableColumnChangeDown
|
||||
}
|
||||
text := fmt.Sprintf("%.2f%%", coin.PercentChange30D)
|
||||
text := fmt.Sprintf("%v%%", humanize.Numericf(coin.PercentChange30D, 2))
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -220,7 +220,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
Text: text,
|
||||
})
|
||||
case "market_cap":
|
||||
text := humanize.Commaf(coin.MarketCap)
|
||||
text := humanize.Monetaryf(coin.MarketCap, 0)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -232,7 +232,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
Text: text,
|
||||
})
|
||||
case "total_supply":
|
||||
text := humanize.Commaf(coin.TotalSupply)
|
||||
text := humanize.Numericf(coin.TotalSupply, 0)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
@ -244,7 +244,7 @@ func (ct *Cointop) GetCoinsTable() *table.Table {
|
||||
Text: text,
|
||||
})
|
||||
case "available_supply":
|
||||
text := humanize.Commaf(coin.AvailableSupply)
|
||||
text := humanize.Numericf(coin.AvailableSupply, 0)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells,
|
||||
|
@ -35,10 +35,10 @@ func (ct *Cointop) UpdateMarketbar() error {
|
||||
if ct.IsPortfolioVisible() {
|
||||
ct.State.marketBarHeight = 1
|
||||
total := ct.GetPortfolioTotal()
|
||||
totalstr := humanize.Commaf(total)
|
||||
totalstr := humanize.Monetaryf(total, 2)
|
||||
if !(ct.State.currencyConversion == "BTC" || ct.State.currencyConversion == "ETH" || total < 1) {
|
||||
total = math.Round(total*1e2) / 1e2
|
||||
totalstr = humanize.Commaf2(total)
|
||||
totalstr = humanize.Monetaryf(total, 2)
|
||||
}
|
||||
|
||||
timeframe := ct.State.selectedChartRange
|
||||
@ -149,9 +149,9 @@ func (ct *Cointop) UpdateMarketbar() error {
|
||||
content = fmt.Sprintf(
|
||||
"%sGlobal ▶ Market Cap: %s %s 24H Volume: %s %s BTC Dominance: %.2f%%",
|
||||
chartInfo,
|
||||
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Commaf0(market.TotalMarketCapUSD)),
|
||||
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Monetaryf(market.TotalMarketCapUSD, 0)),
|
||||
separator1,
|
||||
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Commaf0(market.Total24HVolumeUSD)),
|
||||
fmt.Sprintf("%s%s", ct.CurrencySymbol(), humanize.Monetaryf(market.Total24HVolumeUSD, 0)),
|
||||
separator2,
|
||||
market.BitcoinPercentageOfMarketCap,
|
||||
)
|
||||
|
@ -125,7 +125,7 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
|
||||
Text: symbol,
|
||||
})
|
||||
case "price":
|
||||
text := humanize.Commaf(coin.Price)
|
||||
text := humanize.Monetaryf(coin.Price, 2)
|
||||
symbolPadding := 1
|
||||
ct.SetTableColumnWidth(header, utf8.RuneCountInString(text)+symbolPadding)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
@ -150,7 +150,7 @@ func (ct *Cointop) GetPortfolioTable() *table.Table {
|
||||
Text: text,
|
||||
})
|
||||
case "balance":
|
||||
text := humanize.Commaf(coin.Balance)
|
||||
text := humanize.Monetaryf(coin.Balance, 2)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
colorBalance := ct.colorscheme.TableColumnPrice
|
||||
@ -715,31 +715,31 @@ func (ct *Cointop) PrintHoldingsTable(options *TablePrintOptions) error {
|
||||
item[i] = entry.Symbol
|
||||
case "price":
|
||||
if humanReadable {
|
||||
item[i] = fmt.Sprintf("%s%s", symbol, humanize.Commaf(entry.Price))
|
||||
item[i] = fmt.Sprintf("%s%s", symbol, humanize.Monetaryf(entry.Price, 2))
|
||||
} else {
|
||||
item[i] = strconv.FormatFloat(entry.Price, 'f', -1, 64)
|
||||
}
|
||||
case "holdings":
|
||||
if humanReadable {
|
||||
item[i] = humanize.Commaf(entry.Holdings)
|
||||
item[i] = humanize.Monetaryf(entry.Holdings, 2)
|
||||
} else {
|
||||
item[i] = strconv.FormatFloat(entry.Holdings, 'f', -1, 64)
|
||||
}
|
||||
case "balance":
|
||||
if humanReadable {
|
||||
item[i] = fmt.Sprintf("%s%s", symbol, humanize.Commaf(entry.Balance))
|
||||
item[i] = fmt.Sprintf("%s%s", symbol, humanize.Monetaryf(entry.Balance, 2))
|
||||
} else {
|
||||
item[i] = strconv.FormatFloat(entry.Balance, 'f', -1, 64)
|
||||
}
|
||||
case "24h%":
|
||||
if humanReadable {
|
||||
item[i] = fmt.Sprintf("%.2f%%", entry.PercentChange24H)
|
||||
item[i] = fmt.Sprintf("%s%%", humanize.Numericf(entry.PercentChange24H, 2))
|
||||
} else {
|
||||
item[i] = fmt.Sprintf("%.2f", entry.PercentChange24H)
|
||||
}
|
||||
case "%holdings":
|
||||
if humanReadable {
|
||||
item[i] = fmt.Sprintf("%.2f%%", percentHoldings)
|
||||
item[i] = fmt.Sprintf("%s%%", humanize.Numericf(percentHoldings, 2))
|
||||
} else {
|
||||
item[i] = fmt.Sprintf("%.2f", percentHoldings)
|
||||
}
|
||||
@ -852,7 +852,7 @@ func (ct *Cointop) PrintTotalHoldings(options *TablePrintOptions) error {
|
||||
value := strconv.FormatFloat(total, 'f', -1, 64)
|
||||
|
||||
if humanReadable {
|
||||
value = fmt.Sprintf("%s%s", symbol, humanize.Commaf(total))
|
||||
value = fmt.Sprintf("%s%s", symbol, humanize.Monetaryf(total, 2))
|
||||
}
|
||||
|
||||
if format == "csv" {
|
||||
|
@ -69,7 +69,7 @@ func GetCoinPrices(config *PricesConfig) ([]string, error) {
|
||||
}
|
||||
|
||||
symbol := CurrencySymbol(config.Currency)
|
||||
value := fmt.Sprintf("%s%s", symbol, humanize.Commaf(price))
|
||||
value := fmt.Sprintf("%s%s", symbol, humanize.Monetaryf(price, 2))
|
||||
prices = append(prices, value)
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ func (ct *Cointop) GetPriceAlertsTable() *table.Table {
|
||||
})
|
||||
|
||||
case "target_price":
|
||||
targetPrice := fmt.Sprintf("%s %s", entry.Operator, humanize.Commaf(entry.TargetPrice))
|
||||
targetPrice := fmt.Sprintf("%s %s", entry.Operator, humanize.Monetaryf(entry.TargetPrice, 2))
|
||||
ct.SetTableColumnWidthFromString(header, targetPrice)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells, &table.RowCell{
|
||||
@ -107,7 +107,7 @@ func (ct *Cointop) GetPriceAlertsTable() *table.Table {
|
||||
Text: targetPrice,
|
||||
})
|
||||
case "price":
|
||||
text := humanize.Commaf(coin.Price)
|
||||
text := humanize.Monetaryf(coin.Price, 2)
|
||||
ct.SetTableColumnWidthFromString(header, text)
|
||||
ct.SetTableColumnAlignLeft(header, false)
|
||||
rowCells = append(rowCells, &table.RowCell{
|
||||
@ -187,7 +187,7 @@ func (ct *Cointop) CheckPriceAlert(alert *PriceAlert) error {
|
||||
}
|
||||
var msg string
|
||||
title := "Cointop Alert"
|
||||
priceStr := fmt.Sprintf("%s%s (%s%s)", ct.CurrencySymbol(), humanize.Commaf(alert.TargetPrice), ct.CurrencySymbol(), humanize.Commaf(coin.Price))
|
||||
priceStr := fmt.Sprintf("%s%s (%s%s)", ct.CurrencySymbol(), humanize.Numericf(alert.TargetPrice, 2), ct.CurrencySymbol(), humanize.Monetaryf(coin.Price, 2))
|
||||
if alert.Operator == ">" {
|
||||
if coin.Price > alert.TargetPrice {
|
||||
msg = fmt.Sprintf("%s price is greater than %v", alert.CoinName, priceStr)
|
||||
|
@ -1,7 +1,8 @@
|
||||
package humanize
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -9,47 +10,44 @@ import (
|
||||
"golang.org/x/text/message"
|
||||
)
|
||||
|
||||
// Commaf produces a string form of the given number in base 10 with
|
||||
// commas after every three orders of magnitude.
|
||||
// Numericf produces a string from of the given number with give fixed precision
|
||||
// in base 10 with thousands separators after every three orders of magnitude
|
||||
// using a thousands and decimal spearator according to LC_NUMERIC; defaulting "en".
|
||||
//
|
||||
// e.g. Commaf(834142.32) -> 834,142.32
|
||||
func Commaf(v float64) string {
|
||||
buf := &bytes.Buffer{}
|
||||
if v < 0 {
|
||||
buf.Write([]byte{'-'})
|
||||
v = 0 - v
|
||||
}
|
||||
|
||||
comma := []byte{','}
|
||||
|
||||
parts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), ".")
|
||||
pos := 0
|
||||
if len(parts[0])%3 != 0 {
|
||||
pos += len(parts[0]) % 3
|
||||
buf.WriteString(parts[0][:pos])
|
||||
buf.Write(comma)
|
||||
}
|
||||
for ; pos < len(parts[0]); pos += 3 {
|
||||
buf.WriteString(parts[0][pos : pos+3])
|
||||
buf.Write(comma)
|
||||
}
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
|
||||
if len(parts) > 1 {
|
||||
buf.Write([]byte{'.'})
|
||||
buf.WriteString(parts[1])
|
||||
}
|
||||
return buf.String()
|
||||
// e.g. Numericf(834142.32, 2) -> "834,142.32"
|
||||
func Numericf(value float64, precision int) string {
|
||||
return f(value, precision, "LC_NUMERIC", true)
|
||||
}
|
||||
|
||||
// Commaf2 ...
|
||||
func Commaf2(v float64) string {
|
||||
p := message.NewPrinter(language.English)
|
||||
return p.Sprintf("%.2f", v)
|
||||
// Monetaryf produces a string from of the given number give minimum precision
|
||||
// in base 10 with thousands separators after every three orders of magnitude
|
||||
// using thousands and decimal spearator according to LC_MONETARY; defaulting "en".
|
||||
//
|
||||
// e.g. Monetaryf(834142.3256, 2) -> "834,142.3256"
|
||||
func Monetaryf(value float64, precision int) string {
|
||||
return f(value, precision, "LC_MONETARY", false)
|
||||
}
|
||||
|
||||
// Commaf0 ...
|
||||
func Commaf0(v float64) string {
|
||||
p := message.NewPrinter(language.English)
|
||||
return p.Sprintf("%.0f", v)
|
||||
// f formats given value v, with d decimal places using thousands and decimal
|
||||
// separator according to language found in given locale environment variable e.
|
||||
// If r is true the decimal places are fixed to the given d otherwise d is the
|
||||
// minimum of decimal places until the first 0.
|
||||
func f(value float64, precision int, envvar string, fixed bool) string {
|
||||
parts := strings.Split(strconv.FormatFloat(value, 'f', -1, 64), ".")
|
||||
if !fixed && len(parts) > 1 {
|
||||
for ; precision < len(parts[1]); precision += 1 {
|
||||
if parts[1][precision] == '0' {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
envlang, ok := os.LookupEnv(envvar)
|
||||
if !ok {
|
||||
envlang = "en"
|
||||
}
|
||||
lang := language.Make(envlang)
|
||||
|
||||
format := fmt.Sprintf("%%.%df", precision)
|
||||
return message.NewPrinter(lang).Sprintf(format, value)
|
||||
}
|
||||
|
@ -3,35 +3,39 @@ package align
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// AlignLeft align left
|
||||
func AlignLeft(s string, n int) string {
|
||||
if len(s) > n {
|
||||
slen := utf8.RuneCountInString(s)
|
||||
if slen > n {
|
||||
return s[:n]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s", s, strings.Repeat(" ", n-len(s)))
|
||||
return fmt.Sprintf("%s%s", s, strings.Repeat(" ", n-slen))
|
||||
}
|
||||
|
||||
// AlignRight align right
|
||||
func AlignRight(s string, n int) string {
|
||||
if len(s) > n {
|
||||
slen := utf8.RuneCountInString(s)
|
||||
if slen > n {
|
||||
return s[:n]
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s%s", strings.Repeat(" ", n-len(s)), s)
|
||||
return fmt.Sprintf("%s%s", strings.Repeat(" ", n-slen), s)
|
||||
}
|
||||
|
||||
// AlignCenter align center
|
||||
func AlignCenter(s string, n int) string {
|
||||
if len(s) > n {
|
||||
slen := utf8.RuneCountInString(s)
|
||||
if slen > n {
|
||||
return s[:n]
|
||||
}
|
||||
|
||||
pad := (n - len(s)) / 2
|
||||
pad := (n - slen) / 2
|
||||
lpad := pad
|
||||
rpad := n - len(s) - lpad
|
||||
rpad := n - slen - lpad
|
||||
|
||||
return fmt.Sprintf("%s%s%s", strings.Repeat(" ", lpad), s, strings.Repeat(" ", rpad))
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/miguelmota/cointop/pkg/pad"
|
||||
"github.com/miguelmota/cointop/pkg/table/align"
|
||||
@ -129,7 +130,7 @@ func (t *Table) normalizeColWidthPerc() {
|
||||
// Format format table
|
||||
func (t *Table) Format() *Table {
|
||||
for _, c := range t.cols {
|
||||
c.width = len(c.name) + 1
|
||||
c.width = utf8.RuneCountInString(c.name) + 1
|
||||
if c.minWidth > c.width {
|
||||
c.width = c.minWidth
|
||||
}
|
||||
@ -151,8 +152,9 @@ func (t *Table) Format() *Table {
|
||||
r.strValues[j] = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
if len(r.strValues[j]) > t.cols[j].width {
|
||||
t.cols[j].width = len(r.strValues[j])
|
||||
runeCount := utf8.RuneCountInString(r.strValues[j])
|
||||
if runeCount > t.cols[j].width {
|
||||
t.cols[j].width = runeCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user