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 }