Simple MJPEG streamer for ESPHome cameras.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

86 lines
1.9 KiB

package main
import (
"fmt"
"io"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/flosch/pongo2"
"github.com/labstack/echo/v4"
)
// Renderer manages a pongo2 TemplateSet
type Renderer struct {
Path string
TemplateSet *pongo2.TemplateSet
Debug bool
}
// NewRenderer creates a new instance of Renderer
func NewRenderer(root string) (*Renderer, error) {
// check if root exists
fInfo, err := os.Lstat(root)
if err != nil {
return nil, err
}
if fInfo.IsDir() == false {
return nil, fmt.Errorf("%s is not a directory", root)
}
rdr := Renderer{}
loader, err := pongo2.NewLocalFileSystemLoader(root)
if err != nil {
return nil, err
}
rdr.TemplateSet = pongo2.NewSet("TemplateSet-"+filepath.Base(root), loader)
return &rdr, nil
}
// Render implements echo.Render interface
func (r *Renderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
// get template, compile it anf store it in cache
//tpl, err := r.TemplateSet.FromCache(name)
tpl, err := r.TemplateSet.FromFile(name)
if err != nil {
return err
}
// convert supplied data to pongo2.Context
val, err := toPongoCtx(data)
if err != nil {
return err
}
// generate render the template
err = tpl.ExecuteWriter(val, w)
return err
}
// toPongoCtx converts a pongo2.Context, struct, map[string] to
// pongo2.Context
func toPongoCtx(data interface{}) (pongo2.Context, error) {
if c, ok := data.(pongo2.Context); ok {
return c, nil
}
var (
ctx = pongo2.Context{}
val = reflect.ValueOf(data)
)
if val.Kind().String() == "struct" {
for i := 0; i < val.NumField(); i++ {
ctx[val.Type().Field(i).Name] = val.Field(i).Interface()
}
} else if strings.HasPrefix(val.Type().String(), "map[string]") {
for _, k := range val.MapKeys() {
ctx[k.String()] = val.MapIndex(k).Interface()
}
} else {
return nil, fmt.Errorf("cant convert %T to pongo2.Context", data)
}
return ctx, nil
}