mirror of https://github.com/miguelmota/cointop
build script
parent
7da09bc644
commit
6f3f3dd824
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
|
||||
}
|
@ -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 (
|
||||
cmc "github.com/miguelmota/cointop/apis/cmc"
|
||||
cmc "github.com/miguelmota/cointop/pkg/api/cmc"
|
||||
)
|
||||
|
||||
// NewCMC new CoinMarketCap api
|
@ -1,7 +1,7 @@
|
||||
package apis
|
||||
package api
|
||||
|
||||
import (
|
||||
types "github.com/miguelmota/cointop/apis/types"
|
||||
types "github.com/miguelmota/cointop/pkg/api/types"
|
||||
cmc "github.com/miguelmota/go-coinmarketcap"
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package apis
|
||||
package api
|
||||
|
||||
import (
|
||||
types "github.com/miguelmota/cointop/apis/types"
|
||||
types "github.com/miguelmota/cointop/pkg/api/types"
|
||||
)
|
||||
|
||||
// Interface interface
|
@ -1,4 +1,4 @@
|
||||
package apis
|
||||
package api
|
||||
|
||||
// Coin struct
|
||||
type Coin struct {
|
@ -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,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…
Reference in New Issue