diff --git a/cryptoexchanges/cryptolive/cryptolive.go b/cryptoexchanges/cryptolive/cryptolive.go index b9e641a0..f92d7dbf 100644 --- a/cryptoexchanges/cryptolive/cryptolive.go +++ b/cryptoexchanges/cryptolive/cryptolive.go @@ -1,28 +1 @@ package cryptolive - -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, - }) -} diff --git a/cryptoexchanges/cryptolive/price/price.go b/cryptoexchanges/cryptolive/price/price.go new file mode 100644 index 00000000..76464d9a --- /dev/null +++ b/cryptoexchanges/cryptolive/price/price.go @@ -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, + }) +} diff --git a/cryptoexchanges/cryptolive/price/widget.go b/cryptoexchanges/cryptolive/price/widget.go new file mode 100644 index 00000000..26d8ef9d --- /dev/null +++ b/cryptoexchanges/cryptolive/price/widget.go @@ -0,0 +1,166 @@ +package price + +import ( + "encoding/json" + "fmt" + "net/http" + "time" + + "github.com/olebedev/config" +) + +// Config is a pointer to the global config object +var Config *config.Config + +var started = false +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 { + started = false + widget := Widget{} + + widget.setList() + + return &widget +} + +func (widget *Widget) setList() { + currenciesMap, _ := Config.Map("wtf.mods.cryptolive.currencies") + + widget.list = &list{} + + for currency := range currenciesMap { + displayName, _ := 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() { + + if started == false { + // this code should run once + go func() { + for { + widget.updateCurrencies() + time.Sleep(time.Duration(widget.RefreshInterval) * time.Second) + } + }() + + } + + started = true + + if !ok { + widget.Result = fmt.Sprint("Please check your internet connection!") + return + } + widget.display() +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) display() { + str := "" + var ( + fromNameColor = Config.UString("wtf.mods.cryptolive.colors.from.name", "coral") + fromDisplayNameColor = Config.UString("wtf.mods.cryptolive.colors.from.displayName", "grey") + toNameColor = Config.UString("wtf.mods.cryptolive.colors.to.name", "white") + toPriceColor = 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, _ := 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) + } + + widget.display() +} + +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] + } +} diff --git a/cryptoexchanges/cryptolive/toplist/display.go b/cryptoexchanges/cryptolive/toplist/display.go new file mode 100644 index 00000000..5b5f2434 --- /dev/null +++ b/cryptoexchanges/cryptolive/toplist/display.go @@ -0,0 +1,23 @@ +package toplist + +import "fmt" + +func (widget *Widget) display() { + str := "" + for _, fromCurrency := range widget.list.items { + str += fmt.Sprintf("%s (%s)\n", fromCurrency.displayName, fromCurrency.name) + for _, toCurrency := range fromCurrency.to { + str += fmt.Sprintf(" %s\n", toCurrency.name) + for _, info := range toCurrency.info { + str += makeInfoRow(info) + str += "\n\n" + } + } + } + + widget.Result = str +} + +func makeInfoRow(info tInfo) string { + return fmt.Sprintf(" Exchange: %s\n", info.exchange) + fmt.Sprintf(" Volume(24h): %f-%f", info.volume24h, info.volume24hTo) +} diff --git a/cryptoexchanges/cryptolive/toplist/toplist.go b/cryptoexchanges/cryptolive/toplist/toplist.go new file mode 100644 index 00000000..9bb48947 --- /dev/null +++ b/cryptoexchanges/cryptolive/toplist/toplist.go @@ -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, + }) +} diff --git a/cryptoexchanges/cryptolive/toplist/widget.go b/cryptoexchanges/cryptolive/toplist/widget.go new file mode 100644 index 00000000..b040cee0 --- /dev/null +++ b/cryptoexchanges/cryptolive/toplist/widget.go @@ -0,0 +1,117 @@ +package toplist + +import ( + "encoding/json" + "fmt" + "net/http" + "os" + "time" + + "github.com/olebedev/config" +) + +// Config is a pointer to the global config object +var Config *config.Config +var started = false +var baseURL = "https://min-api.cryptocompare.com/data/top/exchanges" + +// Widget Toplist Widget +type Widget struct { + Result string + + RefreshInterval int + + list *cList +} + +// NewWidget Make new toplist widget +func NewWidget() *Widget { + widget := Widget{} + + started = false + widget.list = &cList{} + widget.setList() + + return &widget +} + +func (widget *Widget) setList() { + currenciesMap, _ := Config.Map("wtf.mods.cryptolive.top") + + for fromCurrency := range currenciesMap { + displayName := Config.UString("wtf.mods.cryptolive.top."+fromCurrency+".displayName", "") + limit := Config.UInt("wtf.mods.cryptolive.top."+fromCurrency+".limit", 5) + widget.list.addItem(fromCurrency, displayName, limit, makeToList(fromCurrency, limit)) + } +} + +func makeToList(fCurrencyName string, limit int) (list []*tCurrency) { + toList, _ := Config.List("wtf.mods.cryptolive.top." + fCurrencyName + ".to") + + for _, toCurrency := range toList { + list = append(list, &tCurrency{ + name: toCurrency.(string), + info: make([]tInfo, limit), + }) + } + + return +} + +/* -------------------- Exported Functions -------------------- */ + +// Refresh & update after interval time +func (widget *Widget) Refresh() { + + if !started { + go func() { + for { + widget.updateData() + time.Sleep(time.Second * time.Duration(widget.RefreshInterval)) + } + }() + started = true + } + + widget.display() +} + +/* -------------------- Unexported Functions -------------------- */ + +func (widget *Widget) updateData() { + + 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 +} diff --git a/cryptoexchanges/cryptolive/widget.go b/cryptoexchanges/cryptolive/widget.go index e58b9435..eba98559 100644 --- a/cryptoexchanges/cryptolive/widget.go +++ b/cryptoexchanges/cryptolive/widget.go @@ -1,54 +1,41 @@ package cryptolive import ( - "encoding/json" "fmt" - "net/http" - "time" "github.com/olebedev/config" + "github.com/senorprogrammer/wtf/cryptoexchanges/cryptolive/price" + "github.com/senorprogrammer/wtf/cryptoexchanges/cryptolive/toplist" "github.com/senorprogrammer/wtf/wtf" ) // Config is a pointer to the global config object var Config *config.Config -var started = false -var baseURL = "https://min-api.cryptocompare.com/data/price" -var ok = true - // Widget define wtf widget to register widget later type Widget struct { wtf.TextWidget - - *list + priceWidget *price.Widget + toplistWidget *toplist.Widget } // NewWidget Make new instance of widget func NewWidget() *Widget { - started = false + price.Config = Config + toplist.Config = Config + widget := Widget{ - TextWidget: wtf.NewTextWidget(" CryptoLive ", "cryptolive", false), + TextWidget: wtf.NewTextWidget(" CryptoLive ", "cryptolive", false), + priceWidget: price.NewWidget(), + toplistWidget: toplist.NewWidget(), } - widget.setList() + widget.priceWidget.RefreshInterval = widget.RefreshInterval() + widget.toplistWidget.RefreshInterval = widget.RefreshInterval() return &widget } -func (widget *Widget) setList() { - currenciesMap, _ := Config.Map("wtf.mods.cryptolive.currencies") - - widget.list = &list{} - - for currency := range currenciesMap { - displayName, _ := Config.String("wtf.mods.cryptolive.currencies." + currency + ".displayName") - toList := getToList(currency) - widget.list.addItem(currency, displayName, toList) - } - -} - /* -------------------- Exported Functions -------------------- */ // Refresh & update after interval time @@ -57,28 +44,11 @@ func (widget *Widget) Refresh() { return } - if started == false { - // this code should run once - go func() { - for { - widget.updateCurrencies() - time.Sleep(time.Duration(widget.RefreshInterval()) * time.Second) - } - }() - - } - - started = true + widget.priceWidget.Refresh() + widget.toplistWidget.Refresh() widget.UpdateRefreshedAt() - widget.View.Clear() - if !ok { - widget.View.SetText( - fmt.Sprint("Please check your internet connection!"), - ) - return - } display(widget) } @@ -86,90 +56,7 @@ func (widget *Widget) Refresh() { func display(widget *Widget) { str := "" - var ( - fromNameColor = Config.UString("wtf.mods.cryptolive.colors.from.name", "coral") - fromDisplayNameColor = Config.UString("wtf.mods.cryptolive.colors.from.displayName", "grey") - toNameColor = Config.UString("wtf.mods.cryptolive.colors.to.name", "white") - toPriceColor = 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" - } - + str += widget.priceWidget.Result + str += widget.toplistWidget.Result widget.View.SetText(fmt.Sprintf("\n%s", str)) } - -func getToList(fromName string) []*toCurrency { - toNames, _ := 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) - } - - display(widget) -} - -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] - } -}