feat: misc improvements about upload/copy/hash (#5045)
general: add createTime/updateTime support in webdav and some drivers general: add hash support in some drivers general: cross-storage rapid-upload support general: enhance upload to avoid local temp file if possible general: replace readseekcloser with File interface to speed upstream operations feat(aliyun_open): same as above feat(crypt): add hack for 139cloud Close #4934 Close #4819 baidu_netdisk needs to improve the upload code to support rapid-upload
This commit is contained in:
@ -3,7 +3,9 @@ package utils
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/exp/constraints"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
@ -17,7 +19,7 @@ type readerFunc func(p []byte) (n int, err error)
|
||||
func (rf readerFunc) Read(p []byte) (n int, err error) { return rf(p) }
|
||||
|
||||
// CopyWithCtx slightly modified function signature:
|
||||
// - context has been added in order to propagate cancelation
|
||||
// - context has been added in order to propagate cancellation
|
||||
// - I do not return the number of bytes written, has it is not useful in my use case
|
||||
func CopyWithCtx(ctx context.Context, out io.Writer, in io.Reader, size int64, progress func(percentage int)) error {
|
||||
// Copy will call the Reader and Writer interface multiple time, in order
|
||||
@ -132,16 +134,6 @@ func (mr *MultiReadable) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type nopCloser struct {
|
||||
io.ReadSeeker
|
||||
}
|
||||
|
||||
func (nopCloser) Close() error { return nil }
|
||||
|
||||
func ReadSeekerNopCloser(r io.ReadSeeker) io.ReadSeekCloser {
|
||||
return nopCloser{r}
|
||||
}
|
||||
|
||||
func Retry(attempts int, sleep time.Duration, f func() error) (err error) {
|
||||
for i := 0; i < attempts; i++ {
|
||||
fmt.Println("This is attempt number", i)
|
||||
@ -158,23 +150,56 @@ func Retry(attempts int, sleep time.Duration, f func() error) (err error) {
|
||||
return fmt.Errorf("after %d attempts, last error: %s", attempts, err)
|
||||
}
|
||||
|
||||
type Closers struct {
|
||||
closers []*io.Closer
|
||||
type ClosersIF interface {
|
||||
io.Closer
|
||||
Add(closer io.Closer)
|
||||
AddClosers(closers Closers)
|
||||
GetClosers() Closers
|
||||
}
|
||||
|
||||
func (c *Closers) Close() (err error) {
|
||||
type Closers struct {
|
||||
closers []io.Closer
|
||||
}
|
||||
|
||||
func (c *Closers) GetClosers() Closers {
|
||||
return *c
|
||||
}
|
||||
|
||||
var _ ClosersIF = (*Closers)(nil)
|
||||
|
||||
func (c *Closers) Close() error {
|
||||
var errs []error
|
||||
for _, closer := range c.closers {
|
||||
if closer != nil {
|
||||
_ = (*closer).Close()
|
||||
errs = append(errs, closer.Close())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return errors.Join(errs...)
|
||||
}
|
||||
func (c *Closers) Add(closer io.Closer) {
|
||||
if closer != nil {
|
||||
c.closers = append(c.closers, &closer)
|
||||
c.closers = append(c.closers, closer)
|
||||
|
||||
}
|
||||
func (c *Closers) AddClosers(closers Closers) {
|
||||
c.closers = append(c.closers, closers.closers...)
|
||||
}
|
||||
|
||||
func EmptyClosers() Closers {
|
||||
return Closers{[]io.Closer{}}
|
||||
}
|
||||
func NewClosers(c ...io.Closer) Closers {
|
||||
return Closers{c}
|
||||
}
|
||||
|
||||
func Min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
func NewClosers() *Closers {
|
||||
return &Closers{[]*io.Closer{}}
|
||||
func Max[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
Reference in New Issue
Block a user