mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 01:44:41 +01:00
opendrive: fix moving file/folder within the same parent dir - #7591
Before this change, moving (renaming) a file or folder to a different name within the same parent directory would fail, due to using the wrong API operation ("/file/move_copy.json" and "/folder/move_copy.json", instead of the separate "/file/rename.json" and "/folder/rename.json" that opendrive has for this purpose.) After this change, Move and DirMove check whether the move is within the same parent dir. If so, "rename" is used. If not, "move_copy" is used, like before.
This commit is contained in:
parent
db8fb5ceda
commit
9d2bd163c7
@ -437,23 +437,41 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object,
|
|||||||
return nil, fs.ErrorFileNameTooLong
|
return nil, fs.ErrorFileNameTooLong
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the object
|
moveCopyFileData := moveCopyFile{
|
||||||
|
SessionID: f.session.SessionID,
|
||||||
|
SrcFileID: srcObj.id,
|
||||||
|
DstFolderID: directoryID,
|
||||||
|
Move: "true",
|
||||||
|
OverwriteIfExists: "true",
|
||||||
|
NewFileName: leaf,
|
||||||
|
}
|
||||||
|
opts := rest.Opts{
|
||||||
|
Method: "POST",
|
||||||
|
Path: "/file/move_copy.json",
|
||||||
|
}
|
||||||
|
var request interface{} = moveCopyFileData
|
||||||
|
|
||||||
|
// use /file/rename.json if moving within the same directory
|
||||||
|
_, srcDirID, err := srcObj.fs.dirCache.FindPath(ctx, srcObj.remote, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if srcDirID == directoryID {
|
||||||
|
fs.Debugf(src, "same parent dir (%v) - using file/rename instead of move_copy for %s", directoryID, remote)
|
||||||
|
renameFileData := renameFile{
|
||||||
|
SessionID: f.session.SessionID,
|
||||||
|
FileID: srcObj.id,
|
||||||
|
NewFileName: leaf,
|
||||||
|
}
|
||||||
|
opts.Path = "/file/rename.json"
|
||||||
|
request = renameFileData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the object
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
response := moveCopyFileResponse{}
|
response := moveCopyFileResponse{}
|
||||||
err = f.pacer.Call(func() (bool, error) {
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
copyFileData := moveCopyFile{
|
resp, err = f.srv.CallJSON(ctx, &opts, &request, &response)
|
||||||
SessionID: f.session.SessionID,
|
|
||||||
SrcFileID: srcObj.id,
|
|
||||||
DstFolderID: directoryID,
|
|
||||||
Move: "true",
|
|
||||||
OverwriteIfExists: "true",
|
|
||||||
NewFileName: leaf,
|
|
||||||
}
|
|
||||||
opts := rest.Opts{
|
|
||||||
Method: "POST",
|
|
||||||
Path: "/file/move_copy.json",
|
|
||||||
}
|
|
||||||
resp, err = f.srv.CallJSON(ctx, &opts, ©FileData, &response)
|
|
||||||
return f.shouldRetry(ctx, resp, err)
|
return f.shouldRetry(ctx, resp, err)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -482,27 +500,47 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string
|
|||||||
return fs.ErrorCantDirMove
|
return fs.ErrorCantDirMove
|
||||||
}
|
}
|
||||||
|
|
||||||
srcID, _, _, dstDirectoryID, dstLeaf, err := f.dirCache.DirMove(ctx, srcFs.dirCache, srcFs.root, srcRemote, f.root, dstRemote)
|
srcID, srcDirectoryID, _, dstDirectoryID, dstLeaf, err := f.dirCache.DirMove(ctx, srcFs.dirCache, srcFs.root, srcRemote, f.root, dstRemote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// move_copy will silently truncate new filenames
|
||||||
|
if len(dstLeaf) > 255 {
|
||||||
|
fs.Debugf(src, "Can't move folder: name (%q) exceeds 255 char", dstLeaf)
|
||||||
|
return fs.ErrorFileNameTooLong
|
||||||
|
}
|
||||||
|
|
||||||
|
moveFolderData := moveCopyFolder{
|
||||||
|
SessionID: f.session.SessionID,
|
||||||
|
FolderID: srcID,
|
||||||
|
DstFolderID: dstDirectoryID,
|
||||||
|
Move: "true",
|
||||||
|
NewFolderName: dstLeaf,
|
||||||
|
}
|
||||||
|
opts := rest.Opts{
|
||||||
|
Method: "POST",
|
||||||
|
Path: "/folder/move_copy.json",
|
||||||
|
}
|
||||||
|
var request interface{} = moveFolderData
|
||||||
|
|
||||||
|
// use /folder/rename.json if moving within the same parent directory
|
||||||
|
if srcDirectoryID == dstDirectoryID {
|
||||||
|
fs.Debugf(dstRemote, "same parent dir (%v) - using folder/rename instead of move_copy", srcDirectoryID)
|
||||||
|
renameFolderData := renameFolder{
|
||||||
|
SessionID: f.session.SessionID,
|
||||||
|
FolderID: srcID,
|
||||||
|
FolderName: dstLeaf,
|
||||||
|
}
|
||||||
|
opts.Path = "/folder/rename.json"
|
||||||
|
request = renameFolderData
|
||||||
|
}
|
||||||
|
|
||||||
// Do the move
|
// Do the move
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
response := moveCopyFolderResponse{}
|
response := moveCopyFolderResponse{}
|
||||||
err = f.pacer.Call(func() (bool, error) {
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
moveFolderData := moveCopyFolder{
|
resp, err = f.srv.CallJSON(ctx, &opts, &request, &response)
|
||||||
SessionID: f.session.SessionID,
|
|
||||||
FolderID: srcID,
|
|
||||||
DstFolderID: dstDirectoryID,
|
|
||||||
Move: "true",
|
|
||||||
NewFolderName: dstLeaf,
|
|
||||||
}
|
|
||||||
opts := rest.Opts{
|
|
||||||
Method: "POST",
|
|
||||||
Path: "/folder/move_copy.json",
|
|
||||||
}
|
|
||||||
resp, err = f.srv.CallJSON(ctx, &opts, &moveFolderData, &response)
|
|
||||||
return f.shouldRetry(ctx, resp, err)
|
return f.shouldRetry(ctx, resp, err)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,6 +100,13 @@ type moveCopyFolder struct {
|
|||||||
NewFolderName string `json:"new_folder_name"` // New name for destination folder.
|
NewFolderName string `json:"new_folder_name"` // New name for destination folder.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type renameFolder struct {
|
||||||
|
SessionID string `json:"session_id"`
|
||||||
|
FolderID string `json:"folder_id"`
|
||||||
|
FolderName string `json:"folder_name"` // New name for destination folder (max 255).
|
||||||
|
SharingID string `json:"sharing_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type moveCopyFolderResponse struct {
|
type moveCopyFolderResponse struct {
|
||||||
FolderID string `json:"FolderID"`
|
FolderID string `json:"FolderID"`
|
||||||
}
|
}
|
||||||
@ -146,6 +153,14 @@ type moveCopyFileResponse struct {
|
|||||||
Size string `json:"Size"`
|
Size string `json:"Size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type renameFile struct {
|
||||||
|
SessionID string `json:"session_id"`
|
||||||
|
NewFileName string `json:"new_file_name"` // New name for destination file.
|
||||||
|
FileID string `json:"file_id"`
|
||||||
|
AccessFolderID string `json:"access_folder_id"`
|
||||||
|
SharingID string `json:"sharing_id"`
|
||||||
|
}
|
||||||
|
|
||||||
type createFile struct {
|
type createFile struct {
|
||||||
SessionID string `json:"session_id"`
|
SessionID string `json:"session_id"`
|
||||||
FolderID string `json:"folder_id"`
|
FolderID string `json:"folder_id"`
|
||||||
|
Loading…
Reference in New Issue
Block a user