package widget
import (
"context"
"html/template"
"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 "ok"
}
return "error"
}
type Monitor struct {
widgetBase `yaml:",inline"`
Sites []struct {
*feed.SiteStatusRequest `yaml:",inline"`
Status *feed.SiteStatus `yaml:"-"`
Title string `yaml:"title"`
IconUrl string `yaml:"icon"`
IsSimpleIcon bool `yaml:"-"`
SameTab bool `yaml:"same-tab"`
StatusText string `yaml:"-"`
StatusStyle string `yaml:"-"`
} `yaml:"sites"`
ShowFailingOnly bool `yaml:"show-failing-only"`
HasFailing bool `yaml:"-"`
}
func (widget *Monitor) Initialize() error {
widget.withTitle("Monitor").withCacheDuration(5 * time.Minute)
for i := range widget.Sites {
widget.Sites[i].IconUrl, widget.Sites[i].IsSimpleIcon = toSimpleIconIfPrefixed(widget.Sites[i].IconUrl)
}
return nil
}
func (widget *Monitor) Update(ctx context.Context) {
requests := make([]*feed.SiteStatusRequest, len(widget.Sites))
for i := range widget.Sites {
requests[i] = widget.Sites[i].SiteStatusRequest
}
statuses, err := feed.FetchStatusForSites(requests)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return
}
widget.HasFailing = false
for i := range widget.Sites {
site := &widget.Sites[i]
status := &statuses[i]
site.Status = status
if status.Code >= 400 || status.TimedOut || status.Error != nil {
widget.HasFailing = true
}
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)
}