repos / pico

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

pico / pkg / apps / feeds
Antonio Mika  ·  2025-03-14

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