diff --git a/pkg/models/task_attachment.go b/pkg/models/task_attachment.go index 10d9b1ffb..64e3a4129 100644 --- a/pkg/models/task_attachment.go +++ b/pkg/models/task_attachment.go @@ -58,8 +58,7 @@ func (*TaskAttachment) TableName() string { } // NewAttachment creates a new task attachment -// Note: I'm not sure if only accepting an io.ReadCloser and not an afero.File or os.File instead is a good way of doing things. -func (ta *TaskAttachment) NewAttachment(s *xorm.Session, f io.ReadCloser, realname string, realsize uint64, a web.Auth) error { +func (ta *TaskAttachment) NewAttachment(s *xorm.Session, f io.ReadSeeker, realname string, realsize uint64, a web.Auth) error { // Store the file file, err := files.Create(f, realname, realsize, a) diff --git a/pkg/modules/avatar/upload/upload.go b/pkg/modules/avatar/upload/upload.go index d79efb624..81de8f25b 100644 --- a/pkg/modules/avatar/upload/upload.go +++ b/pkg/modules/avatar/upload/upload.go @@ -171,7 +171,7 @@ func StoreAvatarFile(s *xorm.Session, u *user.User, src io.Reader) (err error) { } // Save the file - f, err := files.CreateWithMime(buf, "avatar.png", uint64(buf.Len()), u, "image/png") + f, err := files.CreateWithMime(bytes.NewReader(buf.Bytes()), "avatar.png", uint64(buf.Len()), u, "image/png") if err != nil { return err } diff --git a/pkg/modules/background/handler/background.go b/pkg/modules/background/handler/background.go index 1308c3d2e..6564ccdde 100644 --- a/pkg/modules/background/handler/background.go +++ b/pkg/modules/background/handler/background.go @@ -278,7 +278,7 @@ func SaveBackgroundFile(s *xorm.Session, auth web.Auth, project *models.Project, return err } - f, err := files.Create(&buf, filename, filesize, auth) + f, err := files.Create(bytes.NewReader(buf.Bytes()), filename, filesize, auth) if err != nil { return err } diff --git a/pkg/modules/background/unsplash/unsplash.go b/pkg/modules/background/unsplash/unsplash.go index 7833d7441..cb4e2f4a8 100644 --- a/pkg/modules/background/unsplash/unsplash.go +++ b/pkg/modules/background/unsplash/unsplash.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "encoding/json" + "io" "net/http" "net/url" "strconv" @@ -279,8 +280,14 @@ func (p *Provider) Set(s *xorm.Session, image *background.Image, project *models } log.Debugf("Pinged unsplash download endpoint for photo %s", image.ID) + // Buffer the response body so we have a seekable reader for S3 uploads + bodyBytes, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + // Save it as a file in vikunja - file, err := files.Create(resp.Body, "", 0, auth) + file, err := files.Create(bytes.NewReader(bodyBytes), "", uint64(len(bodyBytes)), auth) if err != nil { return } diff --git a/pkg/modules/dump/restore.go b/pkg/modules/dump/restore.go index c01623148..749ae08f7 100644 --- a/pkg/modules/dump/restore.go +++ b/pkg/modules/dump/restore.go @@ -181,11 +181,15 @@ func Restore(filename string, overrideConfig bool) error { return fmt.Errorf("could not open file %s: %w", i, err) } - if err := f.Save(fc); err != nil { - return fmt.Errorf("could not save file: %w", err) + content, err := io.ReadAll(fc) + _ = fc.Close() + if err != nil { + return fmt.Errorf("could not read file %s: %w", i, err) } - _ = fc.Close() + if err := f.Save(bytes.NewReader(content)); err != nil { + return fmt.Errorf("could not save file: %w", err) + } log.Infof("Restored file %s", i) } log.Infof("Restored %d files.", len(filesFiles)) diff --git a/pkg/modules/migration/create_from_structure.go b/pkg/modules/migration/create_from_structure.go index c14d9eb56..177f13c39 100644 --- a/pkg/modules/migration/create_from_structure.go +++ b/pkg/modules/migration/create_from_structure.go @@ -18,7 +18,6 @@ package migration import ( "bytes" - "io" "xorm.io/xorm" @@ -395,8 +394,7 @@ func createProjectWithEverything(s *xorm.Session, project *models.ProjectWithTas oldID := a.ID a.ID = 0 a.TaskID = t.ID - fr := io.NopCloser(bytes.NewReader(a.File.FileContent)) - err = a.NewAttachment(s, fr, a.File.Name, a.File.Size, user) + err = a.NewAttachment(s, bytes.NewReader(a.File.FileContent), a.File.Name, a.File.Size, user) if err != nil { if models.IsErrTaskAttachmentIsTooLarge(err) { log.Warningf("[creating structure] Attachment %s is too large (%d bytes), skipping: %v", a.File.Name, a.File.Size, err)