repos / pico

pico services mono repo
git clone https://github.com/picosh/pico.git

pico / pkg / apps / feeds
Eric Bower  ·  2025-05-25

cli.go

  1package feeds
  2
  3import (
  4	"fmt"
  5	"text/tabwriter"
  6	"time"
  7
  8	"github.com/picosh/pico/pkg/db"
  9	"github.com/picosh/pico/pkg/pssh"
 10	"github.com/picosh/pico/pkg/shared"
 11)
 12
 13func Middleware(dbpool db.DB, cfg *shared.ConfigSite) pssh.SSHServerMiddleware {
 14	return func(next pssh.SSHServerHandler) pssh.SSHServerHandler {
 15		return func(sesh *pssh.SSHServerConnSession) error {
 16			args := sesh.Command()
 17
 18			logger := pssh.GetLogger(sesh)
 19			user := pssh.GetUser(sesh)
 20
 21			if user == nil {
 22				err := fmt.Errorf("user not found")
 23				_, _ = fmt.Fprintln(sesh.Stderr(), err)
 24				return err
 25			}
 26
 27			cmd := "help"
 28			if len(args) > 0 {
 29				cmd = args[0]
 30			}
 31
 32			switch cmd {
 33			case "help":
 34				_, _ = fmt.Fprintf(sesh, "Commands: [help, ls, rm, run]\r\n\r\n")
 35				writer := tabwriter.NewWriter(sesh, 0, 0, 1, ' ', tabwriter.TabIndent)
 36				_, _ = fmt.Fprintln(writer, "Cmd\tDesc")
 37				_, _ = fmt.Fprintf(
 38					writer,
 39					"%s\t%s\r\n",
 40					"help", "this help text",
 41				)
 42				_, _ = fmt.Fprintf(
 43					writer,
 44					"%s\t%s\r\n",
 45					"ls", "list feed digest posts with metadata",
 46				)
 47				_, _ = fmt.Fprintf(
 48					writer,
 49					"%s\t%s\r\n",
 50					"rm {filename}", "removes feed digest post",
 51				)
 52				_, _ = fmt.Fprintf(
 53					writer,
 54					"%s\t%s\r\n",
 55					"run {filename}", "runs the feed digest post immediately, ignoring last digest time validation",
 56				)
 57				return writer.Flush()
 58			case "ls":
 59				posts, err := dbpool.FindPostsForUser(&db.Pager{Page: 0, Num: 1000}, user.ID, "feeds")
 60				if err != nil {
 61					_, _ = fmt.Fprintln(sesh.Stderr(), err)
 62					return err
 63				}
 64
 65				if len(posts.Data) == 0 {
 66					_, _ = fmt.Fprintln(sesh, "no posts found")
 67				}
 68
 69				writer := tabwriter.NewWriter(sesh, 0, 0, 1, ' ', tabwriter.TabIndent)
 70				_, _ = fmt.Fprintln(writer, "Filename\tLast Digest\tNext Digest\tInterval\tFailed Attempts")
 71				for _, post := range posts.Data {
 72					parsed := shared.ListParseText(post.Text)
 73					digestOption := DigestOptionToTime(*post.Data.LastDigest, parsed.DigestInterval)
 74					_, _ = fmt.Fprintf(
 75						writer,
 76						"%s\t%s\t%s\t%s\t%d/10\r\n",
 77						post.Filename,
 78						post.Data.LastDigest.Format(time.RFC3339),
 79						digestOption.Format(time.RFC3339),
 80						parsed.DigestInterval,
 81						post.Data.Attempts,
 82					)
 83				}
 84				return writer.Flush()
 85			case "rm":
 86				filename := args[1]
 87				_, _ = fmt.Fprintf(sesh, "removing digest post %s\r\n", filename)
 88				write := false
 89				if len(args) > 2 {
 90					writeRaw := args[2]
 91					if writeRaw == "--write" {
 92						write = true
 93					}
 94				}
 95
 96				post, err := dbpool.FindPostWithFilename(filename, user.ID, "feeds")
 97				if err != nil {
 98					_, _ = fmt.Fprintln(sesh.Stderr(), err)
 99					return err
100				}
101				if write {
102					err = dbpool.RemovePosts([]string{post.ID})
103					if err != nil {
104						_, _ = fmt.Fprintln(sesh.Stderr(), err)
105					}
106				}
107				_, _ = fmt.Fprintf(sesh, "digest post removed %s\r\n", filename)
108				if !write {
109					_, _ = fmt.Fprintln(sesh, "WARNING: *must* append with `--write` for the changes to persist.")
110				}
111				return err
112			case "run":
113				if len(args) < 2 {
114					err := fmt.Errorf("must provide filename of post to run")
115					_, _ = fmt.Fprintln(sesh.Stderr(), err)
116					return err
117				}
118				filename := args[1]
119				post, err := dbpool.FindPostWithFilename(filename, user.ID, "feeds")
120				if err != nil {
121					_, _ = fmt.Fprintln(sesh.Stderr(), err)
122					return err
123				}
124				_, _ = fmt.Fprintf(sesh, "running feed post: %s\r\n", filename)
125				fetcher := NewFetcher(dbpool, cfg)
126				err = fetcher.RunPost(logger, user, post, true)
127				if err != nil {
128					_, _ = fmt.Fprintln(sesh.Stderr(), err)
129				}
130				return err
131			}
132
133			return next(sesh)
134		}
135	}
136}