fix: 189 family cloud upload (#761)

pull/774/head
foxxorcat 2022-03-16 14:22:42 +08:00 committed by GitHub
parent 58426613f6
commit 2dbedc245c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 52 deletions

View File

@ -16,7 +16,6 @@ import (
"github.com/Xhofe/alist/utils" "github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
"github.com/google/uuid" "github.com/google/uuid"
jsoniter "github.com/json-iterator/go"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -110,7 +109,7 @@ func (s *State) login(account *model.Account) error {
if err != nil { if err != nil {
return err return err
} }
toUrl := jsoniter.Get(res.Body(), "toUrl").ToString() toUrl := utils.Json.Get(res.Body(), "toUrl").ToString()
if toUrl == "" { if toUrl == "" {
log.Error(res.String()) log.Error(res.String())
return fmt.Errorf(res.String()) return fmt.Errorf(res.String())
@ -179,10 +178,10 @@ func (s *State) getLoginParam() (*LoginParam, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if jsoniter.Get(vRes.Body(), "status").ToInt() != 200 { if utils.Json.Get(vRes.Body(), "status").ToInt() != 200 {
return nil, errors.New("ocr error:" + jsoniter.Get(vRes.Body(), "msg").ToString()) return nil, errors.New("ocr error:" + utils.Json.Get(vRes.Body(), "msg").ToString())
} }
param.vCodeRS = jsoniter.Get(vRes.Body(), "result").ToString() param.vCodeRS = utils.Json.Get(vRes.Body(), "result").ToString()
log.Debugln("code: ", param.vCodeRS) log.Debugln("code: ", param.vCodeRS)
} }
return param, nil return param, nil
@ -308,9 +307,9 @@ func (s *State) Request(method string, fullUrl string, params url.Values, callba
} }
if account != nil { if account != nil {
switch jsoniter.Get(res.Body(), "res_code").ToInt64() { switch utils.Json.Get(res.Body(), "res_code").ToInt64() {
case 11, 18: case 11, 18:
if err := s.refreshSession(account); err != nil { if err := s.RefreshSession(account); err != nil {
return nil, err return nil, err
} }
return s.Request(method, fullUrl, params, callback, account) return s.Request(method, fullUrl, params, callback, account)
@ -324,8 +323,8 @@ func (s *State) Request(method string, fullUrl string, params url.Values, callba
} }
} }
if jsoniter.Get(res.Body(), "res_code").ToInt64() != 0 { if utils.Json.Get(res.Body(), "res_code").ToInt64() != 0 {
return res, fmt.Errorf(jsoniter.Get(res.Body(), "res_message").ToString()) return res, fmt.Errorf(utils.Json.Get(res.Body(), "res_message").ToString())
} }
return res, nil return res, nil
} }

View File

@ -3,7 +3,6 @@ package _189
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -64,9 +63,10 @@ func (driver Cloud189) Items() []base.Item {
Values: "Personal,Family", Values: "Personal,Family",
}, },
{ {
Name: "site_id", Name: "site_id",
Label: "family id", Label: "family id",
Type: base.TypeString, Type: base.TypeString,
Required: true,
}, },
{ {
Name: "order_by", Name: "order_by",
@ -96,13 +96,41 @@ func (driver Cloud189) Save(account *model.Account, old *model.Account) error {
state := GetState(account) state := GetState(account)
if !state.IsLogin() { if !state.IsLogin() {
return state.Login(account) if err := state.Login(account); err != nil {
return err
}
} }
if isFamily(account) {
list, err := driver.getFamilyInfoList(account)
if err != nil {
return err
}
for _, l := range list {
if account.SiteId == "" {
account.SiteId = fmt.Sprint(l.FamilyID)
}
log.Infof("天翼家庭云 用户名:%s FamilyID %d\n", l.RemarkName, l.FamilyID)
}
}
account.Status = "work" account.Status = "work"
model.SaveAccount(account) model.SaveAccount(account)
return nil return nil
} }
func (driver Cloud189) getFamilyInfoList(account *model.Account) ([]FamilyInfoResp, error) {
var resp FamilyInfoListResp
_, err := GetState(account).Request("GET", API_URL+"/family/manage/getFamilyList.action", nil, func(r *resty.Request) {
r.SetQueryParams(clientSuffix())
r.SetResult(&resp)
}, account)
if err != nil {
return nil, err
}
return resp.FamilyInfoResp, nil
}
func (driver Cloud189) File(path string, account *model.Account) (*model.File, error) { func (driver Cloud189) File(path string, account *model.Account) (*model.File, error) {
path = utils.ParsePath(path) path = utils.ParsePath(path)
if path == "/" { if path == "/" {
@ -329,7 +357,7 @@ func (driver Cloud189) Move(src string, dst string, account *model.Account) erro
_, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) { _, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) {
r.SetFormData(clientSuffix()).SetFormData(map[string]string{ r.SetFormData(clientSuffix()).SetFormData(map[string]string{
"type": "MOVE", "type": "MOVE",
"taskInfos": string(MustToBytes(json.Marshal( "taskInfos": string(MustToBytes(utils.Json.Marshal(
[]*BatchTaskInfo{ []*BatchTaskInfo{
{ {
FileId: srcFile.Id, FileId: srcFile.Id,
@ -445,7 +473,7 @@ func (driver Cloud189) Copy(src string, dst string, account *model.Account) erro
_, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) { _, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) {
r.SetFormData(clientSuffix()).SetFormData(map[string]string{ r.SetFormData(clientSuffix()).SetFormData(map[string]string{
"type": "COPY", "type": "COPY",
"taskInfos": string(MustToBytes(json.Marshal( "taskInfos": string(MustToBytes(utils.Json.Marshal(
[]*BatchTaskInfo{ []*BatchTaskInfo{
{ {
FileId: srcFile.Id, FileId: srcFile.Id,
@ -475,7 +503,7 @@ func (driver Cloud189) Delete(path string, account *model.Account) error {
_, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) { _, err = GetState(account).Request("POST", API_URL+"/batch/createBatchTask.action", nil, func(r *resty.Request) {
r.SetFormData(clientSuffix()).SetFormData(map[string]string{ r.SetFormData(clientSuffix()).SetFormData(map[string]string{
"type": "DELETE", "type": "DELETE",
"taskInfos": string(MustToBytes(json.Marshal( "taskInfos": string(MustToBytes(utils.Json.Marshal(
[]*BatchTaskInfo{ []*BatchTaskInfo{
{ {
FileId: srcFile.Id, FileId: srcFile.Id,
@ -546,7 +574,7 @@ func (driver Cloud189) uploadFamily(file *model.FileStream, parentFile *model.Fi
} }
if createUpload.FileDataExists != 1 { if createUpload.FileDataExists != 1 {
if err = driver.uploadFileData(file, tempFile, createUpload, account); err != nil { if createUpload.UploadFileId, err = driver.uploadFileData(file, tempFile, createUpload, account); err != nil {
return err return err
} }
} }
@ -601,7 +629,7 @@ func (driver Cloud189) uploadPerson(file *model.FileStream, parentFile *model.Fi
} }
if createUpload.FileDataExists != 1 { if createUpload.FileDataExists != 1 {
if err = driver.uploadFileData(file, tempFile, createUpload, account); err != nil { if createUpload.UploadFileId, err = driver.uploadFileData(file, tempFile, createUpload, account); err != nil {
return err return err
} }
} }
@ -618,40 +646,39 @@ func (driver Cloud189) uploadPerson(file *model.FileStream, parentFile *model.Fi
return err return err
} }
func (driver Cloud189) uploadFileData(file *model.FileStream, tempFile *os.File, createUpload CreateUploadFileResult, account *model.Account) error { func (driver Cloud189) uploadFileData(file *model.FileStream, tempFile *os.File, createUpload CreateUploadFileResult, account *model.Account) (int64, error) {
var uploadFileState *UploadFileStatusResult uploadFileState, err := driver.getUploadFileState(createUpload.UploadFileId, account)
var err error if err != nil {
for i := 0; i < 10; i++ { return 0, err
if uploadFileState, err = driver.getUploadFileState(createUpload.UploadFileId, account); err != nil {
return err
}
if uploadFileState.FileDataExists == 1 || uploadFileState.DataSize == int64(file.Size) {
return nil
}
if _, err = tempFile.Seek(uploadFileState.DataSize, io.SeekStart); err != nil {
return err
}
_, err = GetState(account).Request("PUT", uploadFileState.FileUploadUrl, nil, func(r *resty.Request) {
r.SetQueryParams(clientSuffix())
r.SetHeaders(map[string]string{
"ResumePolicy": "1",
"Edrive-UploadFileId": fmt.Sprint(createUpload.UploadFileId),
"Edrive-UploadFileRange": fmt.Sprintf("bytes=%d-%d", uploadFileState.DataSize, file.Size),
"Expect": "100-continue",
})
if isFamily(account) {
r.SetHeader("FamilyId", account.SiteId)
}
r.SetBody(tempFile)
}, account)
if err == nil {
break
}
} }
return err
if uploadFileState.FileDataExists == 1 || uploadFileState.DataSize == int64(file.Size) {
return uploadFileState.UploadFileId, nil
}
if _, err = tempFile.Seek(uploadFileState.DataSize, io.SeekStart); err != nil {
return 0, err
}
_, err = GetState(account).Request("PUT", uploadFileState.FileUploadUrl, nil, func(r *resty.Request) {
r.SetQueryParams(clientSuffix())
r.SetHeaders(map[string]string{
"Content-Type": "application/octet-stream",
"ResumePolicy": "1",
"Edrive-UploadFileRange": fmt.Sprintf("bytes=%d-%d", uploadFileState.DataSize, file.Size),
"Expect": "100-continue",
})
if isFamily(account) {
r.SetHeaders(map[string]string{
"familyId": account.SiteId,
"UploadFileId": fmt.Sprint(uploadFileState.UploadFileId),
})
} else {
r.SetHeader("Edrive-UploadFileId", fmt.Sprint(uploadFileState.UploadFileId))
}
r.SetBody(tempFile)
}, account)
return uploadFileState.UploadFileId, err
} }
func (driver Cloud189) getUploadFileState(uploadFileId int64, account *model.Account) (*UploadFileStatusResult, error) { func (driver Cloud189) getUploadFileState(uploadFileId int64, account *model.Account) (*UploadFileStatusResult, error) {

View File

@ -60,6 +60,19 @@ type appSessionResp struct {
RefreshToken string `json:"refreshToken"` RefreshToken string `json:"refreshToken"`
} }
type FamilyInfoListResp struct {
FamilyInfoResp []FamilyInfoResp `json:"familyInfoResp"`
}
type FamilyInfoResp struct {
Count int `json:"count"`
CreateTime string `json:"createTime"`
FamilyID int `json:"familyId"`
RemarkName string `json:"remarkName"`
Type int `json:"type"`
UseFlag int `json:"useFlag"`
UserRole int `json:"userRole"`
}
/*文件部分*/ /*文件部分*/
// 文件 // 文件
type Cloud189File struct { type Cloud189File struct {