github.com/wtfutil/wtf@v0.43.0/modules/cryptocurrency/cryptolive/price/widget.go (about)

     1  package price
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"sync"
     8  	"time"
     9  )
    10  
    11  var baseURL = "https://min-api.cryptocompare.com/data/price"
    12  var ok = true
    13  
    14  // Widget define wtf widget to register widget later
    15  type Widget struct {
    16  	*list
    17  	settings *Settings
    18  
    19  	Result string
    20  
    21  	RefreshInterval time.Duration
    22  }
    23  
    24  // NewWidget Make new instance of widget
    25  func NewWidget(settings *Settings) *Widget {
    26  	widget := Widget{
    27  		settings: settings,
    28  	}
    29  
    30  	widget.setList()
    31  
    32  	return &widget
    33  }
    34  
    35  func (widget *Widget) setList() {
    36  	widget.list = &list{}
    37  
    38  	for symbol, currency := range widget.settings.currencies {
    39  		toList := widget.getToList(symbol)
    40  		widget.list.addItem(symbol, currency.displayName, toList)
    41  	}
    42  }
    43  
    44  /* -------------------- Exported Functions -------------------- */
    45  
    46  // Refresh & update after interval time
    47  func (widget *Widget) Refresh(wg *sync.WaitGroup) {
    48  	if len(widget.list.items) != 0 {
    49  		widget.updateCurrencies()
    50  		if !ok {
    51  			widget.Result = "Please check your internet connection"
    52  		} else {
    53  			widget.display()
    54  		}
    55  	}
    56  	wg.Done()
    57  }
    58  
    59  /* -------------------- Unexported Functions -------------------- */
    60  
    61  func (widget *Widget) display() {
    62  	str := ""
    63  
    64  	for _, item := range widget.list.items {
    65  		str += fmt.Sprintf(
    66  			" [%s]%s[%s] (%s)\n",
    67  			widget.settings.colors.from.name,
    68  			item.displayName,
    69  			widget.settings.colors.from.name,
    70  			item.name,
    71  		)
    72  		for _, toItem := range item.to {
    73  			str += fmt.Sprintf(
    74  				"\t[%s]%s: [%s]%f\n",
    75  				widget.settings.colors.to.name,
    76  				toItem.name,
    77  				widget.settings.colors.to.price,
    78  				toItem.price,
    79  			)
    80  		}
    81  		str += "\n"
    82  	}
    83  
    84  	widget.Result = fmt.Sprintf("\n%s", str)
    85  }
    86  
    87  func (widget *Widget) getToList(symbol string) []*toCurrency {
    88  	var toList []*toCurrency
    89  
    90  	for _, to := range widget.settings.currencies[symbol].to {
    91  		toList = append(toList, &toCurrency{
    92  			name:  to.(string),
    93  			price: 0,
    94  		})
    95  	}
    96  
    97  	return toList
    98  }
    99  
   100  func (widget *Widget) updateCurrencies() {
   101  	defer func() {
   102  		if r := recover(); r != nil {
   103  			fmt.Println("recovered in updateSummary()", r)
   104  		}
   105  	}()
   106  	for _, fromCurrency := range widget.list.items {
   107  
   108  		var (
   109  			client       http.Client
   110  			jsonResponse cResponse
   111  		)
   112  
   113  		client = http.Client{
   114  			Timeout: 5 * time.Second,
   115  		}
   116  
   117  		request := makeRequest(fromCurrency)
   118  		response, err := client.Do(request)
   119  
   120  		if err != nil {
   121  			ok = false
   122  		} else {
   123  			ok = true
   124  		}
   125  
   126  		defer func() { _ = response.Body.Close() }()
   127  
   128  		_ = json.NewDecoder(response.Body).Decode(&jsonResponse)
   129  
   130  		setPrices(&jsonResponse, fromCurrency)
   131  	}
   132  }
   133  
   134  func makeRequest(currency *fromCurrency) *http.Request {
   135  	tsyms := ""
   136  	for _, to := range currency.to {
   137  		tsyms += fmt.Sprintf("%s,", to.name)
   138  	}
   139  
   140  	url := fmt.Sprintf("%s?fsym=%s&tsyms=%s", baseURL, currency.name, tsyms)
   141  	request, _ := http.NewRequest("GET", url, http.NoBody)
   142  
   143  	return request
   144  }
   145  
   146  func setPrices(response *cResponse, currencry *fromCurrency) {
   147  	for idx, toCurrency := range currencry.to {
   148  		currencry.to[idx].price = (*response)[toCurrency.name]
   149  	}
   150  }