Merge branch 'master' into table-alignment

pull/118/head
Alexis Hildebrandt 3 years ago
commit cae7d520f0

@ -0,0 +1,8 @@
**
!go.*
!*.go
!assets
!cmd
!cointop
!pkg
!vendor

@ -4,14 +4,15 @@ RUN mkdir /app
WORKDIR /app
ARG VERSION
ADD . /app/
COPY . ./
RUN go build -ldflags=-s -ldflags=-w -ldflags=-X=github.com/miguelmota/cointop/cointop.version=$VERSION -o main .
RUN git clone https://github.com/cointop-sh/colors && rm -Rf colors/.git*
ADD https://github.com/cointop-sh/colors/archive/master.tar.gz ./
RUN tar zxf master.tar.gz --exclude images
FROM busybox:glibc
RUN mkdir -p /etc/ssl
COPY --from=build /etc/ssl/certs/ /etc/ssl/certs
COPY --from=build /app/main /bin/cointop
COPY --from=build /app/colors /root/.config/cointop/colors
ENTRYPOINT cointop
COPY --from=build /app/colors-master /root/.config/cointop/colors
ENTRYPOINT ["/bin/cointop"]
CMD []

@ -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)
@ -251,7 +251,8 @@ func (ct *Cointop) UpdatePriceAlertsUpdateMenu(isNew bool, coin *Coin) error {
if ok {
coin.Name = entry.CoinName
currentPrice = strconv.FormatFloat(coin.Price, 'f', -1, 64)
value = fmt.Sprintf("%s %v", entry.Operator, entry.TargetPrice)
targetPrice := strconv.FormatFloat(entry.TargetPrice, 'f', -1, 64)
value = fmt.Sprintf("%s %v", entry.Operator, targetPrice)
ct.State.priceAlertEditID = entry.ID
isEdit = true
}

@ -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
}
// e.g. Numericf(834142.32, 2) -> "834,142.32"
func Numericf(value float64, precision int) string {
return f(value, precision, "LC_NUMERIC", true)
}
comma := []byte{','}
// 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)
}
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)
// 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
}
}
}
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])
envlang, ok := os.LookupEnv(envvar)
if !ok {
envlang = "en"
}
return buf.String()
}
// Commaf2 ...
func Commaf2(v float64) string {
p := message.NewPrinter(language.English)
return p.Sprintf("%.2f", v)
}
lang := language.Make(envlang)
// Commaf0 ...
func Commaf0(v float64) string {
p := message.NewPrinter(language.English)
return p.Sprintf("%.0f", v)
format := fmt.Sprintf("%%.%df", precision)
return message.NewPrinter(lang).Sprintf(format, value)
}

@ -22,6 +22,22 @@ func UserPreferredConfigDir() string {
return config
}
// UserPreferredCacheDir returns the preferred cache directory for the user
func UserPreferredCacheDir() string {
defaultCacheDir := "/tmp"
cache, err := os.UserCacheDir()
if err != nil {
return defaultCacheDir
}
if cache == "" {
return defaultCacheDir
}
return cache
}
// UserPreferredHomeDir returns the preferred home directory for the user
func UserPreferredHomeDir() string {
home, err := os.UserHomeDir()
@ -36,6 +52,7 @@ func UserPreferredHomeDir() string {
func NormalizePath(path string) string {
userHome := UserPreferredHomeDir()
userConfigHome := UserPreferredConfigDir()
userCacheHome := UserPreferredCacheDir()
// expand tilde
if strings.HasPrefix(path, "~/") {
@ -44,6 +61,7 @@ func NormalizePath(path string) string {
path = strings.Replace(path, ":HOME:", userHome, -1)
path = strings.Replace(path, ":PREFERRED_CONFIG_HOME:", userConfigHome, -1)
path = strings.Replace(path, ":PREFERRED_CACHE_HOME:", userCacheHome, -1)
path = strings.Replace(path, "/", string(filepath.Separator), -1)
return filepath.Clean(path)

Loading…
Cancel
Save