diff --git a/drivers/123/driver.go b/drivers/123/driver.go index 32c053e2..cf221fee 100644 --- a/drivers/123/driver.go +++ b/drivers/123/driver.go @@ -6,6 +6,8 @@ import ( "fmt" "net/http" "net/url" + "strconv" + "strings" "sync" "time" @@ -28,7 +30,8 @@ import ( type Pan123 struct { model.Storage Addition - apiRateLimit sync.Map + apiRateLimit sync.Map + safeBoxUnlocked sync.Map } func (d *Pan123) Config() driver.Config { @@ -52,9 +55,26 @@ func (d *Pan123) Drop(ctx context.Context) error { } func (d *Pan123) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { + if f, ok := dir.(File); ok && f.IsLock { + if err := d.unlockSafeBox(f.FileId); err != nil { + return nil, err + } + } files, err := d.getFiles(ctx, dir.GetID(), dir.GetName()) if err != nil { - return nil, err + msg := strings.ToLower(err.Error()) + if strings.Contains(msg, "safe box") || strings.Contains(err.Error(), "保险箱") { + if id, e := strconv.ParseInt(dir.GetID(), 10, 64); e == nil { + if e = d.unlockSafeBox(id); e == nil { + files, err = d.getFiles(ctx, dir.GetID(), dir.GetName()) + } else { + return nil, e + } + } + } + if err != nil { + return nil, err + } } return utils.SliceConvert(files, func(src File) (model.Obj, error) { return src, nil diff --git a/drivers/123/meta.go b/drivers/123/meta.go index cb2cbc15..6c5f013a 100644 --- a/drivers/123/meta.go +++ b/drivers/123/meta.go @@ -6,8 +6,9 @@ import ( ) type Addition struct { - Username string `json:"username" required:"true"` - Password string `json:"password" required:"true"` + Username string `json:"username" required:"true"` + Password string `json:"password" required:"true"` + SafePassword string `json:"safe_password"` driver.RootID //OrderBy string `json:"order_by" type:"select" options:"file_id,file_name,size,update_at" default:"file_name"` //OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"` diff --git a/drivers/123/types.go b/drivers/123/types.go index a8682c52..962e5fbd 100644 --- a/drivers/123/types.go +++ b/drivers/123/types.go @@ -20,6 +20,7 @@ type File struct { Etag string `json:"Etag"` S3KeyFlag string `json:"S3KeyFlag"` DownloadUrl string `json:"DownloadUrl"` + IsLock bool `json:"IsLock"` } func (f File) CreateTime() time.Time { diff --git a/drivers/123/util.go b/drivers/123/util.go index b85c9afb..bca54b59 100644 --- a/drivers/123/util.go +++ b/drivers/123/util.go @@ -43,6 +43,7 @@ const ( S3Auth = MainApi + "/file/s3_upload_object/auth" UploadCompleteV2 = MainApi + "/file/upload_complete/v2" S3Complete = MainApi + "/file/s3_complete_multipart_upload" + SafeBoxUnlock = MainApi + "/restful/goapi/v1/file/safe_box/auth/unlockbox" //AuthKeySalt = "8-8D$sL8gPjom7bk#cY" ) @@ -238,6 +239,22 @@ do: return body, nil } +func (d *Pan123) unlockSafeBox(fileId int64) error { + if _, ok := d.safeBoxUnlocked.Load(fileId); ok { + return nil + } + data := base.Json{"password": d.SafePassword} + url := fmt.Sprintf("%s?fileId=%d", SafeBoxUnlock, fileId) + _, err := d.Request(url, http.MethodPost, func(req *resty.Request) { + req.SetBody(data) + }, nil) + if err != nil { + return err + } + d.safeBoxUnlocked.Store(fileId, true) + return nil +} + func (d *Pan123) getFiles(ctx context.Context, parentId string, name string) ([]File, error) { page := 1 total := 0 @@ -267,6 +284,15 @@ func (d *Pan123) getFiles(ctx context.Context, parentId string, name string) ([] req.SetQueryParams(query) }, &resp) if err != nil { + msg := strings.ToLower(err.Error()) + if strings.Contains(msg, "safe box") || strings.Contains(err.Error(), "保险箱") { + if fid, e := strconv.ParseInt(parentId, 10, 64); e == nil { + if e = d.unlockSafeBox(fid); e == nil { + return d.getFiles(ctx, parentId, name) + } + return nil, e + } + } return nil, err } log.Debug(string(_res))