Commit bb7b4f2

Eric Bower  ·  2026-01-08 22:13:26 -0500 EST
parent b2aa9b3
feat(pipe): web based rss feed
2 files changed,  +51, -12
+41, -2
......@@ -16,6 +16,7 @@ import (
1616
1717 "github.com/google/uuid"
1818 "github.com/gorilla/websocket"
19+ "github.com/picosh/pico/pkg/db"
1920 "github.com/picosh/pico/pkg/db/postgres"
2021 "github.com/picosh/pico/pkg/shared"
2122 "github.com/picosh/utils/pipe"
......@@ -386,10 +387,48 @@ func handlePipe() http.HandlerFunc {
386387 }
387388 }
388389
389-func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
390+func rssHandler(cfg *shared.ConfigSite, dbpool db.DB) http.HandlerFunc {
391+ return func(w http.ResponseWriter, r *http.Request) {
392+ apiToken, _ := url.PathUnescape(shared.GetField(r, 0))
393+ user, err := dbpool.FindUserByToken(apiToken)
394+ if err != nil {
395+ cfg.Logger.Error(
396+ "could not find user for token",
397+ "err", err.Error(),
398+ "token", apiToken,
399+ )
400+ http.Error(w, "invalid token", http.StatusNotFound)
401+ return
402+ }
403+ rss, err := MonitorRss(dbpool, user, cfg.Domain)
404+ if err != nil {
405+ cfg.Logger.Error(
406+ "error generating monitor rss feed",
407+ "err", err,
408+ "token", apiToken,
409+ )
410+ http.Error(w, "error generating monitor rss feed", http.StatusInternalServerError)
411+ return
412+ }
413+
414+ _, err = w.Write([]byte(rss))
415+ if err != nil {
416+ cfg.Logger.Error(
417+ "error with rss response writer",
418+ "err", err,
419+ "token", apiToken,
420+ )
421+ http.Error(w, "error generating monitor rss feederror with rss response writer", http.StatusInternalServerError)
422+ return
423+ }
424+ }
425+}
426+
427+func createMainRoutes(staticRoutes []shared.Route, cfg *shared.ConfigSite, dbpool db.DB) []shared.Route {
390428 routes := []shared.Route{
391429 shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
392430 shared.NewRoute("GET", "/check", shared.CheckHandler),
431+ shared.NewRoute("GET", "/rss/(.+)", rssHandler(cfg, dbpool)),
393432 shared.NewRoute("GET", "/_metrics", promhttp.Handler().ServeHTTP),
394433 }
395434
......@@ -428,7 +467,7 @@ func StartApiServer() {
428467 staticRoutes = shared.CreatePProfRoutes(staticRoutes)
429468 }
430469
431- mainRoutes := createMainRoutes(staticRoutes)
470+ mainRoutes := createMainRoutes(staticRoutes, cfg, db)
432471 subdomainRoutes := staticRoutes
433472
434473 info := shared.NewPicoPipeClient()
+10, -10
......@@ -93,7 +93,8 @@ func Middleware(handler *CliHandler) pssh.SSHServerMiddleware {
9393 }
9494 return next(sesh)
9595 case "rss":
96- err := handler.rss(cliCmd, user)
96+ rss, err := MonitorRss(handler.DBPool, user, handler.Cfg.Domain)
97+ _, _ = fmt.Fprintln(sesh, rss)
9798 if err != nil {
9899 logger.Error("rss cmd", "err", err)
99100 sesh.Fatal(err)
......@@ -542,20 +543,20 @@ func parseDuration(s string) (time.Duration, error) {
542543 return time.ParseDuration(s)
543544 }
544545
545-func (handler *CliHandler) rss(cmd *CliCmd, user *db.User) error {
546+func MonitorRss(dbpool db.DB, user *db.User, domain string) (string, error) {
546547 if user == nil {
547- return fmt.Errorf("access denied")
548+ return "", fmt.Errorf("access denied")
548549 }
549550
550- monitors, err := handler.DBPool.FindPipeMonitorsByUser(user.ID)
551+ monitors, err := dbpool.FindPipeMonitorsByUser(user.ID)
551552 if err != nil {
552- return fmt.Errorf("failed to fetch monitors: %w", err)
553+ return "", fmt.Errorf("failed to fetch monitors: %w", err)
553554 }
554555
555556 now := time.Now()
556557 feed := &feeds.Feed{
557558 Title: fmt.Sprintf("Pipe Monitors for %s", user.Name),
558- Link: &feeds.Link{Href: fmt.Sprintf("https://%s", handler.Cfg.Domain)},
559+ Link: &feeds.Link{Href: fmt.Sprintf("https://%s", domain)},
559560 Description: "Alerts for pipe monitor status changes",
560561 Author: &feeds.Author{Name: user.Name},
561562 Created: now,
......@@ -567,7 +568,7 @@ func (handler *CliHandler) rss(cmd *CliCmd, user *db.User) error {
567568 item := &feeds.Item{
568569 Id: fmt.Sprintf("%s-%s-%d", user.ID, m.Topic, now.Unix()),
569570 Title: fmt.Sprintf("ALERT: %s is unhealthy", m.Topic),
570- Link: &feeds.Link{Href: fmt.Sprintf("https://%s", handler.Cfg.Domain)},
571+ Link: &feeds.Link{Href: fmt.Sprintf("https://%s", domain)},
571572 Description: err.Error(),
572573 Created: now,
573574 Updated: now,
......@@ -580,11 +581,10 @@ func (handler *CliHandler) rss(cmd *CliCmd, user *db.User) error {
580581
581582 rss, err := feed.ToRss()
582583 if err != nil {
583- return fmt.Errorf("failed to generate RSS: %w", err)
584+ return "", fmt.Errorf("failed to generate RSS: %w", err)
584585 }
585586
586- _, _ = fmt.Fprint(cmd.sesh, rss)
587- return nil
587+ return rss, nil
588588 }
589589
590590 func (handler *CliHandler) pub(cmd *CliCmd, topic string, clientID string) error {