mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
49
modules/cryptoexchanges/bittrex/bittrex.go
Normal file
49
modules/cryptoexchanges/bittrex/bittrex.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package bittrex
|
||||
|
||||
type summaryList struct {
|
||||
items []*bCurrency
|
||||
}
|
||||
|
||||
// Base Currency
|
||||
type bCurrency struct {
|
||||
name string
|
||||
displayName string
|
||||
markets []*mCurrency
|
||||
}
|
||||
|
||||
// Market Currency
|
||||
type mCurrency struct {
|
||||
name string
|
||||
summaryInfo
|
||||
}
|
||||
|
||||
type summaryInfo struct {
|
||||
Low string
|
||||
High string
|
||||
Volume string
|
||||
Last string
|
||||
OpenSellOrders string
|
||||
OpenBuyOrders string
|
||||
}
|
||||
|
||||
type summaryResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Result []struct {
|
||||
MarketName string `json:"MarketName"`
|
||||
High float64 `json:"High"`
|
||||
Low float64 `json:"Low"`
|
||||
Last float64 `json:"Last"`
|
||||
Volume float64 `json:"Volume"`
|
||||
OpenSellOrders int `json:"OpenSellOrders"`
|
||||
OpenBuyOrders int `json:"OpenBuyOrders"`
|
||||
} `json:"result"`
|
||||
}
|
||||
|
||||
func (list *summaryList) addSummaryItem(name, displayName string, marketList []*mCurrency) {
|
||||
list.items = append(list.items, &bCurrency{
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
markets: marketList,
|
||||
})
|
||||
}
|
||||
64
modules/cryptoexchanges/bittrex/display.go
Normal file
64
modules/cryptoexchanges/bittrex/display.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package bittrex
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
func (widget *Widget) display() {
|
||||
if ok == false {
|
||||
widget.View.SetText(errorText)
|
||||
return
|
||||
}
|
||||
|
||||
widget.View.SetText(summaryText(&widget.summaryList, &widget.TextColors))
|
||||
}
|
||||
|
||||
func summaryText(list *summaryList, colors *TextColors) string {
|
||||
str := ""
|
||||
|
||||
for _, baseCurrency := range list.items {
|
||||
str += fmt.Sprintf(" [%s]%s[%s] (%s)\n\n", colors.base.displayName, baseCurrency.displayName, colors.base.name, baseCurrency.name)
|
||||
|
||||
resultTemplate := template.New("bittrex")
|
||||
|
||||
for _, marketCurrency := range baseCurrency.markets {
|
||||
writer := new(bytes.Buffer)
|
||||
|
||||
strTemplate, _ := resultTemplate.Parse(
|
||||
" [{{.nameColor}}]{{.mName}}\n" +
|
||||
formatableText("High", "High") +
|
||||
formatableText("Low", "Low") +
|
||||
formatableText("Last", "Last") +
|
||||
formatableText("Volume", "Volume") +
|
||||
"\n" +
|
||||
formatableText("Open Buy", "OpenBuyOrders") +
|
||||
formatableText("Open Sell", "OpenSellOrders"),
|
||||
)
|
||||
|
||||
strTemplate.Execute(writer, map[string]string{
|
||||
"nameColor": colors.market.name,
|
||||
"fieldColor": colors.market.field,
|
||||
"valueColor": colors.market.value,
|
||||
"mName": marketCurrency.name,
|
||||
"High": marketCurrency.High,
|
||||
"Low": marketCurrency.Low,
|
||||
"Last": marketCurrency.Last,
|
||||
"Volume": marketCurrency.Volume,
|
||||
"OpenBuyOrders": marketCurrency.OpenBuyOrders,
|
||||
"OpenSellOrders": marketCurrency.OpenSellOrders,
|
||||
})
|
||||
|
||||
str += writer.String() + "\n"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return str
|
||||
|
||||
}
|
||||
|
||||
func formatableText(key, value string) string {
|
||||
return fmt.Sprintf("[{{.fieldColor}}]%12s: [{{.valueColor}}]{{.%s}}\n", key, value)
|
||||
}
|
||||
169
modules/cryptoexchanges/bittrex/widget.go
Normal file
169
modules/cryptoexchanges/bittrex/widget.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package bittrex
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type TextColors struct {
|
||||
base struct {
|
||||
name string
|
||||
displayName string
|
||||
}
|
||||
market struct {
|
||||
name string
|
||||
field string
|
||||
value string
|
||||
}
|
||||
}
|
||||
|
||||
var ok = true
|
||||
var errorText = ""
|
||||
|
||||
var baseURL = "https://bittrex.com/api/v1.1/public/getmarketsummary"
|
||||
|
||||
// Widget define wtf widget to register widget later
|
||||
type Widget struct {
|
||||
wtf.TextWidget
|
||||
summaryList
|
||||
TextColors
|
||||
}
|
||||
|
||||
// NewWidget Make new instance of widget
|
||||
func NewWidget(app *tview.Application) *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: wtf.NewTextWidget(app, "Bittrex", "bittrex", false),
|
||||
summaryList: summaryList{},
|
||||
}
|
||||
|
||||
ok = true
|
||||
errorText = ""
|
||||
|
||||
widget.config()
|
||||
widget.setSummaryList()
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
func (widget *Widget) config() {
|
||||
widget.TextColors.base.name = wtf.Config.UString("wtf.mods.bittrex.colors.base.name", "red")
|
||||
widget.TextColors.base.displayName = wtf.Config.UString("wtf.mods.bittrex.colors.base.displayName", "grey")
|
||||
widget.TextColors.market.name = wtf.Config.UString("wtf.mods.bittrex.colors.market.name", "red")
|
||||
widget.TextColors.market.field = wtf.Config.UString("wtf.mods.bittrex.colors.market.field", "coral")
|
||||
widget.TextColors.market.value = wtf.Config.UString("wtf.mods.bittrex.colors.market.value", "white")
|
||||
}
|
||||
|
||||
func (widget *Widget) setSummaryList() {
|
||||
sCurrencies, _ := wtf.Config.Map("wtf.mods.bittrex.summary")
|
||||
for baseCurrencyName := range sCurrencies {
|
||||
displayName, _ := wtf.Config.String("wtf.mods.bittrex.summary." + baseCurrencyName + ".displayName")
|
||||
mCurrencyList := makeSummaryMarketList(baseCurrencyName)
|
||||
widget.summaryList.addSummaryItem(baseCurrencyName, displayName, mCurrencyList)
|
||||
}
|
||||
}
|
||||
|
||||
func makeSummaryMarketList(currencyName string) []*mCurrency {
|
||||
mCurrencyList := []*mCurrency{}
|
||||
|
||||
configMarketList, _ := wtf.Config.List("wtf.mods.bittrex.summary." + currencyName + ".market")
|
||||
for _, mCurrencyName := range configMarketList {
|
||||
mCurrencyList = append(mCurrencyList, makeMarketCurrency(mCurrencyName.(string)))
|
||||
}
|
||||
|
||||
return mCurrencyList
|
||||
}
|
||||
|
||||
func makeMarketCurrency(name string) *mCurrency {
|
||||
return &mCurrency{
|
||||
name: name,
|
||||
summaryInfo: summaryInfo{
|
||||
High: "",
|
||||
Low: "",
|
||||
Volume: "",
|
||||
Last: "",
|
||||
OpenBuyOrders: "",
|
||||
OpenSellOrders: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Refresh & update after interval time
|
||||
func (widget *Widget) Refresh() {
|
||||
widget.updateSummary()
|
||||
widget.display()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) updateSummary() {
|
||||
// In case if anything bad happened!
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: time.Duration(5 * time.Second),
|
||||
}
|
||||
|
||||
for _, baseCurrency := range widget.summaryList.items {
|
||||
for _, mCurrency := range baseCurrency.markets {
|
||||
request := makeRequest(baseCurrency.name, mCurrency.name)
|
||||
response, err := client.Do(request)
|
||||
|
||||
if err != nil {
|
||||
ok = false
|
||||
errorText = "Please Check Your Internet Connection!"
|
||||
break
|
||||
} else {
|
||||
ok = true
|
||||
errorText = ""
|
||||
}
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
errorText = response.Status
|
||||
ok = false
|
||||
break
|
||||
} else {
|
||||
ok = true
|
||||
errorText = ""
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
jsonResponse := summaryResponse{}
|
||||
decoder := json.NewDecoder(response.Body)
|
||||
decoder.Decode(&jsonResponse)
|
||||
|
||||
if !jsonResponse.Success {
|
||||
ok = false
|
||||
errorText = fmt.Sprintf("%s-%s: %s", baseCurrency.name, mCurrency.name, jsonResponse.Message)
|
||||
break
|
||||
}
|
||||
ok = true
|
||||
errorText = ""
|
||||
|
||||
mCurrency.Last = fmt.Sprintf("%f", jsonResponse.Result[0].Last)
|
||||
mCurrency.High = fmt.Sprintf("%f", jsonResponse.Result[0].High)
|
||||
mCurrency.Low = fmt.Sprintf("%f", jsonResponse.Result[0].Low)
|
||||
mCurrency.Volume = fmt.Sprintf("%f", jsonResponse.Result[0].Volume)
|
||||
mCurrency.OpenBuyOrders = fmt.Sprintf("%d", jsonResponse.Result[0].OpenBuyOrders)
|
||||
mCurrency.OpenSellOrders = fmt.Sprintf("%d", jsonResponse.Result[0].OpenSellOrders)
|
||||
}
|
||||
}
|
||||
|
||||
widget.display()
|
||||
}
|
||||
|
||||
func makeRequest(baseName, marketName string) *http.Request {
|
||||
url := fmt.Sprintf("%s?market=%s-%s", baseURL, baseName, marketName)
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
|
||||
return request
|
||||
}
|
||||
119
modules/cryptoexchanges/blockfolio/widget.go
Normal file
119
modules/cryptoexchanges/blockfolio/widget.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package blockfolio
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
type Widget struct {
|
||||
wtf.TextWidget
|
||||
|
||||
device_token string
|
||||
}
|
||||
|
||||
func NewWidget(app *tview.Application) *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: wtf.NewTextWidget(app, "Blockfolio", "blockfolio", false),
|
||||
device_token: wtf.Config.UString("wtf.mods.blockfolio.device_token"),
|
||||
}
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) Refresh() {
|
||||
widget.View.SetTitle(" Blockfolio ")
|
||||
|
||||
positions, err := Fetch(widget.device_token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
widget.View.SetText(contentFrom(positions))
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
func contentFrom(positions *AllPositionsResponse) string {
|
||||
res := ""
|
||||
colorName := wtf.Config.UString("wtf.mods.blockfolio.colors.name")
|
||||
colorGrows := wtf.Config.UString("wtf.mods.blockfolio.colors.grows")
|
||||
colorDrop := wtf.Config.UString("wtf.mods.blockfolio.colors.drop")
|
||||
displayHoldings := wtf.Config.UBool("wtf.mods.blockfolio.displayHoldings")
|
||||
var totalFiat float32
|
||||
totalFiat = 0.0
|
||||
for i := 0; i < len(positions.PositionList); i++ {
|
||||
colorForChange := colorGrows
|
||||
if positions.PositionList[i].TwentyFourHourPercentChangeFiat <= 0 {
|
||||
colorForChange = colorDrop
|
||||
}
|
||||
totalFiat += positions.PositionList[i].HoldingValueFiat
|
||||
if displayHoldings {
|
||||
res = res + fmt.Sprintf("[%s]%-6s - %5.2f ([%s]%.3fk [%s]%.2f%s)\n", colorName, positions.PositionList[i].Coin, positions.PositionList[i].Quantity, colorForChange, positions.PositionList[i].HoldingValueFiat/1000, colorForChange, positions.PositionList[i].TwentyFourHourPercentChangeFiat, "%")
|
||||
} else {
|
||||
res = res + fmt.Sprintf("[%s]%-6s - %5.2f ([%s]%.2f%s)\n", colorName, positions.PositionList[i].Coin, positions.PositionList[i].Quantity, colorForChange, positions.PositionList[i].TwentyFourHourPercentChangeFiat, "%")
|
||||
}
|
||||
}
|
||||
if displayHoldings {
|
||||
res = res + fmt.Sprintf("\n[%s]Total value: $%.3fk", "green", totalFiat/1000)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
//always the same
|
||||
const magic = "edtopjhgn2345piuty89whqejfiobh89-2q453"
|
||||
|
||||
type Position struct {
|
||||
Coin string `json:"coin"`
|
||||
LastPriceFiat float32 `json:"lastPriceFiat"`
|
||||
TwentyFourHourPercentChangeFiat float32 `json:"twentyFourHourPercentChangeFiat"`
|
||||
Quantity float32 `json:"quantity"`
|
||||
HoldingValueFiat float32 `json:"holdingValueFiat"`
|
||||
}
|
||||
|
||||
type AllPositionsResponse struct {
|
||||
PositionList []Position `json:"positionList"`
|
||||
}
|
||||
|
||||
func MakeApiRequest(token string, method string) ([]byte, error) {
|
||||
client := &http.Client{}
|
||||
url := "https://api-v0.blockfolio.com/rest/" + method + "/" + token + "?use_alias=true&fiat_currency=USD"
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("magic", magic)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return body, err
|
||||
}
|
||||
|
||||
func GetAllPositions(token string) (*AllPositionsResponse, error) {
|
||||
jsn, _ := MakeApiRequest(token, "get_all_positions")
|
||||
var parsed AllPositionsResponse
|
||||
|
||||
err := json.Unmarshal(jsn, &parsed)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse json %v", err)
|
||||
return nil, err
|
||||
}
|
||||
return &parsed, err
|
||||
}
|
||||
|
||||
func Fetch(token string) (*AllPositionsResponse, error) {
|
||||
return GetAllPositions(token)
|
||||
}
|
||||
28
modules/cryptoexchanges/cryptolive/price/price.go
Normal file
28
modules/cryptoexchanges/cryptolive/price/price.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package price
|
||||
|
||||
type list struct {
|
||||
items []*fromCurrency
|
||||
}
|
||||
|
||||
type fromCurrency struct {
|
||||
name string
|
||||
displayName string
|
||||
to []*toCurrency
|
||||
}
|
||||
|
||||
type toCurrency struct {
|
||||
name string
|
||||
price float32
|
||||
}
|
||||
|
||||
type cResponse map[string]float32
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (l *list) addItem(name string, displayName string, to []*toCurrency) {
|
||||
l.items = append(l.items, &fromCurrency{
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
to: to,
|
||||
})
|
||||
}
|
||||
154
modules/cryptoexchanges/cryptolive/price/widget.go
Normal file
154
modules/cryptoexchanges/cryptolive/price/widget.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package price
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
var baseURL = "https://min-api.cryptocompare.com/data/price"
|
||||
var ok = true
|
||||
|
||||
// Widget define wtf widget to register widget later
|
||||
type Widget struct {
|
||||
*list
|
||||
|
||||
Result string
|
||||
|
||||
RefreshInterval int
|
||||
}
|
||||
|
||||
// NewWidget Make new instance of widget
|
||||
func NewWidget() *Widget {
|
||||
widget := Widget{}
|
||||
|
||||
widget.setList()
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
func (widget *Widget) setList() {
|
||||
currenciesMap, _ := wtf.Config.Map("wtf.mods.cryptolive.currencies")
|
||||
|
||||
widget.list = &list{}
|
||||
|
||||
for currency := range currenciesMap {
|
||||
displayName, _ := wtf.Config.String("wtf.mods.cryptolive.currencies." + currency + ".displayName")
|
||||
toList := getToList(currency)
|
||||
widget.list.addItem(currency, displayName, toList)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Refresh & update after interval time
|
||||
func (widget *Widget) Refresh(wg *sync.WaitGroup) {
|
||||
if len(widget.list.items) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
widget.updateCurrencies()
|
||||
|
||||
if !ok {
|
||||
widget.Result = fmt.Sprint("Please check your internet connection!")
|
||||
return
|
||||
}
|
||||
widget.display()
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) display() {
|
||||
str := ""
|
||||
var (
|
||||
fromNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.from.name", "coral")
|
||||
fromDisplayNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.from.displayName", "grey")
|
||||
toNameColor = wtf.Config.UString("wtf.mods.cryptolive.colors.to.name", "white")
|
||||
toPriceColor = wtf.Config.UString("wtf.mods.cryptolive.colors.to.price", "green")
|
||||
)
|
||||
for _, item := range widget.list.items {
|
||||
str += fmt.Sprintf(" [%s]%s[%s] (%s)\n", fromNameColor, item.displayName, fromDisplayNameColor, item.name)
|
||||
for _, toItem := range item.to {
|
||||
str += fmt.Sprintf("\t[%s]%s: [%s]%f\n", toNameColor, toItem.name, toPriceColor, toItem.price)
|
||||
}
|
||||
str += "\n"
|
||||
}
|
||||
|
||||
widget.Result = fmt.Sprintf("\n%s", str)
|
||||
}
|
||||
|
||||
func getToList(fromName string) []*toCurrency {
|
||||
toNames, _ := wtf.Config.List("wtf.mods.cryptolive.currencies." + fromName + ".to")
|
||||
|
||||
var toList []*toCurrency
|
||||
|
||||
for _, to := range toNames {
|
||||
toList = append(toList, &toCurrency{
|
||||
name: to.(string),
|
||||
price: 0,
|
||||
})
|
||||
}
|
||||
|
||||
return toList
|
||||
}
|
||||
|
||||
func (widget *Widget) updateCurrencies() {
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
for _, fromCurrency := range widget.list.items {
|
||||
|
||||
var (
|
||||
client http.Client
|
||||
jsonResponse cResponse
|
||||
)
|
||||
|
||||
client = http.Client{
|
||||
Timeout: time.Duration(5 * time.Second),
|
||||
}
|
||||
|
||||
request := makeRequest(fromCurrency)
|
||||
response, err := client.Do(request)
|
||||
|
||||
if err != nil {
|
||||
ok = false
|
||||
} else {
|
||||
ok = true
|
||||
}
|
||||
|
||||
defer response.Body.Close()
|
||||
|
||||
_ = json.NewDecoder(response.Body).Decode(&jsonResponse)
|
||||
|
||||
setPrices(&jsonResponse, fromCurrency)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func makeRequest(currency *fromCurrency) *http.Request {
|
||||
fsym := currency.name
|
||||
tsyms := ""
|
||||
for _, to := range currency.to {
|
||||
tsyms += fmt.Sprintf("%s,", to.name)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, fsym, tsyms)
|
||||
request, err := http.NewRequest("GET", url, nil)
|
||||
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
func setPrices(response *cResponse, currencry *fromCurrency) {
|
||||
for idx, toCurrency := range currencry.to {
|
||||
currencry.to[idx].price = (*response)[toCurrency.name]
|
||||
}
|
||||
}
|
||||
55
modules/cryptoexchanges/cryptolive/toplist/display.go
Normal file
55
modules/cryptoexchanges/cryptolive/toplist/display.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package toplist
|
||||
|
||||
import "fmt"
|
||||
|
||||
func (widget *Widget) display() {
|
||||
str := ""
|
||||
for _, fromCurrency := range widget.list.items {
|
||||
str += fmt.Sprintf(
|
||||
"[%s]%s [%s](%s)\n",
|
||||
widget.colors.from.displayName,
|
||||
fromCurrency.displayName,
|
||||
widget.colors.from.name,
|
||||
fromCurrency.name,
|
||||
)
|
||||
str += makeToListText(fromCurrency.to, widget.colors)
|
||||
}
|
||||
|
||||
widget.Result = str
|
||||
}
|
||||
|
||||
func makeToListText(toList []*tCurrency, colors textColors) string {
|
||||
str := ""
|
||||
for _, toCurrency := range toList {
|
||||
str += makeToText(toCurrency, colors)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
func makeToText(toCurrency *tCurrency, colors textColors) string {
|
||||
str := ""
|
||||
str += fmt.Sprintf(" [%s]%s\n", colors.to.name, toCurrency.name)
|
||||
for _, info := range toCurrency.info {
|
||||
str += makeInfoText(info, colors)
|
||||
str += "\n\n"
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func makeInfoText(info tInfo, colors textColors) string {
|
||||
return fmt.Sprintf(
|
||||
" [%s]Exchange: [%s]%s\n",
|
||||
colors.to.field,
|
||||
colors.to.value,
|
||||
info.exchange,
|
||||
) +
|
||||
fmt.Sprintf(
|
||||
" [%s]Volume(24h): [%s]%f-[%s]%f",
|
||||
colors.to.field,
|
||||
colors.to.value,
|
||||
info.volume24h,
|
||||
colors.to.value,
|
||||
info.volume24hTo,
|
||||
)
|
||||
}
|
||||
41
modules/cryptoexchanges/cryptolive/toplist/toplist.go
Normal file
41
modules/cryptoexchanges/cryptolive/toplist/toplist.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package toplist
|
||||
|
||||
type cList struct {
|
||||
items []*fCurrency
|
||||
}
|
||||
|
||||
type fCurrency struct {
|
||||
name, displayName string
|
||||
limit int
|
||||
to []*tCurrency
|
||||
}
|
||||
|
||||
type tCurrency struct {
|
||||
name string
|
||||
info []tInfo
|
||||
}
|
||||
|
||||
type tInfo struct {
|
||||
exchange string
|
||||
volume24h, volume24hTo float32
|
||||
}
|
||||
|
||||
type responseInterface struct {
|
||||
Response string `json:"Response"`
|
||||
Data []struct {
|
||||
Exchange string `json:"exchange"`
|
||||
FromSymbol string `json:"fromSymbol"`
|
||||
ToSymbol string `json:"toSymbol"`
|
||||
Volume24h float32 `json:"volume24h"`
|
||||
Volume24hTo float32 `json:"volume24hTo"`
|
||||
} `json:"Data"`
|
||||
}
|
||||
|
||||
func (list *cList) addItem(name, displayName string, limit int, to []*tCurrency) {
|
||||
list.items = append(list.items, &fCurrency{
|
||||
name: name,
|
||||
displayName: displayName,
|
||||
limit: limit,
|
||||
to: to,
|
||||
})
|
||||
}
|
||||
137
modules/cryptoexchanges/cryptolive/toplist/widget.go
Normal file
137
modules/cryptoexchanges/cryptolive/toplist/widget.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package toplist
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
var baseURL = "https://min-api.cryptocompare.com/data/top/exchanges"
|
||||
|
||||
type textColors struct {
|
||||
from struct {
|
||||
name string
|
||||
displayName string
|
||||
}
|
||||
to struct {
|
||||
name string
|
||||
field string
|
||||
value string
|
||||
}
|
||||
}
|
||||
|
||||
// Widget Toplist Widget
|
||||
type Widget struct {
|
||||
Result string
|
||||
|
||||
RefreshInterval int
|
||||
|
||||
list *cList
|
||||
|
||||
colors textColors
|
||||
}
|
||||
|
||||
// NewWidget Make new toplist widget
|
||||
func NewWidget() *Widget {
|
||||
widget := Widget{}
|
||||
|
||||
widget.list = &cList{}
|
||||
widget.setList()
|
||||
widget.config()
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
func (widget *Widget) setList() {
|
||||
currenciesMap, _ := wtf.Config.Map("wtf.mods.cryptolive.top")
|
||||
|
||||
for fromCurrency := range currenciesMap {
|
||||
displayName := wtf.Config.UString("wtf.mods.cryptolive.top."+fromCurrency+".displayName", "")
|
||||
limit := wtf.Config.UInt("wtf.mods.cryptolive.top."+fromCurrency+".limit", 1)
|
||||
widget.list.addItem(fromCurrency, displayName, limit, makeToList(fromCurrency, limit))
|
||||
}
|
||||
}
|
||||
|
||||
func makeToList(fCurrencyName string, limit int) (list []*tCurrency) {
|
||||
toList, _ := wtf.Config.List("wtf.mods.cryptolive.top." + fCurrencyName + ".to")
|
||||
|
||||
for _, toCurrency := range toList {
|
||||
list = append(list, &tCurrency{
|
||||
name: toCurrency.(string),
|
||||
info: make([]tInfo, limit),
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (widget *Widget) config() {
|
||||
// set colors
|
||||
widget.colors.from.name = wtf.Config.UString("wtf.mods.cryptolive.colors.top.from.name", "coral")
|
||||
widget.colors.from.displayName = wtf.Config.UString("wtf.mods.cryptolive.colors.top.from.displayName", "grey")
|
||||
widget.colors.to.name = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.name", "red")
|
||||
widget.colors.to.field = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.field", "white")
|
||||
widget.colors.to.value = wtf.Config.UString("wtf.mods.cryptolive.colors.top.to.value", "value")
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Refresh & update after interval time
|
||||
func (widget *Widget) Refresh(wg *sync.WaitGroup) {
|
||||
if len(widget.list.items) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
widget.updateData()
|
||||
|
||||
widget.display()
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) updateData() {
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: time.Duration(5 * time.Second),
|
||||
}
|
||||
|
||||
for _, fromCurrency := range widget.list.items {
|
||||
for _, toCurrency := range fromCurrency.to {
|
||||
|
||||
request := makeRequest(fromCurrency.name, toCurrency.name, fromCurrency.limit)
|
||||
response, _ := client.Do(request)
|
||||
|
||||
var jsonResponse responseInterface
|
||||
|
||||
err := json.NewDecoder(response.Body).Decode(&jsonResponse)
|
||||
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for idx, info := range jsonResponse.Data {
|
||||
toCurrency.info[idx] = tInfo{
|
||||
exchange: info.Exchange,
|
||||
volume24h: info.Volume24h,
|
||||
volume24hTo: info.Volume24hTo,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeRequest(fsym, tsym string, limit int) *http.Request {
|
||||
url := fmt.Sprintf("%s?fsym=%s&tsym=%s&limit=%d", baseURL, fsym, tsym, limit)
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
return request
|
||||
}
|
||||
55
modules/cryptoexchanges/cryptolive/widget.go
Normal file
55
modules/cryptoexchanges/cryptolive/widget.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package cryptolive
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive/price"
|
||||
"github.com/wtfutil/wtf/modules/cryptoexchanges/cryptolive/toplist"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
)
|
||||
|
||||
// Widget define wtf widget to register widget later
|
||||
type Widget struct {
|
||||
wtf.TextWidget
|
||||
priceWidget *price.Widget
|
||||
toplistWidget *toplist.Widget
|
||||
}
|
||||
|
||||
// NewWidget Make new instance of widget
|
||||
func NewWidget(app *tview.Application) *Widget {
|
||||
widget := Widget{
|
||||
TextWidget: wtf.NewTextWidget(app, "CryptoLive", "cryptolive", false),
|
||||
priceWidget: price.NewWidget(),
|
||||
toplistWidget: toplist.NewWidget(),
|
||||
}
|
||||
|
||||
widget.priceWidget.RefreshInterval = widget.RefreshInterval()
|
||||
widget.toplistWidget.RefreshInterval = widget.RefreshInterval()
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
// Refresh & update after interval time
|
||||
func (widget *Widget) Refresh() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(2)
|
||||
widget.priceWidget.Refresh(&wg)
|
||||
widget.toplistWidget.Refresh(&wg)
|
||||
wg.Wait()
|
||||
|
||||
display(widget)
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func display(widget *Widget) {
|
||||
str := ""
|
||||
str += widget.priceWidget.Result
|
||||
str += widget.toplistWidget.Result
|
||||
widget.View.SetText(fmt.Sprintf("\n%s", str))
|
||||
}
|
||||
Reference in New Issue
Block a user