|
|
package http |
|
|
|
|
|
import ( |
|
|
"embed" |
|
|
"fmt" |
|
|
"html/template" |
|
|
"io" |
|
|
"io/fs" |
|
|
"net/http" |
|
|
"strings" |
|
|
|
|
|
"github.com/Masterminds/sprig/v3" |
|
|
"github.com/labstack/echo/v4" |
|
|
"github.com/microcosm-cc/bluemonday" |
|
|
"github.com/mudler/LocalAI/core/http/middleware" |
|
|
"github.com/mudler/LocalAI/core/schema" |
|
|
"github.com/russross/blackfriday" |
|
|
) |
|
|
|
|
|
|
|
|
var viewsfs embed.FS |
|
|
|
|
|
|
|
|
type TemplateRenderer struct { |
|
|
templates *template.Template |
|
|
} |
|
|
|
|
|
|
|
|
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error { |
|
|
return t.templates.ExecuteTemplate(w, name, data) |
|
|
} |
|
|
|
|
|
func notFoundHandler(c echo.Context) error { |
|
|
|
|
|
contentType := c.Request().Header.Get("Content-Type") |
|
|
accept := c.Request().Header.Get("Accept") |
|
|
if strings.Contains(contentType, "application/json") || !strings.Contains(accept, "text/html") { |
|
|
|
|
|
return c.JSON(http.StatusNotFound, schema.ErrorResponse{ |
|
|
Error: &schema.APIError{Message: "Resource not found", Code: http.StatusNotFound}, |
|
|
}) |
|
|
} else { |
|
|
|
|
|
return c.Render(http.StatusNotFound, "views/404", map[string]interface{}{ |
|
|
"BaseURL": middleware.BaseURL(c), |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
func renderEngine() *TemplateRenderer { |
|
|
|
|
|
tmpl := template.New("").Funcs(sprig.FuncMap()) |
|
|
tmpl = tmpl.Funcs(template.FuncMap{ |
|
|
"MDToHTML": markDowner, |
|
|
}) |
|
|
|
|
|
|
|
|
err := fs.WalkDir(viewsfs, "views", func(path string, d fs.DirEntry, err error) error { |
|
|
if err != nil { |
|
|
return err |
|
|
} |
|
|
if !d.IsDir() && strings.HasSuffix(path, ".html") { |
|
|
data, err := viewsfs.ReadFile(path) |
|
|
if err == nil { |
|
|
|
|
|
templateName := strings.TrimSuffix(path, ".html") |
|
|
_, err := tmpl.New(templateName).Parse(string(data)) |
|
|
if err != nil { |
|
|
|
|
|
tmpl.Parse(string(data)) |
|
|
} |
|
|
} |
|
|
} |
|
|
return nil |
|
|
}) |
|
|
if err != nil { |
|
|
|
|
|
fmt.Printf("Error walking views directory: %v\n", err) |
|
|
} |
|
|
|
|
|
return &TemplateRenderer{ |
|
|
templates: tmpl, |
|
|
} |
|
|
} |
|
|
|
|
|
func markDowner(args ...interface{}) template.HTML { |
|
|
s := blackfriday.MarkdownCommon([]byte(fmt.Sprintf("%s", args...))) |
|
|
return template.HTML(bluemonday.UGCPolicy().Sanitize(string(s))) |
|
|
} |
|
|
|