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:
Sean
2023-08-27 21:14:23 +08:00
committed by GitHub
parent 9b765ef696
commit a3748af772
77 changed files with 1731 additions and 615 deletions

View File

@ -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
}