build script

pull/5/head
Miguel Mota 6 years ago
parent 7da09bc644
commit 6f3f3dd824

12
Gopkg.lock generated

@ -65,7 +65,7 @@
branch = "master" branch = "master"
name = "github.com/miguelmota/go-coinmarketcap" name = "github.com/miguelmota/go-coinmarketcap"
packages = ["."] packages = ["."]
revision = "05fd2d0c45f763462f90e630da2ddc0392d2cdd3" revision = "9c6b4c2a42d7189f8778825da9640c3efda17d7e"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -79,12 +79,6 @@
packages = ["."] packages = ["."]
revision = "e2050e41c8847748ec5288741c0b19a8cb26d084" revision = "e2050e41c8847748ec5288741c0b19a8cb26d084"
[[projects]]
branch = "master"
name = "github.com/willf/pad"
packages = ["."]
revision = "b3d7806010228b1a954b4d9c4ee4cf6cb476b063"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "go4.org" name = "go4.org"
@ -98,7 +92,7 @@
"html", "html",
"html/atom" "html/atom"
] ]
revision = "6078986fec03a1dcc236c34816c71b0e05018fda" revision = "b68f30494add4df6bd8ef5e82803f308e7f7c59c"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -109,6 +103,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "ff54fa52bac3cde3f10f5c237dad28da497594584e4291356b5efd040501fe4e" inputs-digest = "cc43de082ffa9bbc96488c9bfc6659269a914a24c4ff2a04e1d43bfc66a992a4"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

@ -49,10 +49,6 @@
branch = "master" branch = "master"
name = "github.com/miguelmota/go-coinmarketcap" name = "github.com/miguelmota/go-coinmarketcap"
[[constraint]]
branch = "master"
name = "github.com/willf/pad"
[prune] [prune]
go-tests = true go-tests = true
unused-packages = true unused-packages = true

@ -2,7 +2,10 @@ all:
@echo "no default" @echo "no default"
run: run:
go run cointop.go keybindings.go navigation.go sort.go go run cointop.go keybindings.go navigation.go sort.go layout.go status.go chart.go table.go
build: build: clean
go build go build -ldflags "-s -w" -o bin/cointop && upx bin/cointop
clean:
go clean && rm -f bin/cointop

@ -14,6 +14,11 @@ Make sure to have [golang](https://golang.org/) installed, then do:
go install github.com/miguelmota/cointop go install github.com/miguelmota/cointop
``` ```
### Alternatively
```
```
## Usage ## Usage
```bash ```bash

Binary file not shown.

@ -0,0 +1,84 @@
package main
import (
"fmt"
"log"
"time"
"github.com/gizak/termui"
)
func (ct *Cointop) updateChart() error {
maxX, _ := ct.g.Size()
if len(ct.chartpoints) == 0 {
ct.chartPoints(maxX, "bitcoin")
}
for i := range ct.chartpoints {
var s string
for j := range ct.chartpoints[i] {
p := ct.chartpoints[i][j]
s = fmt.Sprintf("%s%c", s, p.Ch)
}
fmt.Fprintln(ct.chartview, s)
}
return nil
}
func (ct *Cointop) chartPoints(maxX int, coin string) error {
chart := termui.NewLineChart()
chart.Height = 10
chart.AxesColor = termui.ColorWhite
chart.LineColor = termui.ColorCyan
chart.Border = false
now := time.Now()
secs := now.Unix()
start := secs - oneDay
end := secs
_ = coin
//graphData, err := cmc.GetCoinGraphData(coin, start, end)
graphData, err := ct.api.GetGlobalMarketGraphData(start, end)
if err != nil {
log.Fatal(err)
return nil
}
var data []float64
/*
for i := range graphData.PriceUSD {
data = append(data, graphData.PriceUSD[i][1])
}
*/
for i := range graphData.MarketCapByAvailableSupply {
data = append(data, graphData.MarketCapByAvailableSupply[i][1])
}
chart.Data = data
termui.Body = termui.NewGrid()
termui.Body.Width = maxX
termui.Body.AddRows(
termui.NewRow(
termui.NewCol(12, 0, chart),
),
)
var points [][]termui.Cell
// calculate layout
termui.Body.Align()
w := termui.Body.Width
h := 10
row := termui.Body.Rows[0]
b := row.Buffer()
for i := 0; i < h; i = i + 1 {
var rowpoints []termui.Cell
for j := 0; j < w; j = j + 1 {
p := b.At(j, i)
rowpoints = append(rowpoints, p)
}
points = append(points, rowpoints)
}
ct.chartpoints = points
return nil
}

@ -3,19 +3,13 @@ package main
import ( import (
"fmt" "fmt"
"log" "log"
"os/exec"
"strconv"
"strings"
"time"
humanize "github.com/dustin/go-humanize"
"github.com/gizak/termui" "github.com/gizak/termui"
"github.com/jroimartin/gocui" "github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/apis" "github.com/miguelmota/cointop/pkg/api"
apitypes "github.com/miguelmota/cointop/apis/types" apitypes "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/color" "github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pad" "github.com/miguelmota/cointop/pkg/table"
"github.com/miguelmota/cointop/table"
) )
var ( var (
@ -30,6 +24,7 @@ var (
// Cointop cointop // Cointop cointop
type Cointop struct { type Cointop struct {
g *gocui.Gui g *gocui.Gui
marketview *gocui.View
chartview *gocui.View chartview *gocui.View
chartpoints [][]termui.Cell chartpoints [][]termui.Cell
headersview *gocui.View headersview *gocui.View
@ -38,81 +33,10 @@ type Cointop struct {
statusview *gocui.View statusview *gocui.View
sortdesc bool sortdesc bool
currentsort string currentsort string
api apis.Interface api api.Interface
coins []*apitypes.Coin coins []*apitypes.Coin
} }
func (ct *Cointop) layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
chartHeight := 10
if v, err := g.SetView("chart", 0, 0, maxX, chartHeight); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.chartview = v
ct.chartview.Frame = false
ct.updateChart()
}
if v, err := g.SetView("header", 0, chartHeight, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
t := table.New().SetWidth(maxX)
headers := []string{
pad.Right("[r]ank", 13, " "),
pad.Right("[n]ame", 13, " "),
pad.Right("[s]ymbol", 8, " "),
pad.Left("[p]rice", 10, " "),
pad.Left("[m]arket cap", 17, " "),
pad.Left("24H [v]olume", 15, " "),
pad.Left("[1]H%", 9, " "),
pad.Left("[2]4H%", 9, " "),
pad.Left("[7]D%", 9, " "),
pad.Left("[t]otal supply", 20, " "),
pad.Left("[a]vailable supply", 19, " "),
pad.Left("[l]ast updated", 17, " "),
}
for _, h := range headers {
t.AddCol(h)
}
t.Format().Fprint(v)
ct.headersview = v
ct.headersview.Frame = false
ct.headersview.Highlight = true
ct.headersview.SelBgColor = gocui.ColorGreen
ct.headersview.SelFgColor = gocui.ColorBlack
}
if v, err := g.SetView("table", 0, chartHeight+1, maxX, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.tableview = v
ct.tableview.Frame = false
ct.tableview.Highlight = true
ct.tableview.SelBgColor = gocui.ColorCyan
ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateTable()
ct.rowChanged()
}
if v, err := g.SetView("status", 0, maxY-2, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.statusview = v
ct.statusview.Frame = false
ct.statusview.Highlight = true
ct.statusview.SelBgColor = gocui.ColorCyan
ct.statusview.SelFgColor = gocui.ColorBlack
ct.updateStatus("")
}
return nil
}
func (ct *Cointop) rowChanged() { func (ct *Cointop) rowChanged() {
ct.showLink() ct.showLink()
} }
@ -133,188 +57,13 @@ func (ct *Cointop) fetchData() ([]*apitypes.Coin, error) {
return result, nil return result, nil
} }
func (ct *Cointop) chartPoints(maxX int, coin string) error { func (ct *Cointop) updateMarket() error {
chart := termui.NewLineChart()
chart.Height = 10
chart.AxesColor = termui.ColorWhite
chart.LineColor = termui.ColorCyan
chart.Border = false
now := time.Now()
secs := now.Unix()
start := secs - oneDay
end := secs
_ = coin
//graphData, err := cmc.GetCoinGraphData(coin, start, end)
graphData, err := ct.api.GetGlobalMarketGraphData(start, end)
if err != nil {
log.Fatal(err)
return nil
}
var data []float64
/*
for i := range graphData.PriceUSD {
data = append(data, graphData.PriceUSD[i][1])
}
*/
for i := range graphData.MarketCapByAvailableSupply {
data = append(data, graphData.MarketCapByAvailableSupply[i][1])
}
chart.Data = data
termui.Body = termui.NewGrid()
termui.Body.Width = maxX
termui.Body.AddRows(
termui.NewRow(
termui.NewCol(12, 0, chart),
),
)
var points [][]termui.Cell
// calculate layout
termui.Body.Align()
w := termui.Body.Width
h := 10
row := termui.Body.Rows[0]
b := row.Buffer()
for i := 0; i < h; i = i + 1 {
var rowpoints []termui.Cell
for j := 0; j < w; j = j + 1 {
p := b.At(j, i)
rowpoints = append(rowpoints, p)
}
points = append(points, rowpoints)
}
ct.chartpoints = points
return nil
}
func (ct *Cointop) updateChart() error {
maxX, _ := ct.g.Size() maxX, _ := ct.g.Size()
if len(ct.chartpoints) == 0 { s := "barfoo"
ct.chartPoints(maxX, "bitcoin") fmt.Fprintln(ct.marketview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
}
for i := range ct.chartpoints {
var s string
for j := range ct.chartpoints[i] {
p := ct.chartpoints[i][j]
s = fmt.Sprintf("%s%c", s, p.Ch)
}
fmt.Fprintln(ct.chartview, s)
}
return nil return nil
} }
func (ct *Cointop) updateTable() error {
maxX, _ := ct.g.Size()
ct.table = table.New().SetWidth(maxX)
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.HideColumHeaders = true
var err error
if len(ct.coins) == 0 {
ct.coins, err = ct.fetchData()
if err != nil {
return err
}
}
for _, coin := range ct.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
colorprice := color.Cyan
color1h := color.White
color24h := color.White
color7d := color.White
if coin.PercentChange1H > 0 {
color1h = color.Green
}
if coin.PercentChange1H < 0 {
color1h = color.Red
}
if coin.PercentChange24H > 0 {
color24h = color.Green
}
if coin.PercentChange24H < 0 {
color24h = color.Red
}
if coin.PercentChange7D > 0 {
color7d = color.Green
}
if coin.PercentChange7D < 0 {
color7d = color.Red
}
ct.table.AddRow(
pad.Left(fmt.Sprint(coin.Rank), 4, " "),
pad.Right(coin.Name, 22, " "),
pad.Right(coin.Symbol, 6, " "),
colorprice(pad.Left(humanize.Commaf(coin.PriceUSD), 12, " ")),
pad.Left(humanize.Commaf(coin.MarketCapUSD), 17, " "),
pad.Left(humanize.Commaf(coin.USD24HVolume), 15, " "),
color1h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange1H), 9, " ")),
color24h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange24H), 9, " ")),
color7d(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange7D), 9, " ")),
pad.Left(humanize.Commaf(coin.TotalSupply), 20, " "),
pad.Left(humanize.Commaf(coin.AvailableSupply), 18, " "),
pad.Left(fmt.Sprintf("%s", lastUpdated), 18, " "),
// add %percent of cap
)
}
ct.table.Format().Fprint(ct.tableview)
return nil
}
func (ct *Cointop) updateStatus(s string) {
maxX, _ := ct.g.Size()
ct.statusview.Clear()
fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
}
func (ct *Cointop) showLink() {
url := ct.rowLink()
ct.g.Update(func(g *gocui.Gui) error {
ct.updateStatus(fmt.Sprintf("[enter]=%s", url))
return nil
})
}
func (ct *Cointop) enter(g *gocui.Gui, v *gocui.View) error {
exec.Command("open", ct.rowLink()).Output()
return nil
}
func (ct *Cointop) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
func (ct *Cointop) selectedRowIndex() int {
_, y := ct.tableview.Origin()
_, cy := ct.tableview.Cursor()
return y + cy
}
func (ct *Cointop) selectedCoin() *apitypes.Coin {
return ct.coins[ct.selectedRowIndex()]
}
func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.selectedCoin().Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}
func main() { func main() {
g, err := gocui.NewGui(gocui.Output256) g, err := gocui.NewGui(gocui.Output256)
if err != nil { if err != nil {
@ -324,17 +73,14 @@ func main() {
g.Cursor = true g.Cursor = true
g.Mouse = true g.Mouse = true
g.Highlight = true g.Highlight = true
ct := Cointop{ ct := Cointop{
g: g, g: g,
api: apis.NewCMC(), api: api.NewCMC(),
} }
g.SetManagerFunc(ct.layout) g.SetManagerFunc(ct.layout)
if err := ct.keybindings(g); err != nil { if err := ct.keybindings(g); err != nil {
log.Fatalf("keybindings: %v", err) log.Fatalf("keybindings: %v", err)
} }
if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
log.Fatalf("main loop: %v", err) log.Fatalf("main loop: %v", err)
} }

@ -2,6 +2,7 @@ package main
import ( import (
"log" "log"
"os/exec"
"github.com/jroimartin/gocui" "github.com/jroimartin/gocui"
) )
@ -45,3 +46,12 @@ func (ct *Cointop) keybindings(g *gocui.Gui) error {
ct.setKeybinding(gocui.KeyEsc, ct.quit) ct.setKeybinding(gocui.KeyEsc, ct.quit)
return nil return nil
} }
func (ct *Cointop) enter(g *gocui.Gui, v *gocui.View) error {
exec.Command("open", ct.rowLink()).Output()
return nil
}
func (ct *Cointop) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}

@ -0,0 +1,93 @@
package main
import (
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pkg/table"
)
func (ct *Cointop) layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
chartHeight := 10
topOffset := 0
if v, err := g.SetView("market", 0, topOffset, maxX, 2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.marketview = v
ct.marketview.Frame = false
ct.marketview.BgColor = gocui.ColorBlack
ct.marketview.FgColor = gocui.ColorWhite
ct.updateMarket()
}
topOffset = topOffset + 1
if v, err := g.SetView("chart", 0, topOffset, maxX, topOffset+chartHeight); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.chartview = v
ct.chartview.Frame = false
ct.updateChart()
}
topOffset = topOffset + chartHeight
if v, err := g.SetView("header", 0, topOffset, maxX, topOffset+2); err != nil {
if err != gocui.ErrUnknownView {
return err
}
t := table.New().SetWidth(maxX)
headers := []string{
pad.Right("[r]ank", 13, " "),
pad.Right("[n]ame", 13, " "),
pad.Right("[s]ymbol", 8, " "),
pad.Left("[p]rice", 10, " "),
pad.Left("[m]arket cap", 17, " "),
pad.Left("24H [v]olume", 15, " "),
pad.Left("[1]H%", 9, " "),
pad.Left("[2]4H%", 9, " "),
pad.Left("[7]D%", 9, " "),
pad.Left("[t]otal supply", 20, " "),
pad.Left("[a]vailable supply", 19, " "),
pad.Left("[l]ast updated", 17, " "),
}
for _, h := range headers {
t.AddCol(h)
}
t.Format().Fprint(v)
ct.headersview = v
ct.headersview.Frame = false
ct.headersview.Highlight = true
ct.headersview.SelBgColor = gocui.ColorGreen
ct.headersview.SelFgColor = gocui.ColorBlack
}
topOffset = topOffset + 1
if v, err := g.SetView("table", 0, topOffset, maxX, maxY-1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.tableview = v
ct.tableview.Frame = false
ct.tableview.Highlight = true
ct.tableview.SelBgColor = gocui.ColorCyan
ct.tableview.SelFgColor = gocui.ColorBlack
ct.updateTable()
ct.rowChanged()
}
if v, err := g.SetView("status", 0, maxY-2, maxX, maxY); err != nil {
if err != gocui.ErrUnknownView {
return err
}
ct.statusview = v
ct.statusview.Frame = false
ct.statusview.BgColor = gocui.ColorCyan
ct.statusview.FgColor = gocui.ColorBlack
ct.updateStatus("")
}
return nil
}

@ -1,7 +1,7 @@
package apis package api
import ( import (
cmc "github.com/miguelmota/cointop/apis/cmc" cmc "github.com/miguelmota/cointop/pkg/api/cmc"
) )
// NewCMC new CoinMarketCap api // NewCMC new CoinMarketCap api

@ -1,7 +1,7 @@
package apis package api
import ( import (
types "github.com/miguelmota/cointop/apis/types" types "github.com/miguelmota/cointop/pkg/api/types"
cmc "github.com/miguelmota/go-coinmarketcap" cmc "github.com/miguelmota/go-coinmarketcap"
) )

@ -1,7 +1,7 @@
package apis package api
import ( import (
types "github.com/miguelmota/cointop/apis/types" types "github.com/miguelmota/cointop/pkg/api/types"
) )
// Interface interface // Interface interface

@ -1,4 +1,4 @@
package apis package api
// Coin struct // Coin struct
type Coin struct { type Coin struct {

@ -6,7 +6,7 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/miguelmota/cointop/table/align" "github.com/miguelmota/cointop/pkg/table/align"
) )
// Table table // Table table

@ -0,0 +1,22 @@
package main
import (
"fmt"
"github.com/jroimartin/gocui"
"github.com/miguelmota/cointop/pkg/pad"
)
func (ct *Cointop) updateStatus(s string) {
maxX, _ := ct.g.Size()
ct.statusview.Clear()
fmt.Fprintln(ct.statusview, pad.Right(fmt.Sprintf("[q]uit %s", s), maxX, " "))
}
func (ct *Cointop) showLink() {
url := ct.rowLink()
ct.g.Update(func(g *gocui.Gui) error {
ct.updateStatus(fmt.Sprintf("[↵]%s", url))
return nil
})
}

@ -0,0 +1,98 @@
package main
import (
"fmt"
"strconv"
"strings"
"time"
humanize "github.com/dustin/go-humanize"
apitypes "github.com/miguelmota/cointop/pkg/api/types"
"github.com/miguelmota/cointop/pkg/color"
"github.com/miguelmota/cointop/pkg/pad"
"github.com/miguelmota/cointop/pkg/table"
)
func (ct *Cointop) updateTable() error {
maxX, _ := ct.g.Size()
ct.table = table.New().SetWidth(maxX)
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.AddCol("")
ct.table.HideColumHeaders = true
var err error
if len(ct.coins) == 0 {
ct.coins, err = ct.fetchData()
if err != nil {
return err
}
}
for _, coin := range ct.coins {
unix, _ := strconv.ParseInt(coin.LastUpdated, 10, 64)
lastUpdated := time.Unix(unix, 0).Format("15:04:05 Jan 02")
colorprice := color.Cyan
color1h := color.White
color24h := color.White
color7d := color.White
if coin.PercentChange1H > 0 {
color1h = color.Green
}
if coin.PercentChange1H < 0 {
color1h = color.Red
}
if coin.PercentChange24H > 0 {
color24h = color.Green
}
if coin.PercentChange24H < 0 {
color24h = color.Red
}
if coin.PercentChange7D > 0 {
color7d = color.Green
}
if coin.PercentChange7D < 0 {
color7d = color.Red
}
ct.table.AddRow(
pad.Left(fmt.Sprint(coin.Rank), 4, " "),
pad.Right(coin.Name, 22, " "),
pad.Right(coin.Symbol, 6, " "),
colorprice(pad.Left(humanize.Commaf(coin.PriceUSD), 12, " ")),
pad.Left(humanize.Commaf(coin.MarketCapUSD), 17, " "),
pad.Left(humanize.Commaf(coin.USD24HVolume), 15, " "),
color1h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange1H), 9, " ")),
color24h(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange24H), 9, " ")),
color7d(pad.Left(fmt.Sprintf("%.2f%%", coin.PercentChange7D), 9, " ")),
pad.Left(humanize.Commaf(coin.TotalSupply), 20, " "),
pad.Left(humanize.Commaf(coin.AvailableSupply), 18, " "),
pad.Left(fmt.Sprintf("%s", lastUpdated), 18, " "),
// add %percent of cap
)
}
ct.table.Format().Fprint(ct.tableview)
return nil
}
func (ct *Cointop) selectedRowIndex() int {
_, y := ct.tableview.Origin()
_, cy := ct.tableview.Cursor()
return y + cy
}
func (ct *Cointop) selectedCoin() *apitypes.Coin {
return ct.coins[ct.selectedRowIndex()]
}
func (ct *Cointop) rowLink() string {
slug := strings.ToLower(strings.Replace(ct.selectedCoin().Name, " ", "-", -1))
return fmt.Sprintf("https://coinmarketcap.com/currencies/%s", slug)
}

@ -1,5 +1,17 @@
package coinmarketcap package coinmarketcap
// Interface interface
type Interface interface {
GetGlobalMarketData() (GlobalMarketData, error)
GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error)
GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error)
GetCoinData(coin string) (Coin, error)
GetAllCoinData(limit int) (map[string]Coin, error)
GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error)
GetCoinPriceUSD(coin string) (float64, error)
GetCoinMarkets(coin string) ([]Market, error)
}
// Coin struct // Coin struct
type Coin struct { type Coin struct {
ID string `json:"id"` ID string `json:"id"`

@ -1,24 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

@ -1,2 +0,0 @@
language: go

@ -1,24 +0,0 @@
Copyright (c) 2016 Will Fitzgerald. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,36 +0,0 @@
pad
-------------
[![Join the chat at https://gitter.im/willf/pad](https://badges.gitter.im/willf/pad.svg)](https://gitter.im/willf/pad?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/willf/pad.svg?branch=master)](https://travis-ci.org/willf/pad)
A golang implementation of the [left-pad javascript library](https://www.npmjs.com/package/left-pad)
I was inspired by [Stew](https://twitter.com/StewOConnor)'s [`left-cats`](https://github.com/stew/left-cats), who was inspired by [this article](http://arstechnica.com/information-technology/2016/03/rage-quit-coder-unpublished-17-lines-of-javascript-and-broke-the-internet/), to port this to Go.
This implementation will let you pad byte-strings and UTF-8 encoded strings
example usage:
```go
package main
import (
"fmt"
"github.com/willf/pad"
padUtf8 "github.com/willf/pad/utf8"
)
func main() {
fmt.Println(pad.Right("Hello", 20, "!"))
fmt.Println(padUtf8.Left("Exit now", 20, "→"))
}
```
```bash
> go run example.go
Hello!!!!!!!!!!!!!!!
→→→→→→→→→→→→Exit now
```

@ -1,24 +0,0 @@
/*
Package pad provides left-padding functionality
*/
package pad
func times(str string, n int) (out string) {
for i := 0; i < n; i++ {
out += str
}
return
}
// Left left-pads the string with pad up to len runes
// len may be exceeded if
func Left(str string, length int, pad string) string {
return times(pad, length-len(str)) + str
}
// Right right-pads the string with pad up to len runes
func Right(str string, length int, pad string) string {
return str + times(pad, length-len(str))
}
Loading…
Cancel
Save