2025-08-05 03:56:23 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2025-08-19 17:12:36 +02:00
|
|
|
"io/fs"
|
2025-08-05 03:56:23 +02:00
|
|
|
"net/http"
|
2025-08-10 16:38:02 +02:00
|
|
|
"path/filepath"
|
|
|
|
|
"strings"
|
2025-08-05 03:56:23 +02:00
|
|
|
|
2025-08-29 22:55:41 +02:00
|
|
|
"github.com/coalaura/plain"
|
2025-08-05 03:56:23 +02:00
|
|
|
"github.com/go-chi/chi/v5"
|
|
|
|
|
"github.com/go-chi/chi/v5/middleware"
|
|
|
|
|
)
|
|
|
|
|
|
2025-08-18 05:05:07 +02:00
|
|
|
var Version = "dev"
|
2025-08-11 01:38:16 +02:00
|
|
|
|
2025-08-29 22:55:41 +02:00
|
|
|
var log = plain.New(plain.WithDate(plain.RFC3339Local))
|
2025-08-05 03:56:23 +02:00
|
|
|
|
|
|
|
|
func main() {
|
2025-08-19 17:12:36 +02:00
|
|
|
icons, err := LoadIcons()
|
2025-08-29 22:55:41 +02:00
|
|
|
log.MustFail(err)
|
2025-08-19 17:12:36 +02:00
|
|
|
|
2025-08-05 03:56:23 +02:00
|
|
|
models, err := LoadModels()
|
2025-08-29 22:55:41 +02:00
|
|
|
log.MustFail(err)
|
2025-08-05 03:56:23 +02:00
|
|
|
|
2025-08-29 22:55:41 +02:00
|
|
|
log.Println("Preparing router...")
|
2025-08-05 03:56:23 +02:00
|
|
|
r := chi.NewRouter()
|
|
|
|
|
|
|
|
|
|
r.Use(middleware.Recoverer)
|
2025-08-29 22:55:41 +02:00
|
|
|
r.Use(log.Middleware())
|
2025-08-05 03:56:23 +02:00
|
|
|
|
|
|
|
|
fs := http.FileServer(http.Dir("./static"))
|
2025-08-10 16:38:02 +02:00
|
|
|
r.Handle("/*", cache(http.StripPrefix("/", fs)))
|
2025-08-05 03:56:23 +02:00
|
|
|
|
2025-08-11 01:38:16 +02:00
|
|
|
r.Get("/-/data", func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
RespondJson(w, http.StatusOK, map[string]any{
|
2025-08-16 17:18:48 +02:00
|
|
|
"authentication": env.Authentication.Enabled,
|
|
|
|
|
"authenticated": IsAuthenticated(r),
|
|
|
|
|
"search": env.Tokens.Exa != "",
|
2025-08-19 17:12:36 +02:00
|
|
|
"icons": icons,
|
2025-08-16 17:18:48 +02:00
|
|
|
"models": models,
|
2025-08-18 04:46:17 +02:00
|
|
|
"prompts": Prompts,
|
2025-08-16 17:18:48 +02:00
|
|
|
"version": Version,
|
2025-08-11 01:38:16 +02:00
|
|
|
})
|
2025-08-05 03:56:23 +02:00
|
|
|
})
|
|
|
|
|
|
2025-08-16 17:18:48 +02:00
|
|
|
r.Post("/-/auth", HandleAuthentication)
|
|
|
|
|
|
|
|
|
|
r.Group(func(gr chi.Router) {
|
|
|
|
|
gr.Use(Authenticate)
|
|
|
|
|
|
|
|
|
|
gr.Get("/-/stats/{id}", HandleStats)
|
2025-08-25 22:45:03 +02:00
|
|
|
gr.Post("/-/title", HandleTitle)
|
2025-08-16 17:18:48 +02:00
|
|
|
gr.Post("/-/chat", HandleChat)
|
|
|
|
|
})
|
2025-08-05 03:56:23 +02:00
|
|
|
|
2025-08-29 22:55:41 +02:00
|
|
|
log.Println("Listening at http://localhost:3443/")
|
2025-08-05 03:56:23 +02:00
|
|
|
http.ListenAndServe(":3443", r)
|
|
|
|
|
}
|
2025-08-10 16:38:02 +02:00
|
|
|
|
|
|
|
|
func cache(next http.Handler) http.Handler {
|
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
path := strings.ToLower(r.URL.Path)
|
|
|
|
|
ext := filepath.Ext(path)
|
|
|
|
|
|
2025-08-23 15:19:43 +02:00
|
|
|
if ext == ".png" || ext == ".svg" || ext == ".ttf" || strings.HasSuffix(path, ".min.js") || strings.HasSuffix(path, ".min.css") {
|
2025-08-10 16:38:02 +02:00
|
|
|
w.Header().Set("Cache-Control", "public, max-age=3024000, immutable")
|
2025-08-23 15:19:43 +02:00
|
|
|
} else if env.Debug {
|
|
|
|
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
2025-08-10 16:38:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
|
})
|
|
|
|
|
}
|
2025-08-19 17:12:36 +02:00
|
|
|
|
|
|
|
|
func LoadIcons() ([]string, error) {
|
|
|
|
|
var icons []string
|
|
|
|
|
|
|
|
|
|
directory := filepath.Join("static", "css", "icons")
|
|
|
|
|
|
|
|
|
|
err := filepath.Walk(directory, func(path string, info fs.FileInfo, err error) error {
|
|
|
|
|
if err != nil || info.IsDir() {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if strings.HasSuffix(path, ".svg") {
|
|
|
|
|
rel, err := filepath.Rel(directory, path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
icons = append(icons, filepath.ToSlash(rel))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return icons, nil
|
|
|
|
|
}
|