github.com/wtfutil/wtf@v0.43.0/modules/weatherservices/weather/widget.go (about)

     1  package weather
     2  
     3  import (
     4  	owm "github.com/briandowns/openweathermap"
     5  	"github.com/rivo/tview"
     6  	"github.com/wtfutil/wtf/utils"
     7  	"github.com/wtfutil/wtf/view"
     8  )
     9  
    10  // Widget is the container for weather data.
    11  type Widget struct {
    12  	view.MultiSourceWidget
    13  	view.TextWidget
    14  
    15  	// APIKey   string
    16  	Data []*owm.CurrentWeatherData
    17  
    18  	pages    *tview.Pages
    19  	settings *Settings
    20  }
    21  
    22  // NewWidget creates and returns a new instance of the weather Widget
    23  func NewWidget(tviewApp *tview.Application, redrawChan chan bool, pages *tview.Pages, settings *Settings) *Widget {
    24  	widget := Widget{
    25  		MultiSourceWidget: view.NewMultiSourceWidget(settings.Common, "cityid", "cityids"),
    26  		TextWidget:        view.NewTextWidget(tviewApp, redrawChan, pages, settings.Common),
    27  
    28  		pages:    pages,
    29  		settings: settings,
    30  	}
    31  
    32  	widget.initializeKeyboardControls()
    33  
    34  	widget.SetDisplayFunction(widget.display)
    35  
    36  	return &widget
    37  }
    38  
    39  /* -------------------- Exported Functions -------------------- */
    40  
    41  // Fetch retrieves OpenWeatherMap data from the OpenWeatherMap API.
    42  // It takes a list of OpenWeatherMap city IDs.
    43  // It returns a list of OpenWeatherMap CurrentWeatherData structs, one per valid city code.
    44  func (widget *Widget) Fetch(cityIDs []int) []*owm.CurrentWeatherData {
    45  	data := []*owm.CurrentWeatherData{}
    46  
    47  	for _, cityID := range cityIDs {
    48  		result, err := widget.currentWeather(cityID)
    49  		if err == nil {
    50  			data = append(data, result)
    51  		}
    52  	}
    53  
    54  	return data
    55  }
    56  
    57  // Refresh fetches new data from the OpenWeatherMap API and loads the new data into the.
    58  // widget's view for rendering
    59  func (widget *Widget) Refresh() {
    60  	if widget.apiKeyValid() {
    61  		widget.Data = widget.Fetch(utils.ToInts(widget.settings.cityIDs))
    62  	}
    63  
    64  	widget.display()
    65  }
    66  
    67  /* -------------------- Unexported Functions -------------------- */
    68  
    69  func (widget *Widget) apiKeyValid() bool {
    70  	if widget.settings.apiKey == "" {
    71  		return false
    72  	}
    73  
    74  	if len(widget.settings.apiKey) != 32 {
    75  		return false
    76  	}
    77  
    78  	return true
    79  }
    80  
    81  func (widget *Widget) currentData() *owm.CurrentWeatherData {
    82  	if len(widget.Data) == 0 {
    83  		return nil
    84  	}
    85  
    86  	if widget.Idx < 0 || widget.Idx >= len(widget.Data) {
    87  		return nil
    88  	}
    89  
    90  	return widget.Data[widget.Idx]
    91  }
    92  
    93  func (widget *Widget) currentWeather(cityCode int) (*owm.CurrentWeatherData, error) {
    94  	weather, err := owm.NewCurrent(
    95  		widget.settings.tempUnit,
    96  		widget.settings.language,
    97  		widget.settings.apiKey,
    98  	)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	err = weather.CurrentByID(cityCode)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	return weather, nil
   109  }