From fcf2683112ecf4df1f672b68b64b6d7c1efbd31c Mon Sep 17 00:00:00 2001 From: Toby Shi Date: Sun, 16 Jun 2024 16:58:02 +0800 Subject: [PATCH] feat(ftp): custom encoding (#6528 close #1260) --- drivers/ftp/driver.go | 26 +++++++++++++++++--------- drivers/ftp/meta.go | 18 ++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/ftp/driver.go b/drivers/ftp/driver.go index 70fbabdcdcd..05b9e49a91d 100644 --- a/drivers/ftp/driver.go +++ b/drivers/ftp/driver.go @@ -39,7 +39,7 @@ func (d *FTP) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]m if err := d.login(); err != nil { return nil, err } - entries, err := d.conn.List(dir.GetPath()) + entries, err := d.conn.List(encode(dir.GetPath(), d.Encoding)) if err != nil { return nil, err } @@ -49,7 +49,7 @@ func (d *FTP) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]m continue } f := model.Object{ - Name: entry.Name, + Name: decode(entry.Name, d.Encoding), Size: int64(entry.Size), Modified: entry.Time, IsFolder: entry.Type == ftp.EntryTypeFolder, @@ -64,7 +64,7 @@ func (d *FTP) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*m return nil, err } - r := NewFileReader(d.conn, file.GetPath(), file.GetSize()) + r := NewFileReader(d.conn, encode(file.GetPath(), d.Encoding), file.GetSize()) link := &model.Link{ MFile: r, } @@ -75,21 +75,27 @@ func (d *FTP) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) if err := d.login(); err != nil { return err } - return d.conn.MakeDir(stdpath.Join(parentDir.GetPath(), dirName)) + return d.conn.MakeDir(encode(stdpath.Join(parentDir.GetPath(), dirName), d.Encoding)) } func (d *FTP) Move(ctx context.Context, srcObj, dstDir model.Obj) error { if err := d.login(); err != nil { return err } - return d.conn.Rename(srcObj.GetPath(), stdpath.Join(dstDir.GetPath(), srcObj.GetName())) + return d.conn.Rename( + encode(srcObj.GetPath(), d.Encoding), + encode(stdpath.Join(dstDir.GetPath(), srcObj.GetName()), d.Encoding), + ) } func (d *FTP) Rename(ctx context.Context, srcObj model.Obj, newName string) error { if err := d.login(); err != nil { return err } - return d.conn.Rename(srcObj.GetPath(), stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName)) + return d.conn.Rename( + encode(srcObj.GetPath(), d.Encoding), + encode(stdpath.Join(stdpath.Dir(srcObj.GetPath()), newName), d.Encoding), + ) } func (d *FTP) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { @@ -100,10 +106,11 @@ func (d *FTP) Remove(ctx context.Context, obj model.Obj) error { if err := d.login(); err != nil { return err } + path := encode(obj.GetPath(), d.Encoding) if obj.IsDir() { - return d.conn.RemoveDirRecur(obj.GetPath()) + return d.conn.RemoveDirRecur(path) } else { - return d.conn.Delete(obj.GetPath()) + return d.conn.Delete(path) } } @@ -112,7 +119,8 @@ func (d *FTP) Put(ctx context.Context, dstDir model.Obj, stream model.FileStream return err } // TODO: support cancel - return d.conn.Stor(stdpath.Join(dstDir.GetPath(), stream.GetName()), stream) + path := stdpath.Join(dstDir.GetPath(), stream.GetName()) + return d.conn.Stor(encode(path, d.Encoding), stream) } var _ driver.Driver = (*FTP)(nil) diff --git a/drivers/ftp/meta.go b/drivers/ftp/meta.go index 61d9d4a824e..5652c12e184 100644 --- a/drivers/ftp/meta.go +++ b/drivers/ftp/meta.go @@ -3,10 +3,28 @@ package ftp import ( "github.com/alist-org/alist/v3/internal/driver" "github.com/alist-org/alist/v3/internal/op" + "github.com/axgle/mahonia" ) +func encode(str string, encoding string) string { + if encoding == "" { + return str + } + encoder := mahonia.NewEncoder(encoding) + return encoder.ConvertString(str) +} + +func decode(str string, encoding string) string { + if encoding == "" { + return str + } + decoder := mahonia.NewDecoder(encoding) + return decoder.ConvertString(str) +} + type Addition struct { Address string `json:"address" required:"true"` + Encoding string `json:"encoding" required:"true"` Username string `json:"username" required:"true"` Password string `json:"password" required:"true"` driver.RootPath diff --git a/go.mod b/go.mod index cbe21348d0e..b18ff9373fb 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( github.com/aead/ecdh v0.2.0 // indirect github.com/andreburgaud/crypt2go v1.2.0 // indirect github.com/andybalholm/brotli v1.0.4 // indirect + github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/go.sum b/go.sum index f84330a873f..de6005d153e 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevB github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.50.24 h1:3o2Pg7mOoVL0jv54vWtuafoZqAeEXLhm1tltWA2GcEw= github.com/aws/aws-sdk-go v1.50.24/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= +github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=