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}