package widget import ( "context" "fmt" "html/template" "net/http" "strconv" "time" "github.com/glanceapp/glance/internal/assets" "github.com/glanceapp/glance/internal/feed" ) func statusCodeToText(status int) string { if status == 200 { return "OK" } if status == 404 { return "Not Found" } if status == 403 { return "Forbidden" } if status == 401 { return "Unauthorized" } if status >= 400 { return "Client Error" } if status >= 500 { return "Server Error" } return strconv.Itoa(status) } func statusCodeToStyle(status int) string { if status == 200 { return "good" } return "bad" } type Monitor struct { widgetBase `yaml:",inline"` Sites []struct { Title string `yaml:"title"` Url string `yaml:"url"` IconUrl string `yaml:"icon"` Status *feed.SiteStatus `yaml:"-"` StatusText string `yaml:"-"` StatusStyle string `yaml:"-"` } `yaml:"sites"` } func (widget *Monitor) Initialize() error { widget.withTitle("Monitor").withCacheDuration(5 * time.Minute) return nil } func (widget *Monitor) Update(ctx context.Context) { requests := make([]*http.Request, len(widget.Sites)) for i := range widget.Sites { request, err := http.NewRequest("GET", widget.Sites[i].Url, nil) if err != nil { message := fmt.Errorf("failed to create http request for %s: %s", widget.Sites[i].Url, err) widget.withNotice(message) continue } requests[i] = request } statuses, err := feed.FetchStatusesForRequests(requests) if !widget.canContinueUpdateAfterHandlingErr(err) { return } for i := range widget.Sites { site := &widget.Sites[i] status := &statuses[i] site.Status = status if !status.TimedOut { site.StatusText = statusCodeToText(status.Code) site.StatusStyle = statusCodeToStyle(status.Code) } } } func (widget *Monitor) Render() template.HTML { return widget.render(widget, assets.MonitorTemplate) }