Antonio Mika
·
08 Oct 24
img.go
1package uploadimgs
2
3import (
4 "bytes"
5 "fmt"
6 "strings"
7 "time"
8
9 "github.com/charmbracelet/ssh"
10 "github.com/picosh/pico/db"
11 "github.com/picosh/pico/shared"
12 sendutils "github.com/picosh/send/utils"
13 "github.com/picosh/utils"
14)
15
16func (h *UploadImgHandler) validateImg(data *PostMetaData) (bool, error) {
17 totalFileSize, err := h.DBPool.FindTotalSizeForUser(data.User.ID)
18 if err != nil {
19 return false, err
20 }
21
22 fileMax := data.FeatureFlag.Data.FileMax
23 if int64(data.FileSize) > fileMax {
24 return false, fmt.Errorf("ERROR: file (%s) has exceeded maximum file size (%d bytes)", data.Filename, fileMax)
25 }
26
27 storageMax := data.FeatureFlag.Data.StorageMax
28 if uint64(totalFileSize+data.FileSize) > storageMax {
29 return false, fmt.Errorf("ERROR: user (%s) has exceeded (%d bytes) max (%d bytes)", data.User.Name, totalFileSize, storageMax)
30 }
31
32 if !utils.IsExtAllowed(data.Filepath, h.Cfg.AllowedExt) {
33 extStr := strings.Join(h.Cfg.AllowedExt, ",")
34 err := fmt.Errorf(
35 "ERROR: (%s) invalid file, format must be (%s), skipping",
36 data.Filename,
37 extStr,
38 )
39 return false, err
40 }
41
42 return true, nil
43}
44
45func (h *UploadImgHandler) metaImg(data *PostMetaData) error {
46 // if the file is empty that means we should delete it
47 // so we can skip all the meta info
48 if data.FileSize == 0 {
49 return nil
50 }
51
52 bucket, err := h.Storage.UpsertBucket(data.User.ID)
53 if err != nil {
54 return err
55 }
56
57 reader := bytes.NewReader([]byte(data.Text))
58
59 fname, _, err := h.Storage.PutObject(
60 bucket,
61 data.Filename,
62 sendutils.NopReaderAtCloser(reader),
63 &sendutils.FileEntry{},
64 )
65 if err != nil {
66 return err
67 }
68
69 data.Data = db.PostData{
70 ImgPath: fname,
71 }
72
73 data.Text = ""
74
75 return nil
76}
77
78func (h *UploadImgHandler) writeImg(s ssh.Session, data *PostMetaData) error {
79 valid, err := h.validateImg(data)
80 if !valid {
81 return err
82 }
83 user, err := shared.GetUser(s.Context())
84 if err != nil {
85 return err
86 }
87
88 logger := h.Cfg.Logger
89 logger = shared.LoggerWithUser(logger, user)
90
91 err = h.metaImg(data)
92 if err != nil {
93 logger.Error("could not get meta for img", "err", err.Error())
94 return err
95 }
96
97 modTime := time.Now()
98
99 if data.Mtime > 0 {
100 modTime = time.Unix(data.Mtime, 0)
101 }
102
103 logger = logger.With(
104 "filename", data.Filename,
105 )
106
107 if data.Cur == nil {
108 logger.Info("file not found, adding record")
109 insertPost := db.Post{
110 UserID: user.ID,
111 Space: Space,
112
113 Data: data.Data,
114 Description: data.Description,
115 Filename: data.Filename,
116 FileSize: data.FileSize,
117 Hidden: data.Hidden,
118 MimeType: data.MimeType,
119 PublishAt: data.PublishAt,
120 Shasum: data.Shasum,
121 Slug: data.Slug,
122 Text: data.Text,
123 Title: data.Title,
124 UpdatedAt: &modTime,
125 }
126 _, err := h.DBPool.InsertPost(&insertPost)
127 if err != nil {
128 logger.Error("post could not create", "err", err.Error())
129 return fmt.Errorf("error for %s: %v", data.Filename, err)
130 }
131
132 if len(data.Tags) > 0 {
133 logger.Info(
134 "found post tags, replacing with old tags",
135 "tags", strings.Join(data.Tags, ","),
136 )
137 err = h.DBPool.ReplaceTagsForPost(data.Tags, data.Post.ID)
138 if err != nil {
139 logger.Error("post could not replace tags", "err", err.Error())
140 return fmt.Errorf("error for %s: %v", data.Filename, err)
141 }
142 }
143 } else {
144 if data.Shasum == data.Cur.Shasum && modTime.Equal(*data.Cur.UpdatedAt) {
145 logger.Info("image found, but image is identical, skipping")
146 return nil
147 }
148
149 logger.Info("file found, updating record")
150
151 updatePost := db.Post{
152 ID: data.Cur.ID,
153
154 Data: data.Data,
155 FileSize: data.FileSize,
156 Description: data.Description,
157 PublishAt: data.PublishAt,
158 Slug: data.Slug,
159 Shasum: data.Shasum,
160 Text: data.Text,
161 Title: data.Title,
162 Hidden: data.Hidden,
163 UpdatedAt: &modTime,
164 }
165 _, err = h.DBPool.UpdatePost(&updatePost)
166 if err != nil {
167 logger.Error("post could not update", "err", err.Error())
168 return fmt.Errorf("error for %s: %v", data.Filename, err)
169 }
170
171 logger.Info(
172 "found post tags, replacing with old tags",
173 "tags", strings.Join(data.Tags, ","),
174 )
175 err = h.DBPool.ReplaceTagsForPost(data.Tags, data.Cur.ID)
176 if err != nil {
177 logger.Error("post could not replace tags", "err", err.Error())
178 return fmt.Errorf("error for %s: %v", data.Filename, err)
179 }
180 }
181
182 return nil
183}