- commit
- e1aaa8f
- parent
- d09a5d8
- author
- Antonio Mika
- date
- 2022-09-01 01:18:36 +0000 UTC
Add the ability to download images and fix sftp uploads
7 files changed,
+114,
-20
+69,
-2
1@@ -7,6 +7,7 @@ import (
2 "net/http"
3 "os"
4 "path"
5+ "strings"
6 "time"
7
8 "git.sr.ht/~erock/pico/db"
9@@ -64,11 +65,77 @@ func (h *UploadImgHandler) removePost(data *PostMetaData) error {
10 }
11
12 func (h *UploadImgHandler) Read(s ssh.Session, filename string) (os.FileInfo, io.ReaderAt, error) {
13- return nil, nil, nil
14+ cleanFilename := strings.ReplaceAll(filename, "/", "")
15+
16+ if cleanFilename == "" || cleanFilename == "." {
17+ return nil, nil, os.ErrNotExist
18+ }
19+
20+ post, err := h.DBPool.FindPostWithFilename(cleanFilename, h.User.ID, h.Cfg.Space)
21+ if err != nil {
22+ return nil, nil, err
23+ }
24+
25+ fileInfo := &utils.VirtualFile{
26+ FName: post.Filename,
27+ FIsDir: false,
28+ FSize: int64(post.FileSize),
29+ FModTime: *post.UpdatedAt,
30+ }
31+
32+ bucket, err := h.Storage.GetBucket(h.User.ID)
33+ if err != nil {
34+ return nil, nil, err
35+ }
36+
37+ contents, err := h.Storage.GetFile(bucket, post.Filename)
38+ if err != nil {
39+ return nil, nil, err
40+ }
41+
42+ return fileInfo, contents, nil
43 }
44
45 func (h *UploadImgHandler) List(s ssh.Session, filename string) ([]os.FileInfo, error) {
46- return nil, nil
47+ var fileList []os.FileInfo
48+ cleanFilename := strings.ReplaceAll(filename, "/", "")
49+
50+ var err error
51+ var post *db.Post
52+ var posts []*db.Post
53+
54+ if cleanFilename == "" || cleanFilename == "." {
55+ name := cleanFilename
56+ if name == "" {
57+ name = "/"
58+ }
59+
60+ fileList = append(fileList, &utils.VirtualFile{
61+ FName: name,
62+ FIsDir: true,
63+ })
64+
65+ posts, err = h.DBPool.FindAllPostsForUser(h.User.ID, h.Cfg.Space)
66+ } else {
67+ post, err = h.DBPool.FindPostWithFilename(cleanFilename, h.User.ID, h.Cfg.Space)
68+
69+ posts = append(posts, post)
70+ }
71+
72+ if err != nil {
73+ return nil, err
74+ }
75+
76+ for _, post := range posts {
77+ fileList = append(fileList, &utils.VirtualFile{
78+ FName: post.Filename,
79+ FIsDir: false,
80+ FSize: int64(post.FileSize),
81+ FModTime: *post.UpdatedAt,
82+ })
83+ }
84+
85+ return fileList, nil
86 }
87
88 func (h *UploadImgHandler) Validate(s ssh.Session) error {
+2,
-2
1@@ -3,10 +3,10 @@ package uploadimgs
2 import (
3 "bytes"
4 "fmt"
5- "io"
6 "strings"
7
8 "git.sr.ht/~erock/pico/db"
9+ "git.sr.ht/~erock/pico/imgs/storage"
10 "git.sr.ht/~erock/pico/shared"
11 )
12
13@@ -42,7 +42,7 @@ func (h *UploadImgHandler) metaImg(data *PostMetaData) error {
14 if err != nil {
15 return err
16 }
17- fname, err := h.Storage.PutFile(bucket, data.Filename, io.NopCloser(bytes.NewReader([]byte(data.Text))))
18+ fname, err := h.Storage.PutFile(bucket, data.Filename, storage.NopReaderAtCloser(bytes.NewReader([]byte(data.Text))))
19 if err != nil {
20 return err
21 }
M
go.mod
+3,
-2
1@@ -7,13 +7,14 @@ go 1.19
2
3 require (
4 github.com/alecthomas/chroma v0.10.0
5- github.com/antoniomika/go-rsync-receiver v0.0.0-20220825051444-e2df2a87b439
6+ github.com/antoniomika/go-rsync-receiver v0.0.0-20220901010427-e6494124f0c8
7 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
8 github.com/charmbracelet/bubbles v0.13.0
9 github.com/charmbracelet/bubbletea v0.22.1
10 github.com/charmbracelet/lipgloss v0.5.0
11 github.com/charmbracelet/promwish v0.2.0
12 github.com/charmbracelet/wish v0.5.0
13+ github.com/disintegration/imaging v1.6.2
14 github.com/gliderlabs/ssh v0.3.4
15 github.com/gorilla/feeds v1.1.1
16 github.com/kolesa-team/go-webp v1.0.1
17@@ -22,7 +23,6 @@ require (
18 github.com/microcosm-cc/bluemonday v1.0.19
19 github.com/minio/minio-go/v7 v7.0.35
20 github.com/muesli/reflow v0.3.0
21- github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
22 github.com/pkg/sftp v1.13.5
23 github.com/scottleedavis/go-exif-remove v0.0.0-20190908021517-58bdbaac8636
24 github.com/yuin/goldmark v1.4.13
25@@ -88,6 +88,7 @@ require (
26 github.com/sirupsen/logrus v1.9.0 // indirect
27 go.uber.org/atomic v1.10.0 // indirect
28 go.uber.org/multierr v1.8.0 // indirect
29+ golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
30 golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect
31 golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
32 golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
M
go.sum
+7,
-5
1@@ -44,8 +44,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
2 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
3 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
4 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
5-github.com/antoniomika/go-rsync-receiver v0.0.0-20220825051444-e2df2a87b439 h1:5AjhKkEyKSn81jZXXSX/Mob3hLNUfP4Dyo49vyITQQI=
6-github.com/antoniomika/go-rsync-receiver v0.0.0-20220825051444-e2df2a87b439/go.mod h1:zmqePVIo1hp+WEKxERLLGHJBDOr8/z/T4eFqXgWIw1w=
7+github.com/antoniomika/go-rsync-receiver v0.0.0-20220901010427-e6494124f0c8 h1:gR27C6N8s5b+ciBRymi0zhUx8TylKFO755z6yrBuMiI=
8+github.com/antoniomika/go-rsync-receiver v0.0.0-20220901010427-e6494124f0c8/go.mod h1:zmqePVIo1hp+WEKxERLLGHJBDOr8/z/T4eFqXgWIw1w=
9 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
10 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
11 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
12@@ -88,6 +88,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
13 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
14 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
15 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
16+github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
17+github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
18 github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
19 github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
20 github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
21@@ -302,8 +304,6 @@ github.com/muesli/termenv v0.12.0 h1:KuQRUE3PgxRFWhq4gHvZtPSLCGDqM5q/cYr1pZ39ytc
22 github.com/muesli/termenv v0.12.0/go.mod h1:WCCv32tusQ/EEZ5S8oUIIrC/nIuBcxCVqlN4Xfkv+7A=
23 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
24 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
25-github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
26-github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
27 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
28 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
29 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
30@@ -409,8 +409,10 @@ golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txw
31 golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
32 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
33 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
34-golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
35+golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
36 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
37+golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 h1:/eM0PCrQI2xd471rI+snWuu251/+/jpBpZqir2mPdnU=
38+golang.org/x/image v0.0.0-20220722155232-062f8c9fd539/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
39 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
40 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
41 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+2,
-2
1@@ -21,10 +21,10 @@ import (
2 "git.sr.ht/~erock/pico/db/postgres"
3 "git.sr.ht/~erock/pico/imgs/storage"
4 "git.sr.ht/~erock/pico/shared"
5+ "github.com/disintegration/imaging"
6 "github.com/gorilla/feeds"
7 "github.com/kolesa-team/go-webp/encoder"
8 "github.com/kolesa-team/go-webp/webp"
9- "github.com/nfnt/resize"
10 "go.uber.org/zap"
11 "golang.org/x/exp/slices"
12 )
13@@ -290,7 +290,7 @@ func (h *ImgOptimizer) Process(contents io.Reader, writer io.Writer, mimeType st
14
15 nextImg := img
16 if h.Height > 0 || h.Width > 0 {
17- nextImg = resize.Resize(h.Width, h.Height, img, resize.Bicubic)
18+ nextImg = imaging.Resize(img, int(h.Width), int(h.Height), imaging.MitchellNetravali)
19 }
20
21 options, err := encoder.NewLossyEncoderOptions(
+7,
-3
1@@ -4,7 +4,6 @@ import (
2 "context"
3 "errors"
4 "fmt"
5- "io"
6 "net/url"
7
8 "github.com/minio/minio-go/v7"
9@@ -66,16 +65,21 @@ func (s *StorageMinio) UpsertBucket(name string) (Bucket, error) {
10 return bucket, nil
11 }
12
13-func (s *StorageMinio) GetFile(bucket Bucket, fname string) (io.ReadCloser, error) {
14+func (s *StorageMinio) GetFile(bucket Bucket, fname string) (ReaderAtCloser, error) {
15 obj, err := s.Client.GetObject(context.TODO(), bucket.Name, fname, minio.GetObjectOptions{})
16 if err != nil {
17 return nil, err
18 }
19
20+ _, err = obj.Stat()
21+ if err != nil {
22+ return nil, err
23+ }
24+
25 return obj, nil
26 }
27
28-func (s *StorageMinio) PutFile(bucket Bucket, fname string, contents io.ReadCloser) (string, error) {
29+func (s *StorageMinio) PutFile(bucket Bucket, fname string, contents ReaderAtCloser) (string, error) {
30 info, err := s.Client.PutObject(context.TODO(), bucket.Name, fname, contents, -1, minio.PutObjectOptions{})
31 if err != nil {
32 return "", err
+24,
-4
1@@ -12,12 +12,32 @@ type Bucket struct {
2 Path string
3 }
4
5+type ReadAndReaderAt interface {
6+ io.ReaderAt
7+ io.Reader
8+}
9+
10+type ReaderAtCloser interface {
11+ io.ReaderAt
12+ io.ReadCloser
13+}
14+
15+func NopReaderAtCloser(r ReadAndReaderAt) ReaderAtCloser {
16+ return nopReaderAtCloser{r}
17+}
18+
19+type nopReaderAtCloser struct {
20+ ReadAndReaderAt
21+}
22+
23+func (nopReaderAtCloser) Close() error { return nil }
24+
25 type ObjectStorage interface {
26 GetBucket(name string) (Bucket, error)
27 UpsertBucket(name string) (Bucket, error)
28
29- GetFile(bucket Bucket, fname string) (io.ReadCloser, error)
30- PutFile(bucket Bucket, fname string, contents io.ReadCloser) (string, error)
31+ GetFile(bucket Bucket, fname string) (ReaderAtCloser, error)
32+ PutFile(bucket Bucket, fname string, contents ReaderAtCloser) (string, error)
33 DeleteFile(bucket Bucket, fname string) error
34 }
35
36@@ -68,7 +88,7 @@ func (s *StorageFS) UpsertBucket(name string) (Bucket, error) {
37 return bucket, nil
38 }
39
40-func (s *StorageFS) GetFile(bucket Bucket, fname string) (io.ReadCloser, error) {
41+func (s *StorageFS) GetFile(bucket Bucket, fname string) (ReaderAtCloser, error) {
42 dat, err := os.Open(path.Join(bucket.Path, fname))
43 if err != nil {
44 return nil, err
45@@ -77,7 +97,7 @@ func (s *StorageFS) GetFile(bucket Bucket, fname string) (io.ReadCloser, error)
46 return dat, nil
47 }
48
49-func (s *StorageFS) PutFile(bucket Bucket, fname string, contents io.ReadCloser) (string, error) {
50+func (s *StorageFS) PutFile(bucket Bucket, fname string, contents ReaderAtCloser) (string, error) {
51 loc := path.Join(bucket.Path, fname)
52 f, err := os.OpenFile(loc, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
53 if err != nil {