- commit
- ccc0df5
- parent
- 4294df9
- author
- Antonio Mika
- date
- 2023-11-11 15:54:13 +0000 UTC
Add feature flag for advanced pastes management
9 files changed,
+90,
-16
+2,
-1
1@@ -10,7 +10,8 @@
2 "request": "launch",
3 "mode": "auto",
4 "program": "${workspaceFolder}/cmd/${input:service}/${input:type}/main.go",
5- "envFile": "${workspaceFolder}/.env"
6+ "envFile": "${workspaceFolder}/.env",
7+ "cwd": "${workspaceFolder}"
8 }
9 ],
10 "inputs": [
+2,
-1
1@@ -242,7 +242,7 @@ const (
2 sqlUpdatePost = `
3 UPDATE posts
4 SET slug = $1, title = $2, text = $3, description = $4, updated_at = $5, publish_at = $6,
5- file_size = $7, shasum = $8, data = $9, hidden = $11
6+ file_size = $7, shasum = $8, data = $9, hidden = $11, expires_at = $12
7 WHERE id = $10`
8 sqlUpdateUserName = `UPDATE app_users SET name = $1 WHERE id = $2`
9 sqlIncrementViews = `UPDATE posts SET views = views + 1 WHERE id = $1 RETURNING views`
10@@ -753,6 +753,7 @@ func (me *PsqlDB) UpdatePost(post *db.Post) (*db.Post, error) {
11 post.Data,
12 post.ID,
13 post.Hidden,
14+ post.ExpiresAt,
15 )
16 if err != nil {
17 return nil, err
+3,
-2
1@@ -7,6 +7,7 @@ import (
2
3 "slices"
4
5+ "github.com/charmbracelet/ssh"
6 "github.com/picosh/pico/db"
7 "github.com/picosh/pico/filehandlers"
8 "github.com/picosh/pico/imgs"
9@@ -18,7 +19,7 @@ type FeedHooks struct {
10 Db db.DB
11 }
12
13-func (p *FeedHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error) {
14+func (p *FeedHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) {
15 if !shared.IsTextFile(string(data.Text)) {
16 err := fmt.Errorf(
17 "WARNING: (%s) invalid file must be plain text (utf-8), skipping",
18@@ -40,7 +41,7 @@ func (p *FeedHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error)
19 return true, nil
20 }
21
22-func (p *FeedHooks) FileMeta(data *filehandlers.PostMetaData) error {
23+func (p *FeedHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) error {
24 linkify := imgs.NewImgsLinkify(data.Username)
25 parsedText := shared.ListParseText(string(data.Text), linkify)
26
+5,
-4
1@@ -40,8 +40,8 @@ type PostMetaData struct {
2 }
3
4 type ScpFileHooks interface {
5- FileValidate(data *PostMetaData) (bool, error)
6- FileMeta(data *PostMetaData) error
7+ FileValidate(s ssh.Session, data *PostMetaData) (bool, error)
8+ FileMeta(s ssh.Session, data *PostMetaData) error
9 }
10
11 type ScpUploadHandler struct {
12@@ -209,7 +209,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string,
13 FileEntry: entry,
14 }
15
16- valid, err := h.Hooks.FileValidate(&metadata)
17+ valid, err := h.Hooks.FileValidate(s, &metadata)
18 if !valid {
19 logger.Error(err)
20 return "", err
21@@ -226,7 +226,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string,
22 metadata.Post.PublishAt = post.PublishAt
23 }
24
25- err = h.Hooks.FileMeta(&metadata)
26+ err = h.Hooks.FileMeta(s, &metadata)
27 if err != nil {
28 logger.Error(err)
29 return "", err
30@@ -318,6 +318,7 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string,
31 Text: metadata.Text,
32 Title: metadata.Title,
33 Hidden: metadata.Hidden,
34+ ExpiresAt: metadata.ExpiresAt,
35 UpdatedAt: &modTime,
36 }
37 _, err = h.DBPool.UpdatePost(&updatePost)
+3,
-2
1@@ -6,6 +6,7 @@ import (
2
3 "slices"
4
5+ "github.com/charmbracelet/ssh"
6 "github.com/picosh/pico/db"
7 "github.com/picosh/pico/filehandlers"
8 "github.com/picosh/pico/imgs"
9@@ -17,7 +18,7 @@ type ListHooks struct {
10 Db db.DB
11 }
12
13-func (p *ListHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error) {
14+func (p *ListHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) {
15 if !shared.IsTextFile(string(data.Text)) {
16 err := fmt.Errorf(
17 "WARNING: (%s) invalid file must be plain text (utf-8), skipping",
18@@ -39,7 +40,7 @@ func (p *ListHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error)
19 return true, nil
20 }
21
22-func (p *ListHooks) FileMeta(data *filehandlers.PostMetaData) error {
23+func (p *ListHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) error {
24 linkify := imgs.NewImgsLinkify(data.Username)
25 parsedText := shared.ListParseText(string(data.Text), linkify)
26
+1,
-1
1@@ -34,6 +34,6 @@ func CronDeleteExpiredPosts(cfg *shared.ConfigSite, dbpool db.DB) {
2 if err != nil {
3 cfg.Logger.Error(err)
4 }
5- time.Sleep(1 * time.Hour)
6+ time.Sleep(1 * time.Minute)
7 }
8 }
+61,
-2
1@@ -2,8 +2,12 @@ package pastes
2
3 import (
4 "fmt"
5+ "strconv"
6+ "strings"
7 "time"
8
9+ "github.com/araddon/dateparse"
10+ "github.com/charmbracelet/ssh"
11 "github.com/picosh/pico/db"
12 "github.com/picosh/pico/filehandlers"
13 "github.com/picosh/pico/shared"
14@@ -16,7 +20,7 @@ type FileHooks struct {
15 Db db.DB
16 }
17
18-func (p *FileHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error) {
19+func (p *FileHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) {
20 if !shared.IsTextFile(string(data.Text)) {
21 err := fmt.Errorf(
22 "WARNING: (%s) invalid file must be plain text (utf-8), skipping",
23@@ -28,14 +32,69 @@ func (p *FileHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error)
24 return true, nil
25 }
26
27-func (p *FileHooks) FileMeta(data *filehandlers.PostMetaData) error {
28+func (p *FileHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) error {
29 data.Title = shared.ToUpper(data.Slug)
30 // we want the slug to be the filename for pastes
31 data.Slug = data.Filename
32+
33 if data.Post.ExpiresAt == nil || data.Post.ExpiresAt.IsZero() {
34 // mark posts for deletion a X days after creation
35 expiresAt := time.Now().AddDate(0, 0, DEFAULT_EXPIRES_AT)
36 data.ExpiresAt = &expiresAt
37 }
38+
39+ if p.Db.HasFeatureForUser(data.User.ID, "pastes-advanced") {
40+ var hidden bool
41+ var expiresFound bool
42+ var expires *time.Time
43+
44+ cmd := s.Command()
45+
46+ for _, arg := range cmd {
47+ if strings.Contains(arg, "=") {
48+ splitArg := strings.Split(arg, "=")
49+ if len(splitArg) != 2 {
50+ continue
51+ }
52+
53+ switch splitArg[0] {
54+ case "hidden":
55+ val, err := strconv.ParseBool(splitArg[1])
56+ if err != nil {
57+ continue
58+ }
59+
60+ hidden = val
61+ case "expires":
62+ val, err := strconv.ParseBool(splitArg[1])
63+ if err == nil {
64+ expiresFound = !val
65+ continue
66+ }
67+
68+ duration, err := time.ParseDuration(splitArg[1])
69+ if err == nil {
70+ expiresFound = true
71+ expireTime := time.Now().Add(duration)
72+ expires = &expireTime
73+ continue
74+ }
75+
76+ expireTime, err := dateparse.ParseStrict(splitArg[1])
77+ if err == nil {
78+ expiresFound = true
79+ expires = &expireTime
80+ }
81+ }
82+ }
83+ }
84+
85+ data.Hidden = hidden
86+
87+ if expiresFound {
88+ data.ExpiresAt = expires
89+ }
90+ }
91+
92 return nil
93 }
+3,
-2
1@@ -6,6 +6,7 @@ import (
2
3 "slices"
4
5+ "github.com/charmbracelet/ssh"
6 "github.com/picosh/pico/db"
7 "github.com/picosh/pico/filehandlers"
8 "github.com/picosh/pico/imgs"
9@@ -17,7 +18,7 @@ type MarkdownHooks struct {
10 Db db.DB
11 }
12
13-func (p *MarkdownHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error) {
14+func (p *MarkdownHooks) FileValidate(s ssh.Session, data *filehandlers.PostMetaData) (bool, error) {
15 if !shared.IsTextFile(data.Text) {
16 err := fmt.Errorf(
17 "WARNING: (%s) invalid file must be plain text (utf-8), skipping",
18@@ -46,7 +47,7 @@ func (p *MarkdownHooks) FileValidate(data *filehandlers.PostMetaData) (bool, err
19 return true, nil
20 }
21
22-func (p *MarkdownHooks) FileMeta(data *filehandlers.PostMetaData) error {
23+func (p *MarkdownHooks) FileMeta(s ssh.Session, data *filehandlers.PostMetaData) error {
24 linkify := imgs.NewImgsLinkify("")
25 parsedText, err := shared.ParseText(data.Text, linkify)
26 // we return nil here because we don't want the file upload to fail
+10,
-1
1@@ -22,7 +22,16 @@ func Middleware(writeHandler utils.CopyFromClientHandler, ext string) wish.Middl
2 return
3 }
4
5- name := strings.TrimSpace(strings.Join(session.Command(), " "))
6+ cmd := session.Command()
7+
8+ name := ""
9+ if len(cmd) > 0 {
10+ name = strings.TrimSpace(cmd[0])
11+ if strings.Contains(name, "=") {
12+ name = ""
13+ }
14+ }
15+
16 postTime := time.Now()
17
18 if name == "" {