github.com/Files-com/files-sdk-go/v2@v2.1.2/file/upload.go (about) 1 package file 2 3 import ( 4 "context" 5 "io" 6 "os" 7 "os/user" 8 "path/filepath" 9 "time" 10 11 files_sdk "github.com/Files-com/files-sdk-go/v2" 12 "github.com/Files-com/files-sdk-go/v2/file/manager" 13 "github.com/Files-com/files-sdk-go/v2/file/status" 14 lib "github.com/Files-com/files-sdk-go/v2/lib" 15 "github.com/Files-com/files-sdk-go/v2/lib/direction" 16 ) 17 18 type UploadOption func(uploadIO) (uploadIO, error) 19 20 func UploadWithContext(ctx context.Context) UploadOption { 21 return func(params uploadIO) (uploadIO, error) { 22 params.passedInContext = ctx 23 return params, nil 24 } 25 } 26 27 func UploadWithReader(reader io.Reader) UploadOption { 28 return func(params uploadIO) (uploadIO, error) { 29 if lenReader, ok := reader.(Len); ok && params.Size == nil { 30 params.Size = lib.Int64(int64(lenReader.Len())) 31 } 32 params.reader = reader 33 return params, nil 34 } 35 } 36 37 func UploadWithReaderAt(readerAt io.ReaderAt) UploadOption { 38 return func(params uploadIO) (uploadIO, error) { 39 if lenReader, ok := readerAt.(Len); ok && params.Size == nil { 40 params.Size = lib.Int64(int64(lenReader.Len())) 41 } 42 params.readerAt = readerAt 43 return params, nil 44 } 45 } 46 47 func UploadWithFile(sourcePath string) UploadOption { 48 return func(params uploadIO) (uploadIO, error) { 49 file, err := os.Open(sourcePath) 50 if err != nil { 51 return params, err 52 } 53 info, err := file.Stat() 54 if err != nil { 55 return params, err 56 } 57 58 params, err = UploadWithReaderAt(file)(params) 59 if err != nil { 60 return params, err 61 } 62 return UploadWithSize(info.Size())(params) 63 } 64 } 65 66 func UploadWithDestinationPath(destinationPath string) UploadOption { 67 return func(params uploadIO) (uploadIO, error) { 68 params.Path = destinationPath 69 return params, nil 70 } 71 } 72 73 func UploadWithProvidedMtime(providedMtime time.Time) UploadOption { 74 return func(params uploadIO) (uploadIO, error) { 75 params.ProvidedMtime = providedMtime 76 return params, nil 77 } 78 } 79 80 func UploadWithManager(manager lib.ConcurrencyManagerWithSubWorker) UploadOption { 81 return func(params uploadIO) (uploadIO, error) { 82 params.Manager = manager 83 return params, nil 84 } 85 } 86 87 func UploadWithSize(size int64) UploadOption { 88 return func(params uploadIO) (uploadIO, error) { 89 params.Size = &size 90 return params, nil 91 } 92 } 93 94 func UploadWithProgress(progress Progress) UploadOption { 95 return func(params uploadIO) (uploadIO, error) { 96 params.Progress = progress 97 return params, nil 98 } 99 } 100 101 // UploadRewindAllProgressOnFailure on upload failure rewind all successfully parts 102 func UploadRewindAllProgressOnFailure() UploadOption { 103 return func(params uploadIO) (uploadIO, error) { 104 params.RewindAllProgressOnFailure = true 105 return params, nil 106 } 107 } 108 109 func UploadWithResume(resume UploadResumable) UploadOption { 110 return func(params uploadIO) (uploadIO, error) { 111 if params.Path == "" { 112 params.Path = resume.FileUploadPart.Path 113 } 114 params.Parts = resume.Parts 115 params.FileUploadPart = resume.FileUploadPart 116 return params, nil 117 } 118 } 119 120 func (c *Client) Upload(opts ...UploadOption) error { 121 _, err := c.UploadWithResume(opts...) 122 123 return err 124 } 125 126 func (c *Client) UploadWithResume(opts ...UploadOption) (UploadResumable, error) { 127 uploadIo := uploadIO{ 128 Client: c, 129 Manager: manager.Default().FilePartsManager, 130 passedInContext: context.Background(), 131 ByteOffset: ByteOffset{PartSizes: lib.PartSizes}, 132 } 133 134 for _, opt := range opts { 135 var err error 136 uploadIo, err = opt(uploadIo) 137 if err != nil { 138 return UploadResumable{}, err 139 } 140 } 141 return (&uploadIo).Run(uploadIo.passedInContext) 142 } 143 144 // UploadFile Deprecated use c.Upload(UploadWithFile(sourcePath), UploadWithDestinationPath(destinationPath)) 145 func (c *Client) UploadFile(sourcePath string, destinationPath string, opts ...UploadOption) error { 146 return c.Upload(append(opts, UploadWithFile(sourcePath), UploadWithDestinationPath(destinationPath))...) 147 } 148 149 func (c *Client) UploadRetry(job status.Job, opts ...files_sdk.RequestResponseOption) *status.Job { 150 newJob := job.ClearStatuses() 151 return c.Uploader( 152 UploaderParams{ 153 Sync: newJob.Sync, 154 LocalPath: newJob.LocalPath, 155 RemotePath: newJob.RemotePath, 156 EventsReporter: newJob.EventsReporter, 157 Manager: newJob.Manager, 158 RetryPolicy: newJob.RetryPolicy.(RetryPolicy), 159 Ignore: newJob.Params.(UploaderParams).Ignore, 160 Config: c.Config, 161 }, 162 opts..., 163 ) 164 } 165 166 type UploaderParams struct { 167 Ignore []string 168 Include []string 169 *status.Job 170 Sync bool 171 LocalPath string 172 RemotePath string 173 DryRun bool 174 RetryPolicy 175 status.EventsReporter 176 *manager.Manager 177 files_sdk.Config 178 } 179 180 func expand(path string) (string, error) { 181 if len(path) == 0 || path[0] != '~' { 182 return path, nil 183 } 184 usr, err := user.Current() 185 if err != nil { 186 return "", err 187 } 188 return filepath.Join(usr.HomeDir, path[1:]), nil 189 } 190 191 func (c *Client) Uploader(params UploaderParams, opts ...files_sdk.RequestResponseOption) *status.Job { 192 job := (&status.Job{}).Init() 193 SetJobParams(job, direction.UploadType, params, params.Config.Logger(), (&FS{}).Init(c.Config, true)) 194 job.Config = params.Config 195 job.CodeStart = func() { 196 params.Job = job 197 job.Params = params 198 params.RemotePath = lib.Path{Path: params.RemotePath}.PruneStartingSlash().String() 199 file := &UploadStatus{file: files_sdk.File{}, remotePath: params.RemotePath, localPath: params.LocalPath, status: status.Queued, job: job} 200 expandedPath, err := expand(params.LocalPath) 201 if err != nil { 202 job.Add(file) 203 job.UpdateStatus(status.Errored, file, err) 204 return 205 } 206 absolutePath, err := filepath.Abs(expandedPath) 207 if err != nil { 208 job.Add(file) 209 job.UpdateStatus(status.Errored, file, err) 210 return 211 } 212 if (lib.Path{Path: params.LocalPath}).EndingSlash() { 213 params.LocalPath = absolutePath + string(os.PathSeparator) 214 } else { 215 params.LocalPath = absolutePath 216 } 217 218 uploader(files_sdk.ContextOption(opts), c, params).CodeStart() 219 } 220 221 return job 222 }