Add custom API widget

This commit is contained in:
Svilen Markov
2024-10-21 23:27:25 +01:00
parent 2dd5b29303
commit 84a7f90129
8 changed files with 244 additions and 8 deletions

View File

@@ -0,0 +1,70 @@
package widget
import (
"context"
"errors"
"fmt"
"html/template"
"net/http"
"time"
"github.com/glanceapp/glance/internal/assets"
"github.com/glanceapp/glance/internal/feed"
)
type CustomApi struct {
widgetBase `yaml:",inline"`
URL string `yaml:"url"`
Template string `yaml:"template"`
Frameless bool `yaml:"frameless"`
Headers map[string]OptionalEnvString `yaml:"headers"`
APIRequest *http.Request `yaml:"-"`
compiledTemplate *template.Template `yaml:"-"`
CompiledHTML template.HTML `yaml:"-"`
}
func (widget *CustomApi) Initialize() error {
widget.withTitle("Custom API").withCacheDuration(1 * time.Hour)
if widget.URL == "" {
return errors.New("URL is required for the custom API widget")
}
if widget.Template == "" {
return errors.New("template is required for the custom API widget")
}
compiledTemplate, err := template.New("").Funcs(feed.CustomAPITemplateFuncs).Parse(widget.Template)
if err != nil {
return fmt.Errorf("failed parsing custom API widget template: %w", err)
}
widget.compiledTemplate = compiledTemplate
req, err := http.NewRequest(http.MethodGet, widget.URL, nil)
if err != nil {
return err
}
for key, value := range widget.Headers {
req.Header.Add(key, value.String())
}
widget.APIRequest = req
return nil
}
func (widget *CustomApi) Update(ctx context.Context) {
compiledHTML, err := feed.FetchAndParseCustomAPI(widget.APIRequest, widget.compiledTemplate)
if !widget.canContinueUpdateAfterHandlingErr(err) {
return
}
widget.CompiledHTML = compiledHTML
}
func (widget *CustomApi) Render() template.HTML {
return widget.render(widget, assets.CustomAPITemplate)
}

View File

@@ -69,6 +69,8 @@ func New(widgetType string) (Widget, error) {
widget = &DNSStats{}
case "split-column":
widget = &SplitColumn{}
case "custom-api":
widget = &CustomApi{}
default:
return nil, fmt.Errorf("unknown widget type: %s", widgetType)
}