weather.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package widget
  2. import (
  3. "context"
  4. "fmt"
  5. "html/template"
  6. "github.com/glanceapp/glance/internal/assets"
  7. "github.com/glanceapp/glance/internal/feed"
  8. )
  9. type Weather struct {
  10. widgetBase `yaml:",inline"`
  11. Location string `yaml:"location"`
  12. ShowAreaName bool `yaml:"show-area-name"`
  13. HideLocation bool `yaml:"hide-location"`
  14. HourFormat string `yaml:"hour-format"`
  15. Units string `yaml:"units"`
  16. Place *feed.PlaceJson `yaml:"-"`
  17. Weather *feed.Weather `yaml:"-"`
  18. TimeLabels [12]string `yaml:"-"`
  19. }
  20. var timeLabels12h = [12]string{"2am", "4am", "6am", "8am", "10am", "12pm", "2pm", "4pm", "6pm", "8pm", "10pm", "12am"}
  21. var timeLabels24h = [12]string{"02:00", "04:00", "06:00", "08:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00", "00:00"}
  22. func (widget *Weather) Initialize() error {
  23. widget.withTitle("Weather").withCacheOnTheHour()
  24. if widget.Location == "" {
  25. return fmt.Errorf("location must be specified for weather widget")
  26. }
  27. if widget.HourFormat == "" || widget.HourFormat == "12h" {
  28. widget.TimeLabels = timeLabels12h
  29. } else if widget.HourFormat == "24h" {
  30. widget.TimeLabels = timeLabels24h
  31. } else {
  32. return fmt.Errorf("invalid hour format '%s' for weather widget, must be either 12h or 24h", widget.HourFormat)
  33. }
  34. if widget.Units == "" {
  35. widget.Units = "metric"
  36. } else if widget.Units != "metric" && widget.Units != "imperial" {
  37. return fmt.Errorf("invalid units '%s' for weather, must be either metric or imperial", widget.Units)
  38. }
  39. return nil
  40. }
  41. func (widget *Weather) Update(ctx context.Context) {
  42. if widget.Place == nil {
  43. place, err := feed.FetchPlaceFromName(widget.Location)
  44. if err != nil {
  45. widget.withError(err).scheduleEarlyUpdate()
  46. return
  47. }
  48. widget.Place = place
  49. }
  50. weather, err := feed.FetchWeatherForPlace(widget.Place, widget.Units)
  51. if !widget.canContinueUpdateAfterHandlingErr(err) {
  52. return
  53. }
  54. widget.Weather = weather
  55. }
  56. func (widget *Weather) Render() template.HTML {
  57. return widget.render(widget, assets.WeatherTemplate)
  58. }