mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 06:19:00 +08:00
fichier: implement DirMove
See: https://forum.rclone.org/t/1fichier-rclone-does-not-allow-to-rename-files-and-folders-when-you-mount-a-1fichier-disk-drive/24726/
This commit is contained in:
parent
3ad255172c
commit
f2ee949eff
|
@ -408,6 +408,32 @@ func (f *Fs) moveFile(ctx context.Context, url string, folderID int, rename stri
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Fs) moveDir(ctx context.Context, folderID int, newLeaf string, destinationFolderID int) (response *MoveDirResponse, err error) {
|
||||||
|
request := &MoveDirRequest{
|
||||||
|
FolderID: folderID,
|
||||||
|
DestinationFolderID: destinationFolderID,
|
||||||
|
Rename: newLeaf,
|
||||||
|
// DestinationUser: destinationUser,
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := rest.Opts{
|
||||||
|
Method: "POST",
|
||||||
|
Path: "/folder/mv.cgi",
|
||||||
|
}
|
||||||
|
|
||||||
|
response = &MoveDirResponse{}
|
||||||
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
|
resp, err := f.rest.CallJSON(ctx, &opts, request, response)
|
||||||
|
return shouldRetry(ctx, resp, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("couldn't move dir: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Fs) copyFile(ctx context.Context, url string, folderID int, rename string) (response *CopyFileResponse, err error) {
|
func (f *Fs) copyFile(ctx context.Context, url string, folderID int, rename string) (response *CopyFileResponse, err error) {
|
||||||
request := &CopyFileRequest{
|
request := &CopyFileRequest{
|
||||||
URLs: []string{url},
|
URLs: []string{url},
|
||||||
|
|
|
@ -488,6 +488,51 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object,
|
||||||
return dstObj, nil
|
return dstObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DirMove moves src, srcRemote to this remote at dstRemote
|
||||||
|
// using server-side move operations.
|
||||||
|
//
|
||||||
|
// Will only be called if src.Fs().Name() == f.Name()
|
||||||
|
//
|
||||||
|
// If it isn't possible then return fs.ErrorCantDirMove.
|
||||||
|
//
|
||||||
|
// If destination exists then return fs.ErrorDirExists.
|
||||||
|
//
|
||||||
|
// This is complicated by the fact that we can't use moveDir to move
|
||||||
|
// to a different directory AND rename at the same time as it can
|
||||||
|
// overwrite files in the source directory.
|
||||||
|
func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string) error {
|
||||||
|
srcFs, ok := src.(*Fs)
|
||||||
|
if !ok {
|
||||||
|
fs.Debugf(srcFs, "Can't move directory - not same remote type")
|
||||||
|
return fs.ErrorCantDirMove
|
||||||
|
}
|
||||||
|
|
||||||
|
srcID, _, _, dstDirectoryID, dstLeaf, err := f.dirCache.DirMove(ctx, srcFs.dirCache, srcFs.root, srcRemote, f.root, dstRemote)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
srcIDnumeric, err := strconv.Atoi(srcID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dstDirectoryIDnumeric, err := strconv.Atoi(dstDirectoryID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp *MoveDirResponse
|
||||||
|
resp, err = f.moveDir(ctx, srcIDnumeric, dstLeaf, dstDirectoryIDnumeric)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("couldn't rename leaf: %w", err)
|
||||||
|
}
|
||||||
|
if resp.Status != "OK" {
|
||||||
|
return fmt.Errorf("couldn't rename leaf: %s", resp.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
srcFs.dirCache.FlushDir(srcRemote)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Copy src to this remote using server side move operations.
|
// Copy src to this remote using server side move operations.
|
||||||
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
|
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
|
||||||
srcObj, ok := src.(*Object)
|
srcObj, ok := src.(*Object)
|
||||||
|
@ -561,6 +606,7 @@ func (f *Fs) PublicLink(ctx context.Context, remote string, expire fs.Duration,
|
||||||
var (
|
var (
|
||||||
_ fs.Fs = (*Fs)(nil)
|
_ fs.Fs = (*Fs)(nil)
|
||||||
_ fs.Mover = (*Fs)(nil)
|
_ fs.Mover = (*Fs)(nil)
|
||||||
|
_ fs.DirMover = (*Fs)(nil)
|
||||||
_ fs.Copier = (*Fs)(nil)
|
_ fs.Copier = (*Fs)(nil)
|
||||||
_ fs.PublicLinker = (*Fs)(nil)
|
_ fs.PublicLinker = (*Fs)(nil)
|
||||||
_ fs.PutUncheckeder = (*Fs)(nil)
|
_ fs.PutUncheckeder = (*Fs)(nil)
|
||||||
|
|
|
@ -70,6 +70,22 @@ type MoveFileResponse struct {
|
||||||
URLs []string `json:"urls"`
|
URLs []string `json:"urls"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MoveDirRequest is the request structure of the corresponding request
|
||||||
|
type MoveDirRequest struct {
|
||||||
|
FolderID int `json:"folder_id"`
|
||||||
|
DestinationFolderID int `json:"destination_folder_id,omitempty"`
|
||||||
|
DestinationUser string `json:"destination_user"`
|
||||||
|
Rename string `json:"rename,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MoveDirResponse is the response structure of the corresponding request
|
||||||
|
type MoveDirResponse struct {
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
OldName string `json:"old_name"`
|
||||||
|
NewName string `json:"new_name"`
|
||||||
|
}
|
||||||
|
|
||||||
// CopyFileRequest is the request structure of the corresponding request
|
// CopyFileRequest is the request structure of the corresponding request
|
||||||
type CopyFileRequest struct {
|
type CopyFileRequest struct {
|
||||||
URLs []string `json:"urls"`
|
URLs []string `json:"urls"`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user