From d122d1d19187a03a22c0945608e84a8e7f703330 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 21 Sep 2019 13:24:30 +0100 Subject: [PATCH] qingstor: use lib/encoder --- backend/qingstor/qingstor.go | 21 ++++++++++++++------- docs/content/qingstor.md | 9 +++++++++ fs/encodings/encodings.go | 9 ++++++++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/backend/qingstor/qingstor.go b/backend/qingstor/qingstor.go index 77a712dd5..1b62bc52c 100644 --- a/backend/qingstor/qingstor.go +++ b/backend/qingstor/qingstor.go @@ -20,6 +20,7 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/config/configmap" "github.com/rclone/rclone/fs/config/configstruct" + "github.com/rclone/rclone/fs/encodings" "github.com/rclone/rclone/fs/fshttp" "github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/walk" @@ -29,6 +30,8 @@ import ( qs "github.com/yunify/qingstor-sdk-go/v3/service" ) +const enc = encodings.QingStor + // Register with Fs func init() { fs.Register(&fs.RegInfo{ @@ -184,7 +187,8 @@ func parsePath(path string) (root string) { // split returns bucket and bucketPath from the rootRelativePath // relative to f.root func (f *Fs) split(rootRelativePath string) (bucketName, bucketPath string) { - return bucket.Split(path.Join(f.root, rootRelativePath)) + bucketName, bucketPath = bucket.Split(path.Join(f.root, rootRelativePath)) + return enc.FromStandardName(bucketName), enc.FromStandardPath(bucketPath) } // split returns bucket and bucketPath from the object @@ -353,7 +357,8 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) { if err != nil { return nil, err } - _, err = bucketInit.HeadObject(f.rootDirectory, &qs.HeadObjectInput{}) + encodedDirectory := enc.FromStandardPath(f.rootDirectory) + _, err = bucketInit.HeadObject(encodedDirectory, &qs.HeadObjectInput{}) if err == nil { newRoot := path.Dir(f.root) if newRoot == "." { @@ -550,6 +555,7 @@ func (f *Fs) list(ctx context.Context, bucket, directory, prefix string, addBuck continue } remote := *commonPrefix + remote = enc.ToStandardPath(remote) if !strings.HasPrefix(remote, prefix) { fs.Logf(f, "Odd name received %q", remote) continue @@ -569,12 +575,13 @@ func (f *Fs) list(ctx context.Context, bucket, directory, prefix string, addBuck } for _, object := range resp.Keys { - key := qs.StringValue(object.Key) - if !strings.HasPrefix(key, prefix) { - fs.Logf(f, "Odd name received %q", key) + remote := qs.StringValue(object.Key) + remote = enc.ToStandardPath(remote) + if !strings.HasPrefix(remote, prefix) { + fs.Logf(f, "Odd name received %q", remote) continue } - remote := key[len(prefix):] + remote = remote[len(prefix):] if addBucket { remote = path.Join(bucket, remote) } @@ -646,7 +653,7 @@ func (f *Fs) listBuckets(ctx context.Context) (entries fs.DirEntries, err error) } for _, bucket := range resp.Buckets { - d := fs.NewDir(qs.StringValue(bucket.Name), qs.TimeValue(bucket.Created)) + d := fs.NewDir(enc.ToStandardName(qs.StringValue(bucket.Name)), qs.TimeValue(bucket.Created)) entries = append(entries, d) } return entries, nil diff --git a/docs/content/qingstor.md b/docs/content/qingstor.md index af1446755..8b892fd13 100644 --- a/docs/content/qingstor.md +++ b/docs/content/qingstor.md @@ -126,6 +126,15 @@ credentials. In order of precedence: - Access Key ID: `QS_ACCESS_KEY_ID` or `QS_ACCESS_KEY` - Secret Access Key: `QS_SECRET_ACCESS_KEY` or `QS_SECRET_KEY` +### Restricted filename characters + +The control characters 0x00-0x1F and / are replaced as in the [default +restricted characters set](/overview/#restricted-characters). Note +that 0x7F is not replaced. + +Invalid UTF-8 bytes will also be [replaced](/overview/#invalid-utf8), +as they can't be used in JSON strings. + ### Standard Options diff --git a/fs/encodings/encodings.go b/fs/encodings/encodings.go index dcbda8854..673c53f09 100644 --- a/fs/encodings/encodings.go +++ b/fs/encodings/encodings.go @@ -271,6 +271,12 @@ const AzureBlob = encoder.MultiEncoder( encoder.EncodeBackSlash | encoder.EncodeRightPeriod) +// QingStor is the encoding used by the qingstor backend +const QingStor = encoder.MultiEncoder( + encoder.EncodeInvalidUtf8 | + encoder.EncodeCtl | + encoder.EncodeSlash) + // ByName returns the encoder for a give backend name or nil func ByName(name string) encoder.Encoder { switch strings.ToLower(name) { @@ -316,7 +322,8 @@ func ByName(name string) encoder.Encoder { return OpenDrive case "pcloud": return Pcloud - //case "qingstor": + case "qingstor": + return QingStor case "s3": return S3 //case "sftp":