mirror of
https://github.com/rclone/rclone.git
synced 2025-03-11 13:35:14 +08:00
b2: implement SetModTime #3210
SetModTime() is implemented by copying an object onto itself and updating the metadata in the process.
This commit is contained in:
parent
a5bed67016
commit
22368b997c
@ -1206,17 +1206,8 @@ func (o *Object) decodeMetaDataFileInfo(info *api.FileInfo) (err error) {
|
|||||||
return o.decodeMetaDataRaw(info.ID, info.SHA1, info.Size, info.UploadTimestamp, info.Info, info.ContentType)
|
return o.decodeMetaDataRaw(info.ID, info.SHA1, info.Size, info.UploadTimestamp, info.Info, info.ContentType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// readMetaData gets the metadata if it hasn't already been fetched
|
// getMetaData gets the metadata from the object unconditionally
|
||||||
//
|
func (o *Object) getMetaData() (info *api.File, err error) {
|
||||||
// Sets
|
|
||||||
// o.id
|
|
||||||
// o.modTime
|
|
||||||
// o.size
|
|
||||||
// o.sha1
|
|
||||||
func (o *Object) readMetaData() (err error) {
|
|
||||||
if o.id != "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
maxSearched := 1
|
maxSearched := 1
|
||||||
var timestamp api.Timestamp
|
var timestamp api.Timestamp
|
||||||
baseRemote := o.remote
|
baseRemote := o.remote
|
||||||
@ -1224,7 +1215,6 @@ func (o *Object) readMetaData() (err error) {
|
|||||||
timestamp, baseRemote = api.RemoveVersion(baseRemote)
|
timestamp, baseRemote = api.RemoveVersion(baseRemote)
|
||||||
maxSearched = maxVersions
|
maxSearched = maxVersions
|
||||||
}
|
}
|
||||||
var info *api.File
|
|
||||||
err = o.fs.list("", true, baseRemote, maxSearched, o.fs.opt.Versions, func(remote string, object *api.File, isDirectory bool) error {
|
err = o.fs.list("", true, baseRemote, maxSearched, o.fs.opt.Versions, func(remote string, object *api.File, isDirectory bool) error {
|
||||||
if isDirectory {
|
if isDirectory {
|
||||||
return nil
|
return nil
|
||||||
@ -1239,12 +1229,30 @@ func (o *Object) readMetaData() (err error) {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == fs.ErrorDirNotFound {
|
if err == fs.ErrorDirNotFound {
|
||||||
return fs.ErrorObjectNotFound
|
return nil, fs.ErrorObjectNotFound
|
||||||
}
|
}
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
if info == nil {
|
if info == nil {
|
||||||
return fs.ErrorObjectNotFound
|
return nil, fs.ErrorObjectNotFound
|
||||||
|
}
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// readMetaData gets the metadata if it hasn't already been fetched
|
||||||
|
//
|
||||||
|
// Sets
|
||||||
|
// o.id
|
||||||
|
// o.modTime
|
||||||
|
// o.size
|
||||||
|
// o.sha1
|
||||||
|
func (o *Object) readMetaData() (err error) {
|
||||||
|
if o.id != "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
info, err := o.getMetaData()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return o.decodeMetaData(info)
|
return o.decodeMetaData(info)
|
||||||
}
|
}
|
||||||
@ -1283,10 +1291,33 @@ func (o *Object) ModTime() (result time.Time) {
|
|||||||
return o.modTime
|
return o.modTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetModTime sets the modification time of the local fs object
|
// SetModTime sets the modification time of the Object
|
||||||
func (o *Object) SetModTime(modTime time.Time) error {
|
func (o *Object) SetModTime(modTime time.Time) error {
|
||||||
// Not possible with B2
|
info, err := o.getMetaData()
|
||||||
return fs.ErrorCantSetModTime
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
info.Info[timeKey] = timeString(modTime)
|
||||||
|
opts := rest.Opts{
|
||||||
|
Method: "POST",
|
||||||
|
Path: "/b2_copy_file",
|
||||||
|
}
|
||||||
|
var request = api.CopyFileRequest{
|
||||||
|
SourceID: o.id,
|
||||||
|
Name: o.fs.root + o.remote, // copy to same name
|
||||||
|
MetadataDirective: "REPLACE",
|
||||||
|
ContentType: info.ContentType,
|
||||||
|
Info: info.Info,
|
||||||
|
}
|
||||||
|
var response api.FileInfo
|
||||||
|
err = o.fs.pacer.Call(func() (bool, error) {
|
||||||
|
resp, err := o.fs.srv.CallJSON(&opts, &request, &response)
|
||||||
|
return o.fs.shouldRetry(resp, err)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return o.decodeMetaDataFileInfo(&response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Storable returns if this object is storable
|
// Storable returns if this object is storable
|
||||||
|
@ -124,10 +124,9 @@ The modified time is stored as metadata on the object as
|
|||||||
in the Backblaze standard. Other tools should be able to use this as
|
in the Backblaze standard. Other tools should be able to use this as
|
||||||
a modified time.
|
a modified time.
|
||||||
|
|
||||||
Modified times are used in syncing and are fully supported except in
|
Modified times are used in syncing and are fully supported. Note that
|
||||||
the case of updating a modification time on an existing object. In
|
if a modification time needs to be updated on an object then it will
|
||||||
this case the object will be uploaded again as B2 doesn't have an API
|
create a new version of the object.
|
||||||
method to set the modification time independent of doing an upload.
|
|
||||||
|
|
||||||
### SHA1 checksums ###
|
### SHA1 checksums ###
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user