onedrive: implement Move #197

This commit is contained in:
Nick Craig-Wood 2017-03-14 15:35:10 +00:00
parent e80d8db417
commit 99f7fe736a
4 changed files with 75 additions and 3 deletions

View File

@ -111,7 +111,7 @@ operations more efficient.
| Dropbox | Yes | Yes | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) |
| Google Cloud Storage | Yes | Yes | No | No | No |
| Amazon Drive | Yes | No | Yes | Yes | No [#575](https://github.com/ncw/rclone/issues/575) |
| Microsoft One Drive | Yes | Yes | No [#197](https://github.com/ncw/rclone/issues/197) | No [#197](https://github.com/ncw/rclone/issues/197) | No [#575](https://github.com/ncw/rclone/issues/575) |
| Microsoft One Drive | Yes | Yes | Yes | No [#197](https://github.com/ncw/rclone/issues/197) | No [#575](https://github.com/ncw/rclone/issues/575) |
| Hubic | Yes † | Yes | No | No | No |
| Backblaze B2 | No | No | No | No | Yes |
| Yandex Disk | Yes | No | No | No | No [#575](https://github.com/ncw/rclone/issues/575) |

View File

@ -395,7 +395,7 @@ func Move(fdst Fs, dst Object, remote string, src Object) (err error) {
Debugf(src, "Can't move, switching to copy")
default:
Stats.Error()
Errorf(dst, "Couldn't move: %v", err)
Errorf(src, "Couldn't move: %v", err)
return err
}
}

View File

@ -200,6 +200,17 @@ type CopyItemRequest struct {
Name *string `json:"name"` // Optional The new name for the copy. If this isn't provided, the same name will be used as the original.
}
// MoveItemRequest is the request to copy an item object
//
// Note: The parentReference should include either an id or path but
// not both. If both are included, they need to reference the same
// item or an error will occur.
type MoveItemRequest struct {
ParentReference *ItemReference `json:"parentReference,omitempty"` // Reference to the destination parent directory
Name string `json:"name,omitempty"` // Optional The new name for the file. If this isn't provided, the same name will be used as the original.
FileSystemInfo *FileSystemInfoFacet `json:"fileSystemInfo,omitempty"` // File system information on client. Read-write.
}
// AsyncOperationStatus provides information on the status of a asynchronous job progress.
//
// The following API calls return AsyncOperationStatus resources:

View File

@ -667,6 +667,67 @@ func (f *Fs) Purge() error {
return f.purgeCheck("", false)
}
// Move src to this remote using server side move operations.
//
// This is stored with the remote path given
//
// It returns the destination Object and a possible error
//
// Will only be called if src.Fs().Name() == f.Name()
//
// If it isn't possible then return fs.ErrorCantMove
func (f *Fs) Move(src fs.Object, remote string) (fs.Object, error) {
srcObj, ok := src.(*Object)
if !ok {
fs.Debugf(src, "Can't move - not same remote type")
return nil, fs.ErrorCantMove
}
// create the destination directory if necessary
err := f.dirCache.FindRoot(true)
if err != nil {
return nil, err
}
// Create temporary object
dstObj, leaf, directoryID, err := f.createObject(remote, srcObj.modTime, srcObj.size)
if err != nil {
return nil, err
}
// Move the object
opts := rest.Opts{
Method: "PATCH",
Path: "/drive/items/" + srcObj.id,
}
move := api.MoveItemRequest{
Name: replaceReservedChars(leaf),
ParentReference: &api.ItemReference{
ID: directoryID,
},
// We set the mod time too as it gets reset otherwise
FileSystemInfo: &api.FileSystemInfoFacet{
CreatedDateTime: api.Timestamp(srcObj.modTime),
LastModifiedDateTime: api.Timestamp(srcObj.modTime),
},
}
var resp *http.Response
var info api.Item
err = f.pacer.Call(func() (bool, error) {
resp, err = f.srv.CallJSON(&opts, &move, &info)
return shouldRetry(resp, err)
})
if err != nil {
return nil, err
}
err = dstObj.setMetaData(&info)
if err != nil {
return nil, err
}
return dstObj, nil
}
// DirCacheFlush resets the directory cache - used in testing as an
// optional interface
func (f *Fs) DirCacheFlush() {
@ -1000,7 +1061,7 @@ var (
_ fs.Fs = (*Fs)(nil)
_ fs.Purger = (*Fs)(nil)
_ fs.Copier = (*Fs)(nil)
// _ fs.Mover = (*Fs)(nil)
_ fs.Mover = (*Fs)(nil)
// _ fs.DirMover = (*Fs)(nil)
_ fs.DirCacheFlusher = (*Fs)(nil)
_ fs.Object = (*Object)(nil)