feat(139): support new personal cloud api (#5690)
Co-authored-by: Andy Hsu <i@nn.ci>
This commit is contained in:
parent
6d4ab57a0e
commit
de56f926cf
@ -35,25 +35,40 @@ func (d *Yun139) Init(ctx context.Context) error {
|
|||||||
if d.Authorization == "" {
|
if d.Authorization == "" {
|
||||||
return fmt.Errorf("authorization is empty")
|
return fmt.Errorf("authorization is empty")
|
||||||
}
|
}
|
||||||
decode, err := base64.StdEncoding.DecodeString(d.Authorization)
|
switch d.Addition.Type {
|
||||||
if err != nil {
|
case MetaPersonalNew:
|
||||||
return err
|
if len(d.Addition.RootFolderID) == 0 {
|
||||||
}
|
d.RootFolderID = "/"
|
||||||
decodeStr := string(decode)
|
}
|
||||||
splits := strings.Split(decodeStr, ":")
|
return nil
|
||||||
if len(splits) < 2 {
|
case MetaPersonal:
|
||||||
return fmt.Errorf("authorization is invalid, splits < 2")
|
if len(d.Addition.RootFolderID) == 0 {
|
||||||
}
|
d.RootFolderID = "root"
|
||||||
d.Account = splits[1]
|
}
|
||||||
_, err = d.post("/orchestration/personalCloud/user/v1.0/qryUserExternInfo", base.Json{
|
fallthrough
|
||||||
"qryUserExternInfoReq": base.Json{
|
case MetaFamily:
|
||||||
"commonAccountInfo": base.Json{
|
decode, err := base64.StdEncoding.DecodeString(d.Authorization)
|
||||||
"account": d.Account,
|
if err != nil {
|
||||||
"accountType": 1,
|
return err
|
||||||
|
}
|
||||||
|
decodeStr := string(decode)
|
||||||
|
splits := strings.Split(decodeStr, ":")
|
||||||
|
if len(splits) < 2 {
|
||||||
|
return fmt.Errorf("authorization is invalid, splits < 2")
|
||||||
|
}
|
||||||
|
d.Account = splits[1]
|
||||||
|
_, err = d.post("/orchestration/personalCloud/user/v1.0/qryUserExternInfo", base.Json{
|
||||||
|
"qryUserExternInfoReq": base.Json{
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}, nil)
|
||||||
}, nil)
|
return err
|
||||||
return err
|
default:
|
||||||
|
return errs.NotImplement
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Drop(ctx context.Context) error {
|
func (d *Yun139) Drop(ctx context.Context) error {
|
||||||
@ -61,35 +76,65 @@ func (d *Yun139) Drop(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
func (d *Yun139) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
||||||
if d.isFamily() {
|
switch d.Addition.Type {
|
||||||
return d.familyGetFiles(dir.GetID())
|
case MetaPersonalNew:
|
||||||
} else {
|
return d.personalGetFiles(dir.GetID())
|
||||||
|
case MetaPersonal:
|
||||||
return d.getFiles(dir.GetID())
|
return d.getFiles(dir.GetID())
|
||||||
|
case MetaFamily:
|
||||||
|
return d.familyGetFiles(dir.GetID())
|
||||||
|
default:
|
||||||
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
func (d *Yun139) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||||
u, err := d.getLink(file.GetID())
|
var url string
|
||||||
|
var err error
|
||||||
|
switch d.Addition.Type {
|
||||||
|
case MetaPersonalNew:
|
||||||
|
url, err = d.personalGetLink(file.GetID())
|
||||||
|
case MetaPersonal:
|
||||||
|
fallthrough
|
||||||
|
case MetaFamily:
|
||||||
|
url, err = d.getLink(file.GetID())
|
||||||
|
default:
|
||||||
|
return nil, errs.NotImplement
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &model.Link{URL: u}, nil
|
return &model.Link{URL: url}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
data := base.Json{
|
var err error
|
||||||
"createCatalogExtReq": base.Json{
|
switch d.Addition.Type {
|
||||||
"parentCatalogID": parentDir.GetID(),
|
case MetaPersonalNew:
|
||||||
"newCatalogName": dirName,
|
data := base.Json{
|
||||||
"commonAccountInfo": base.Json{
|
"parentFileId": parentDir.GetID(),
|
||||||
"account": d.Account,
|
"name": dirName,
|
||||||
"accountType": 1,
|
"description": "",
|
||||||
|
"type": "folder",
|
||||||
|
"fileRenameMode": "force_rename",
|
||||||
|
}
|
||||||
|
pathname := "/hcy/file/create"
|
||||||
|
_, err = d.personalPost(pathname, data, nil)
|
||||||
|
case MetaPersonal:
|
||||||
|
data := base.Json{
|
||||||
|
"createCatalogExtReq": base.Json{
|
||||||
|
"parentCatalogID": parentDir.GetID(),
|
||||||
|
"newCatalogName": dirName,
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
}
|
pathname := "/orchestration/personalCloud/catalog/v1.0/createCatalogExt"
|
||||||
pathname := "/orchestration/personalCloud/catalog/v1.0/createCatalogExt"
|
_, err = d.post(pathname, data, nil)
|
||||||
if d.isFamily() {
|
case MetaFamily:
|
||||||
data = base.Json{
|
data := base.Json{
|
||||||
"cloudID": d.CloudID,
|
"cloudID": d.CloudID,
|
||||||
"commonAccountInfo": base.Json{
|
"commonAccountInfo": base.Json{
|
||||||
"account": d.Account,
|
"account": d.Account,
|
||||||
@ -97,147 +142,198 @@ func (d *Yun139) MakeDir(ctx context.Context, parentDir model.Obj, dirName strin
|
|||||||
},
|
},
|
||||||
"docLibName": dirName,
|
"docLibName": dirName,
|
||||||
}
|
}
|
||||||
pathname = "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
|
pathname := "/orchestration/familyCloud/cloudCatalog/v1.0/createCloudDoc"
|
||||||
|
_, err = d.post(pathname, data, nil)
|
||||||
|
default:
|
||||||
|
err = errs.NotImplement
|
||||||
}
|
}
|
||||||
_, err := d.post(pathname, data, nil)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
func (d *Yun139) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
||||||
if d.isFamily() {
|
switch d.Addition.Type {
|
||||||
|
case MetaPersonalNew:
|
||||||
|
data := base.Json{
|
||||||
|
"fileIds": []string{srcObj.GetID()},
|
||||||
|
"toParentFileId": dstDir.GetID(),
|
||||||
|
}
|
||||||
|
pathname := "/hcy/file/batchMove"
|
||||||
|
_, err := d.personalPost(pathname, data, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return srcObj, nil
|
||||||
|
case MetaPersonal:
|
||||||
|
var contentInfoList []string
|
||||||
|
var catalogInfoList []string
|
||||||
|
if srcObj.IsDir() {
|
||||||
|
catalogInfoList = append(catalogInfoList, srcObj.GetID())
|
||||||
|
} else {
|
||||||
|
contentInfoList = append(contentInfoList, srcObj.GetID())
|
||||||
|
}
|
||||||
|
data := base.Json{
|
||||||
|
"createBatchOprTaskReq": base.Json{
|
||||||
|
"taskType": 3,
|
||||||
|
"actionType": "304",
|
||||||
|
"taskInfo": base.Json{
|
||||||
|
"contentInfoList": contentInfoList,
|
||||||
|
"catalogInfoList": catalogInfoList,
|
||||||
|
"newCatalogID": dstDir.GetID(),
|
||||||
|
},
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
||||||
|
_, err := d.post(pathname, data, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return srcObj, nil
|
||||||
|
default:
|
||||||
return nil, errs.NotImplement
|
return nil, errs.NotImplement
|
||||||
}
|
}
|
||||||
var contentInfoList []string
|
|
||||||
var catalogInfoList []string
|
|
||||||
if srcObj.IsDir() {
|
|
||||||
catalogInfoList = append(catalogInfoList, srcObj.GetID())
|
|
||||||
} else {
|
|
||||||
contentInfoList = append(contentInfoList, srcObj.GetID())
|
|
||||||
}
|
|
||||||
data := base.Json{
|
|
||||||
"createBatchOprTaskReq": base.Json{
|
|
||||||
"taskType": 3,
|
|
||||||
"actionType": "304",
|
|
||||||
"taskInfo": base.Json{
|
|
||||||
"contentInfoList": contentInfoList,
|
|
||||||
"catalogInfoList": catalogInfoList,
|
|
||||||
"newCatalogID": dstDir.GetID(),
|
|
||||||
},
|
|
||||||
"commonAccountInfo": base.Json{
|
|
||||||
"account": d.Account,
|
|
||||||
"accountType": 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
|
||||||
_, err := d.post(pathname, data, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return srcObj, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
func (d *Yun139) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||||
if d.isFamily() {
|
var err error
|
||||||
return errs.NotImplement
|
switch d.Addition.Type {
|
||||||
}
|
case MetaPersonalNew:
|
||||||
var data base.Json
|
data := base.Json{
|
||||||
var pathname string
|
"fileId": srcObj.GetID(),
|
||||||
if srcObj.IsDir() {
|
"name": newName,
|
||||||
data = base.Json{
|
"description": "",
|
||||||
"catalogID": srcObj.GetID(),
|
|
||||||
"catalogName": newName,
|
|
||||||
"commonAccountInfo": base.Json{
|
|
||||||
"account": d.Account,
|
|
||||||
"accountType": 1,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
pathname = "/orchestration/personalCloud/catalog/v1.0/updateCatalogInfo"
|
pathname := "/hcy/file/update"
|
||||||
} else {
|
_, err = d.personalPost(pathname, data, nil)
|
||||||
data = base.Json{
|
case MetaPersonal:
|
||||||
"contentID": srcObj.GetID(),
|
var data base.Json
|
||||||
"contentName": newName,
|
var pathname string
|
||||||
"commonAccountInfo": base.Json{
|
if srcObj.IsDir() {
|
||||||
"account": d.Account,
|
data = base.Json{
|
||||||
"accountType": 1,
|
"catalogID": srcObj.GetID(),
|
||||||
},
|
"catalogName": newName,
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pathname = "/orchestration/personalCloud/catalog/v1.0/updateCatalogInfo"
|
||||||
|
} else {
|
||||||
|
data = base.Json{
|
||||||
|
"contentID": srcObj.GetID(),
|
||||||
|
"contentName": newName,
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pathname = "/orchestration/personalCloud/content/v1.0/updateContentInfo"
|
||||||
}
|
}
|
||||||
pathname = "/orchestration/personalCloud/content/v1.0/updateContentInfo"
|
_, err = d.post(pathname, data, nil)
|
||||||
|
default:
|
||||||
|
err = errs.NotImplement
|
||||||
}
|
}
|
||||||
_, err := d.post(pathname, data, nil)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
func (d *Yun139) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||||
if d.isFamily() {
|
var err error
|
||||||
return errs.NotImplement
|
switch d.Addition.Type {
|
||||||
}
|
case MetaPersonalNew:
|
||||||
var contentInfoList []string
|
data := base.Json{
|
||||||
var catalogInfoList []string
|
"fileIds": []string{srcObj.GetID()},
|
||||||
if srcObj.IsDir() {
|
"toParentFileId": dstDir.GetID(),
|
||||||
catalogInfoList = append(catalogInfoList, srcObj.GetID())
|
}
|
||||||
} else {
|
pathname := "/hcy/file/batchCopy"
|
||||||
contentInfoList = append(contentInfoList, srcObj.GetID())
|
_, err := d.personalPost(pathname, data, nil)
|
||||||
}
|
return err
|
||||||
data := base.Json{
|
case MetaPersonal:
|
||||||
"createBatchOprTaskReq": base.Json{
|
var contentInfoList []string
|
||||||
"taskType": 3,
|
var catalogInfoList []string
|
||||||
"actionType": 309,
|
if srcObj.IsDir() {
|
||||||
"taskInfo": base.Json{
|
catalogInfoList = append(catalogInfoList, srcObj.GetID())
|
||||||
"contentInfoList": contentInfoList,
|
} else {
|
||||||
"catalogInfoList": catalogInfoList,
|
contentInfoList = append(contentInfoList, srcObj.GetID())
|
||||||
"newCatalogID": dstDir.GetID(),
|
}
|
||||||
|
data := base.Json{
|
||||||
|
"createBatchOprTaskReq": base.Json{
|
||||||
|
"taskType": 3,
|
||||||
|
"actionType": 309,
|
||||||
|
"taskInfo": base.Json{
|
||||||
|
"contentInfoList": contentInfoList,
|
||||||
|
"catalogInfoList": catalogInfoList,
|
||||||
|
"newCatalogID": dstDir.GetID(),
|
||||||
|
},
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"commonAccountInfo": base.Json{
|
}
|
||||||
"account": d.Account,
|
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
||||||
"accountType": 1,
|
_, err = d.post(pathname, data, nil)
|
||||||
},
|
default:
|
||||||
},
|
err = errs.NotImplement
|
||||||
}
|
}
|
||||||
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
|
||||||
_, err := d.post(pathname, data, nil)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Remove(ctx context.Context, obj model.Obj) error {
|
func (d *Yun139) Remove(ctx context.Context, obj model.Obj) error {
|
||||||
var contentInfoList []string
|
switch d.Addition.Type {
|
||||||
var catalogInfoList []string
|
case MetaPersonalNew:
|
||||||
if obj.IsDir() {
|
data := base.Json{
|
||||||
catalogInfoList = append(catalogInfoList, obj.GetID())
|
"fileIds": []string{obj.GetID()},
|
||||||
} else {
|
|
||||||
contentInfoList = append(contentInfoList, obj.GetID())
|
|
||||||
}
|
|
||||||
data := base.Json{
|
|
||||||
"createBatchOprTaskReq": base.Json{
|
|
||||||
"taskType": 2,
|
|
||||||
"actionType": 201,
|
|
||||||
"taskInfo": base.Json{
|
|
||||||
"newCatalogID": "",
|
|
||||||
"contentInfoList": contentInfoList,
|
|
||||||
"catalogInfoList": catalogInfoList,
|
|
||||||
},
|
|
||||||
"commonAccountInfo": base.Json{
|
|
||||||
"account": d.Account,
|
|
||||||
"accountType": 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
|
||||||
if d.isFamily() {
|
|
||||||
data = base.Json{
|
|
||||||
"catalogList": catalogInfoList,
|
|
||||||
"contentList": contentInfoList,
|
|
||||||
"commonAccountInfo": base.Json{
|
|
||||||
"account": d.Account,
|
|
||||||
"accountType": 1,
|
|
||||||
},
|
|
||||||
"sourceCatalogType": 1002,
|
|
||||||
"taskType": 2,
|
|
||||||
}
|
}
|
||||||
pathname = "/orchestration/familyCloud/batchOprTask/v1.0/createBatchOprTask"
|
pathname := "/hcy/recyclebin/batchTrash"
|
||||||
|
_, err := d.personalPost(pathname, data, nil)
|
||||||
|
return err
|
||||||
|
case MetaPersonal:
|
||||||
|
fallthrough
|
||||||
|
case MetaFamily:
|
||||||
|
var contentInfoList []string
|
||||||
|
var catalogInfoList []string
|
||||||
|
if obj.IsDir() {
|
||||||
|
catalogInfoList = append(catalogInfoList, obj.GetID())
|
||||||
|
} else {
|
||||||
|
contentInfoList = append(contentInfoList, obj.GetID())
|
||||||
|
}
|
||||||
|
data := base.Json{
|
||||||
|
"createBatchOprTaskReq": base.Json{
|
||||||
|
"taskType": 2,
|
||||||
|
"actionType": 201,
|
||||||
|
"taskInfo": base.Json{
|
||||||
|
"newCatalogID": "",
|
||||||
|
"contentInfoList": contentInfoList,
|
||||||
|
"catalogInfoList": catalogInfoList,
|
||||||
|
},
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pathname := "/orchestration/personalCloud/batchOprTask/v1.0/createBatchOprTask"
|
||||||
|
if d.isFamily() {
|
||||||
|
data = base.Json{
|
||||||
|
"catalogList": catalogInfoList,
|
||||||
|
"contentList": contentInfoList,
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
"sourceCatalogType": 1002,
|
||||||
|
"taskType": 2,
|
||||||
|
}
|
||||||
|
pathname = "/orchestration/familyCloud/batchOprTask/v1.0/createBatchOprTask"
|
||||||
|
}
|
||||||
|
_, err := d.post(pathname, data, nil)
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
return errs.NotImplement
|
||||||
}
|
}
|
||||||
_, err := d.post(pathname, data, nil)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -257,94 +353,208 @@ func getPartSize(size int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Yun139) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
data := base.Json{
|
switch d.Addition.Type {
|
||||||
"manualRename": 2,
|
case MetaPersonalNew:
|
||||||
"operation": 0,
|
var err error
|
||||||
"fileCount": 1,
|
fullHash := stream.GetHash().GetHash(utils.SHA256)
|
||||||
"totalSize": 0, // 去除上传大小限制
|
if len(fullHash) <= 0 {
|
||||||
"uploadContentList": []base.Json{{
|
tmpF, err := stream.CacheFullInTempFile()
|
||||||
"contentName": stream.GetName(),
|
if err != nil {
|
||||||
"contentSize": 0, // 去除上传大小限制
|
return err
|
||||||
// "digest": "5a3231986ce7a6b46e408612d385bafa"
|
}
|
||||||
}},
|
fullHash, err = utils.HashFile(utils.SHA256, tmpF)
|
||||||
"parentCatalogID": dstDir.GetID(),
|
if err != nil {
|
||||||
"newCatalogName": "",
|
return err
|
||||||
"commonAccountInfo": base.Json{
|
}
|
||||||
"account": d.Account,
|
}
|
||||||
"accountType": 1,
|
// return errs.NotImplement
|
||||||
},
|
data := base.Json{
|
||||||
}
|
"contentHash": fullHash,
|
||||||
pathname := "/orchestration/personalCloud/uploadAndDownload/v1.0/pcUploadFileRequest"
|
"contentHashAlgorithm": "SHA256",
|
||||||
if d.isFamily() {
|
"contentType": "application/octet-stream",
|
||||||
data = d.newJson(base.Json{
|
"parallelUpload": false,
|
||||||
"fileCount": 1,
|
"partInfos": []base.Json{{
|
||||||
"manualRename": 2,
|
"parallelHashCtx": base.Json{
|
||||||
"operation": 0,
|
"partOffset": 0,
|
||||||
"path": "",
|
},
|
||||||
"seqNo": "",
|
"partNumber": 1,
|
||||||
"totalSize": 0,
|
"partSize": stream.GetSize(),
|
||||||
"uploadContentList": []base.Json{{
|
|
||||||
"contentName": stream.GetName(),
|
|
||||||
"contentSize": 0,
|
|
||||||
// "digest": "5a3231986ce7a6b46e408612d385bafa"
|
|
||||||
}},
|
}},
|
||||||
})
|
"size": stream.GetSize(),
|
||||||
pathname = "/orchestration/familyCloud/content/v1.0/getFileUploadURL"
|
"parentFileId": dstDir.GetID(),
|
||||||
return errs.NotImplement
|
"name": stream.GetName(),
|
||||||
}
|
"type": "file",
|
||||||
var resp UploadResp
|
"fileRenameMode": "auto_rename",
|
||||||
_, err := d.post(pathname, data, &resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Progress
|
|
||||||
p := driver.NewProgress(stream.GetSize(), up)
|
|
||||||
|
|
||||||
var partSize = getPartSize(stream.GetSize())
|
|
||||||
part := (stream.GetSize() + partSize - 1) / partSize
|
|
||||||
if part == 0 {
|
|
||||||
part = 1
|
|
||||||
}
|
|
||||||
for i := int64(0); i < part; i++ {
|
|
||||||
if utils.IsCanceled(ctx) {
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
}
|
||||||
|
pathname := "/hcy/file/create"
|
||||||
start := i * partSize
|
var resp PersonalUploadResp
|
||||||
byteSize := stream.GetSize() - start
|
_, err = d.personalPost(pathname, data, &resp)
|
||||||
if byteSize > partSize {
|
|
||||||
byteSize = partSize
|
|
||||||
}
|
|
||||||
|
|
||||||
limitReader := io.LimitReader(stream, byteSize)
|
|
||||||
// Update Progress
|
|
||||||
r := io.TeeReader(limitReader, p)
|
|
||||||
req, err := http.NewRequest("POST", resp.Data.UploadResult.RedirectionURL, r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resp.Data.Exist || resp.Data.RapidUpload {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progress
|
||||||
|
p := driver.NewProgress(stream.GetSize(), up)
|
||||||
|
|
||||||
|
// Update Progress
|
||||||
|
r := io.TeeReader(stream, p)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PUT", resp.Data.PartInfos[0].UploadUrl, r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
req.Header.Set("Content-Type", "text/plain;name="+unicode(stream.GetName()))
|
req.Header.Set("Content-Type", "application/octet-stream")
|
||||||
req.Header.Set("contentSize", strconv.FormatInt(stream.GetSize(), 10))
|
req.Header.Set("Content-Length", fmt.Sprint(stream.GetSize()))
|
||||||
req.Header.Set("range", fmt.Sprintf("bytes=%d-%d", start, start+byteSize-1))
|
req.Header.Set("Origin", "https://yun.139.com")
|
||||||
req.Header.Set("uploadtaskID", resp.Data.UploadResult.UploadTaskID)
|
req.Header.Set("Referer", "https://yun.139.com/")
|
||||||
req.Header.Set("rangeType", "0")
|
req.ContentLength = stream.GetSize()
|
||||||
req.ContentLength = byteSize
|
|
||||||
|
|
||||||
res, err := base.HttpClient.Do(req)
|
res, err := base.HttpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = res.Body.Close()
|
_ = res.Body.Close()
|
||||||
log.Debugf("%+v", res)
|
log.Debugf("%+v", res)
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
data = base.Json{
|
||||||
|
"contentHash": fullHash,
|
||||||
|
"contentHashAlgorithm": "SHA256",
|
||||||
|
"fileId": resp.Data.FileId,
|
||||||
|
"uploadId": resp.Data.UploadId,
|
||||||
|
}
|
||||||
|
_, err = d.personalPost("/hcy/file/complete", data, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
case MetaPersonal:
|
||||||
|
fallthrough
|
||||||
|
case MetaFamily:
|
||||||
|
data := base.Json{
|
||||||
|
"manualRename": 2,
|
||||||
|
"operation": 0,
|
||||||
|
"fileCount": 1,
|
||||||
|
"totalSize": 0, // 去除上传大小限制
|
||||||
|
"uploadContentList": []base.Json{{
|
||||||
|
"contentName": stream.GetName(),
|
||||||
|
"contentSize": 0, // 去除上传大小限制
|
||||||
|
// "digest": "5a3231986ce7a6b46e408612d385bafa"
|
||||||
|
}},
|
||||||
|
"parentCatalogID": dstDir.GetID(),
|
||||||
|
"newCatalogName": "",
|
||||||
|
"commonAccountInfo": base.Json{
|
||||||
|
"account": d.Account,
|
||||||
|
"accountType": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pathname := "/orchestration/personalCloud/uploadAndDownload/v1.0/pcUploadFileRequest"
|
||||||
|
if d.isFamily() {
|
||||||
|
// data = d.newJson(base.Json{
|
||||||
|
// "fileCount": 1,
|
||||||
|
// "manualRename": 2,
|
||||||
|
// "operation": 0,
|
||||||
|
// "path": "",
|
||||||
|
// "seqNo": "",
|
||||||
|
// "totalSize": 0,
|
||||||
|
// "uploadContentList": []base.Json{{
|
||||||
|
// "contentName": stream.GetName(),
|
||||||
|
// "contentSize": 0,
|
||||||
|
// // "digest": "5a3231986ce7a6b46e408612d385bafa"
|
||||||
|
// }},
|
||||||
|
// })
|
||||||
|
// pathname = "/orchestration/familyCloud/content/v1.0/getFileUploadURL"
|
||||||
|
return errs.NotImplement
|
||||||
|
}
|
||||||
|
var resp UploadResp
|
||||||
|
_, err := d.post(pathname, data, &resp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progress
|
||||||
|
p := driver.NewProgress(stream.GetSize(), up)
|
||||||
|
|
||||||
|
var partSize = getPartSize(stream.GetSize())
|
||||||
|
part := (stream.GetSize() + partSize - 1) / partSize
|
||||||
|
if part == 0 {
|
||||||
|
part = 1
|
||||||
|
}
|
||||||
|
for i := int64(0); i < part; i++ {
|
||||||
|
if utils.IsCanceled(ctx) {
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
start := i * partSize
|
||||||
|
byteSize := stream.GetSize() - start
|
||||||
|
if byteSize > partSize {
|
||||||
|
byteSize = partSize
|
||||||
|
}
|
||||||
|
|
||||||
|
limitReader := io.LimitReader(stream, byteSize)
|
||||||
|
// Update Progress
|
||||||
|
r := io.TeeReader(limitReader, p)
|
||||||
|
req, err := http.NewRequest("POST", resp.Data.UploadResult.RedirectionURL, r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
req.Header.Set("Content-Type", "text/plain;name="+unicode(stream.GetName()))
|
||||||
|
req.Header.Set("contentSize", strconv.FormatInt(stream.GetSize(), 10))
|
||||||
|
req.Header.Set("range", fmt.Sprintf("bytes=%d-%d", start, start+byteSize-1))
|
||||||
|
req.Header.Set("uploadtaskID", resp.Data.UploadResult.UploadTaskID)
|
||||||
|
req.Header.Set("rangeType", "0")
|
||||||
|
req.ContentLength = byteSize
|
||||||
|
|
||||||
|
res, err := base.HttpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_ = res.Body.Close()
|
||||||
|
log.Debugf("%+v", res)
|
||||||
|
if res.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return errs.NotImplement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Yun139) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
|
||||||
|
switch d.Addition.Type {
|
||||||
|
case MetaPersonalNew:
|
||||||
|
var resp base.Json
|
||||||
|
var uri string
|
||||||
|
data := base.Json{
|
||||||
|
"category": "video",
|
||||||
|
"fileId": args.Obj.GetID(),
|
||||||
|
}
|
||||||
|
switch args.Method {
|
||||||
|
case "video_preview":
|
||||||
|
uri = "/hcy/videoPreview/getPreviewInfo"
|
||||||
|
default:
|
||||||
|
return nil, errs.NotSupport
|
||||||
|
}
|
||||||
|
_, err := d.personalPost(uri, data, &resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp["data"], nil
|
||||||
|
default:
|
||||||
|
return nil, errs.NotImplement
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ driver.Driver = (*Yun139)(nil)
|
var _ driver.Driver = (*Yun139)(nil)
|
||||||
|
@ -9,7 +9,7 @@ type Addition struct {
|
|||||||
//Account string `json:"account" required:"true"`
|
//Account string `json:"account" required:"true"`
|
||||||
Authorization string `json:"authorization" type:"text" required:"true"`
|
Authorization string `json:"authorization" type:"text" required:"true"`
|
||||||
driver.RootID
|
driver.RootID
|
||||||
Type string `json:"type" type:"select" options:"personal,family" default:"personal"`
|
Type string `json:"type" type:"select" options:"personal,family,personal_new" default:"personal"`
|
||||||
CloudID string `json:"cloud_id"`
|
CloudID string `json:"cloud_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
package _139
|
package _139
|
||||||
|
|
||||||
|
const (
|
||||||
|
MetaPersonal string = "personal"
|
||||||
|
MetaFamily string = "family"
|
||||||
|
MetaPersonalNew string = "personal_new"
|
||||||
|
)
|
||||||
|
|
||||||
type BaseResp struct {
|
type BaseResp struct {
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
@ -185,3 +191,42 @@ type QueryContentListResp struct {
|
|||||||
RecallContent interface{} `json:"recallContent"`
|
RecallContent interface{} `json:"recallContent"`
|
||||||
} `json:"data"`
|
} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PersonalThumbnail struct {
|
||||||
|
Style string `json:"style"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PersonalFileItem struct {
|
||||||
|
FileId string `json:"fileId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
CreatedAt string `json:"createdAt"`
|
||||||
|
UpdatedAt string `json:"updatedAt"`
|
||||||
|
Thumbnails []PersonalThumbnail `json:"thumbnailUrls"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PersonalListResp struct {
|
||||||
|
BaseResp
|
||||||
|
Data struct {
|
||||||
|
Items []PersonalFileItem `json:"items"`
|
||||||
|
NextPageCursor string `json:"nextPageCursor"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PersonalPartInfo struct {
|
||||||
|
PartNumber int `json:"partNumber"`
|
||||||
|
UploadUrl string `json:"uploadUrl"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PersonalUploadResp struct {
|
||||||
|
BaseResp
|
||||||
|
Data struct {
|
||||||
|
FileId string `json:"fileId"`
|
||||||
|
PartInfos []PersonalPartInfo `json:"partInfos"`
|
||||||
|
Exist bool `json:"exist"`
|
||||||
|
RapidUpload bool `json:"rapidUpload"`
|
||||||
|
UploadId string `json:"uploadId"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -252,3 +252,154 @@ func unicode(str string) string {
|
|||||||
textUnquoted := textQuoted[1 : len(textQuoted)-1]
|
textUnquoted := textQuoted[1 : len(textQuoted)-1]
|
||||||
return textUnquoted
|
return textUnquoted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Yun139) personalRequest(pathname string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||||
|
url := "https://personal-kd-njs.yun.139.com" + pathname
|
||||||
|
req := base.RestyClient.R()
|
||||||
|
randStr := random.String(16)
|
||||||
|
ts := time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
if callback != nil {
|
||||||
|
callback(req)
|
||||||
|
}
|
||||||
|
body, err := utils.Json.Marshal(req.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sign := calSign(string(body), ts, randStr)
|
||||||
|
svcType := "1"
|
||||||
|
if d.isFamily() {
|
||||||
|
svcType = "2"
|
||||||
|
}
|
||||||
|
req.SetHeaders(map[string]string{
|
||||||
|
"Accept": "application/json, text/plain, */*",
|
||||||
|
"Authorization": "Basic " + d.Authorization,
|
||||||
|
"Caller": "web",
|
||||||
|
"Cms-Device": "default",
|
||||||
|
"Mcloud-Channel": "1000101",
|
||||||
|
"Mcloud-Client": "10701",
|
||||||
|
"Mcloud-Route": "001",
|
||||||
|
"Mcloud-Sign": fmt.Sprintf("%s,%s,%s", ts, randStr, sign),
|
||||||
|
"Mcloud-Version": "7.13.0",
|
||||||
|
"Origin": "https://yun.139.com",
|
||||||
|
"Referer": "https://yun.139.com/w/",
|
||||||
|
"x-DeviceInfo": "||9|7.13.0|chrome|120.0.0.0|||windows 10||zh-CN|||",
|
||||||
|
"x-huawei-channelSrc": "10000034",
|
||||||
|
"x-inner-ntwk": "2",
|
||||||
|
"x-m4c-caller": "PC",
|
||||||
|
"x-m4c-src": "10002",
|
||||||
|
"x-SvcType": svcType,
|
||||||
|
"X-Yun-Api-Version": "v1",
|
||||||
|
"X-Yun-App-Channel": "10000034",
|
||||||
|
"X-Yun-Channel-Source": "10000034",
|
||||||
|
"X-Yun-Client-Info": "||9|7.13.0|chrome|120.0.0.0|||windows 10||zh-CN|||dW5kZWZpbmVk||",
|
||||||
|
"X-Yun-Module-Type": "100",
|
||||||
|
"X-Yun-Svc-Type": "1",
|
||||||
|
})
|
||||||
|
|
||||||
|
var e BaseResp
|
||||||
|
req.SetResult(&e)
|
||||||
|
res, err := req.Execute(method, url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Debugln(res.String())
|
||||||
|
if !e.Success {
|
||||||
|
return nil, errors.New(e.Message)
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
err = utils.Json.Unmarshal(res.Body(), resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.Body(), nil
|
||||||
|
}
|
||||||
|
func (d *Yun139) personalPost(pathname string, data interface{}, resp interface{}) ([]byte, error) {
|
||||||
|
return d.personalRequest(pathname, http.MethodPost, func(req *resty.Request) {
|
||||||
|
req.SetBody(data)
|
||||||
|
}, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPersonalTime(t string) time.Time {
|
||||||
|
stamp, err := time.ParseInLocation("2006-01-02T15:04:05.999-07:00", t, utils.CNLoc)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return stamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Yun139) personalGetFiles(fileId string) ([]model.Obj, error) {
|
||||||
|
files := make([]model.Obj, 0)
|
||||||
|
nextPageCursor := ""
|
||||||
|
for {
|
||||||
|
data := base.Json{
|
||||||
|
"imageThumbnailStyleList": []string{"Small", "Large"},
|
||||||
|
"orderBy": "updated_at",
|
||||||
|
"orderDirection": "DESC",
|
||||||
|
"pageInfo": base.Json{
|
||||||
|
"pageCursor": nextPageCursor,
|
||||||
|
"pageSize": 100,
|
||||||
|
},
|
||||||
|
"parentFileId": fileId,
|
||||||
|
}
|
||||||
|
var resp PersonalListResp
|
||||||
|
_, err := d.personalPost("/hcy/file/list", data, &resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
nextPageCursor = resp.Data.NextPageCursor
|
||||||
|
for _, item := range resp.Data.Items {
|
||||||
|
var isFolder = (item.Type == "folder")
|
||||||
|
var f model.Obj
|
||||||
|
if isFolder {
|
||||||
|
f = &model.Object{
|
||||||
|
ID: item.FileId,
|
||||||
|
Name: item.Name,
|
||||||
|
Size: 0,
|
||||||
|
Modified: getPersonalTime(item.UpdatedAt),
|
||||||
|
Ctime: getPersonalTime(item.CreatedAt),
|
||||||
|
IsFolder: isFolder,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var Thumbnails = item.Thumbnails
|
||||||
|
var ThumbnailUrl string
|
||||||
|
if len(Thumbnails) > 0 {
|
||||||
|
ThumbnailUrl = Thumbnails[len(Thumbnails)-1].Url
|
||||||
|
}
|
||||||
|
f = &model.ObjThumb{
|
||||||
|
Object: model.Object{
|
||||||
|
ID: item.FileId,
|
||||||
|
Name: item.Name,
|
||||||
|
Size: item.Size,
|
||||||
|
Modified: getPersonalTime(item.UpdatedAt),
|
||||||
|
Ctime: getPersonalTime(item.CreatedAt),
|
||||||
|
IsFolder: isFolder,
|
||||||
|
},
|
||||||
|
Thumbnail: model.Thumbnail{Thumbnail: ThumbnailUrl},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
files = append(files, f)
|
||||||
|
}
|
||||||
|
if len(nextPageCursor) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Yun139) personalGetLink(fileId string) (string, error) {
|
||||||
|
data := base.Json{
|
||||||
|
"fileId": fileId,
|
||||||
|
}
|
||||||
|
res, err := d.personalPost("/hcy/file/getDownloadUrl",
|
||||||
|
data, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var cdnUrl = jsoniter.Get(res, "data", "cdnUrl").ToString()
|
||||||
|
if cdnUrl != "" {
|
||||||
|
return cdnUrl, nil
|
||||||
|
} else {
|
||||||
|
return jsoniter.Get(res, "data", "url").ToString(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user