github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/fichier/object.go (about) 1 package fichier 2 3 import ( 4 "context" 5 "io" 6 "net/http" 7 "time" 8 9 "github.com/pkg/errors" 10 "github.com/rclone/rclone/fs" 11 "github.com/rclone/rclone/fs/hash" 12 "github.com/rclone/rclone/lib/rest" 13 ) 14 15 // Object is a filesystem like object provided by an Fs 16 type Object struct { 17 fs *Fs 18 remote string 19 file File 20 } 21 22 // String returns a description of the Object 23 func (o *Object) String() string { 24 return o.file.Filename 25 } 26 27 // Remote returns the remote path 28 func (o *Object) Remote() string { 29 return o.remote 30 } 31 32 // ModTime returns the modification date of the file 33 // It should return a best guess if one isn't available 34 func (o *Object) ModTime(ctx context.Context) time.Time { 35 modTime, err := time.Parse("2006-01-02 15:04:05", o.file.Date) 36 37 if err != nil { 38 return time.Now() 39 } 40 41 return modTime 42 } 43 44 // Size returns the size of the file 45 func (o *Object) Size() int64 { 46 return o.file.Size 47 } 48 49 // Fs returns read only access to the Fs that this object is part of 50 func (o *Object) Fs() fs.Info { 51 return o.fs 52 } 53 54 // Hash returns the selected checksum of the file 55 // If no checksum is available it returns "" 56 func (o *Object) Hash(ctx context.Context, t hash.Type) (string, error) { 57 if t != hash.Whirlpool { 58 return "", hash.ErrUnsupported 59 } 60 61 return o.file.Checksum, nil 62 } 63 64 // Storable says whether this object can be stored 65 func (o *Object) Storable() bool { 66 return true 67 } 68 69 // SetModTime sets the metadata on the object to set the modification date 70 func (o *Object) SetModTime(context.Context, time.Time) error { 71 return fs.ErrorCantSetModTime 72 //return errors.New("setting modtime is not supported for 1fichier remotes") 73 } 74 75 // Open opens the file for read. Call Close() on the returned io.ReadCloser 76 func (o *Object) Open(ctx context.Context, options ...fs.OpenOption) (io.ReadCloser, error) { 77 fs.FixRangeOption(options, o.file.Size) 78 downloadToken, err := o.fs.getDownloadToken(ctx, o.file.URL) 79 80 if err != nil { 81 return nil, err 82 } 83 84 var resp *http.Response 85 opts := rest.Opts{ 86 Method: "GET", 87 RootURL: downloadToken.URL, 88 Options: options, 89 } 90 91 err = o.fs.pacer.Call(func() (bool, error) { 92 resp, err = o.fs.rest.Call(ctx, &opts) 93 return shouldRetry(resp, err) 94 }) 95 96 if err != nil { 97 return nil, err 98 } 99 return resp.Body, err 100 } 101 102 // Update in to the object with the modTime given of the given size 103 // 104 // When called from outside an Fs by rclone, src.Size() will always be >= 0. 105 // But for unknown-sized objects (indicated by src.Size() == -1), Upload should either 106 // return an error or update the object properly (rather than e.g. calling panic). 107 func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) error { 108 if src.Size() < 0 { 109 return errors.New("refusing to update with unknown size") 110 } 111 112 // upload with new size but old name 113 info, err := o.fs.putUnchecked(ctx, in, o.Remote(), src.Size(), options...) 114 if err != nil { 115 return err 116 } 117 118 // Delete duplicate after successful upload 119 err = o.Remove(ctx) 120 if err != nil { 121 return errors.Wrap(err, "failed to remove old version") 122 } 123 124 // Replace guts of old object with new one 125 *o = *info.(*Object) 126 127 return nil 128 } 129 130 // Remove removes this object 131 func (o *Object) Remove(ctx context.Context) error { 132 // fs.Debugf(f, "Removing file `%s` with url `%s`", o.file.Filename, o.file.URL) 133 134 _, err := o.fs.deleteFile(ctx, o.file.URL) 135 136 if err != nil { 137 return err 138 } 139 140 return nil 141 } 142 143 // MimeType of an Object if known, "" otherwise 144 func (o *Object) MimeType(ctx context.Context) string { 145 return o.file.ContentType 146 } 147 148 // ID returns the ID of the Object if known, or "" if not 149 func (o *Object) ID() string { 150 return o.file.URL 151 } 152 153 // Check the interfaces are satisfied 154 var ( 155 _ fs.Object = (*Object)(nil) 156 _ fs.MimeTyper = (*Object)(nil) 157 _ fs.IDer = (*Object)(nil) 158 )