From 68b7443de9e3eea9a3197c805904ee32ee0cdd89 Mon Sep 17 00:00:00 2001 From: Jordan Hotmann Date: Fri, 17 Nov 2023 11:43:50 -0700 Subject: [PATCH] HATS home and status pages --- go.mod | 1 + go.sum | 2 ++ internal/api/api.go | 43 +++++++++++++++++++++++++++++++------------ main.go | 6 +++++- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index afacbb6..bef268f 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/go-co-op/gocron v1.35.2 github.com/go-resty/resty/v2 v2.9.1 github.com/golang/protobuf v1.5.3 // indirect + github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd github.com/klauspost/compress v1.17.0 // indirect github.com/nats-io/nats-server/v2 v2.10.2 // indirect github.com/nats-io/nkeys v0.4.5 // indirect diff --git a/go.sum b/go.sum index a755266..7de62cc 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/go-resty/resty/v2 v2.9.1/go.mod h1:4/GYJVjh9nhkhGR6AUNW3XhpDYNUr+Uvy9 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd h1:PppHBegd3uPZ3Y/Iax/2mlCFJm1w4Qf/zP1MdW4ju2o= +github.com/gomarkdown/markdown v0.0.0-20231115200524-a660076da3fd/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= diff --git a/internal/api/api.go b/internal/api/api.go index d3b1211..b15e4b0 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -17,6 +17,9 @@ import ( "github.com/go-chi/chi/middleware" "github.com/go-chi/chi/v5" "github.com/go-chi/render" + "github.com/gomarkdown/markdown" + "github.com/gomarkdown/markdown/html" + "github.com/gomarkdown/markdown/parser" ) var ( @@ -24,14 +27,21 @@ var ( logger *slog.Logger server http.Server haClient *homeassistant.RestClient + homepage string ) const ( HA_STATE_PREFIX = "homeassistant.states" ) -func Listen(parentLogger *slog.Logger) { +func Listen(parentLogger *slog.Logger, readme []byte) { logger = parentLogger + + // render readme to HTML + p := parser.NewWithExtensions(parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock) + doc := p.Parse(readme) + homepage = string(markdown.Render(doc, html.NewRenderer(html.RendererOptions{Flags: html.CommonFlags | html.HrefTargetBlank}))) + cfg = config.FromEnvironment() haClient = homeassistant.NewRestClient(cfg.GetHomeAssistantBaseUrl(), cfg.HomeAssistantToken) router := chi.NewRouter() @@ -41,22 +51,31 @@ func Listen(parentLogger *slog.Logger) { router.Use(loggerMiddleware) router.Use(middleware.Recoverer) router.Use(middleware.Timeout(60 * time.Second)) - router.Use(tokenAuthMiddleware) - router.Get(`/api/state/{entityId}`, getEntityStateHandler) - router.Post("/api/state/{entityId}/{service}", setEntityStateHandler) + router.Get("/", func(w http.ResponseWriter, r *http.Request) { + render.HTML(w, r, homepage) + }) + router.Get("/status", func(w http.ResponseWriter, r *http.Request) { + render.PlainText(w, r, "OK") + }) - router.Get("/api/timer/{timerName}", getTimerHandler) - router.Post("/api/timer/{timerName}", startTimerHandler) - router.Delete("/api/timer/{timerName}", deleteTimerHandler) + router.Route("/api", func(r chi.Router) { + r.Use(tokenAuthMiddleware) + r.Get(`/api/state/{entityId}`, getEntityStateHandler) + r.Post("/api/state/{entityId}/{service}", setEntityStateHandler) - router.Get("/api/schedule/{scheduleName}", getScheduleHandler) - router.Post("/api/schedule/{scheduleName}", createScheduleHandler) - router.Delete("/api/schedule/{scheduleName}", deleteScheduleHandler) + r.Get("/api/timer/{timerName}", getTimerHandler) + r.Post("/api/timer/{timerName}", startTimerHandler) + r.Delete("/api/timer/{timerName}", deleteTimerHandler) - router.Post("/api/ntfy", postNtfyHandler) + r.Get("/api/schedule/{scheduleName}", getScheduleHandler) + r.Post("/api/schedule/{scheduleName}", createScheduleHandler) + r.Delete("/api/schedule/{scheduleName}", deleteScheduleHandler) - router.Post("/api/command/{commandName}", postCommandHandler) + r.Post("/api/ntfy", postNtfyHandler) + + r.Post("/api/command/{commandName}", postCommandHandler) + }) server = http.Server{ Addr: ":8888", diff --git a/main.go b/main.go index 3a76373..dc5629b 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "context" + _ "embed" "log/slog" "os" "os/signal" @@ -13,6 +14,9 @@ import ( "code.jhot.me/jhot/hats/pkg/config" ) +//go:embed README.md +var readme []byte + var ( interrupt chan os.Signal cfg *config.HatsConfig @@ -56,7 +60,7 @@ func main() { ntfy.InitClient(cfg) - api.Listen(logger) + api.Listen(logger, readme) defer api.Close() for sig := range interrupt {