File size: 10,054 Bytes
215df2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
package _189pc

import (
	"encoding/xml"
	"fmt"
	"sort"
	"strings"
	"time"

	"github.com/alist-org/alist/v3/pkg/utils"
)

// 居然有四种返回方式
type RespErr struct {
	ResCode    any    `json:"res_code"` // int or string
	ResMessage string `json:"res_message"`

	Error_ string `json:"error"`

	XMLName xml.Name `xml:"error"`
	Code    string   `json:"code" xml:"code"`
	Message string   `json:"message" xml:"message"`
	Msg     string   `json:"msg"`

	ErrorCode string `json:"errorCode"`
	ErrorMsg  string `json:"errorMsg"`
}

func (e *RespErr) HasError() bool {
	switch v := e.ResCode.(type) {
	case int, int64, int32:
		return v != 0
	case string:
		return e.ResCode != ""
	}
	return (e.Code != "" && e.Code != "SUCCESS") || e.ErrorCode != "" || e.Error_ != ""
}

func (e *RespErr) Error() string {
	switch v := e.ResCode.(type) {
	case int, int64, int32:
		if v != 0 {
			return fmt.Sprintf("res_code: %d ,res_msg: %s", v, e.ResMessage)
		}
	case string:
		if e.ResCode != "" {
			return fmt.Sprintf("res_code: %s ,res_msg: %s", e.ResCode, e.ResMessage)
		}
	}

	if e.Code != "" && e.Code != "SUCCESS" {
		if e.Msg != "" {
			return fmt.Sprintf("code: %s ,msg: %s", e.Code, e.Msg)
		}
		if e.Message != "" {
			return fmt.Sprintf("code: %s ,msg: %s", e.Code, e.Message)
		}
		return "code: " + e.Code
	}

	if e.ErrorCode != "" {
		return fmt.Sprintf("err_code: %s ,err_msg: %s", e.ErrorCode, e.ErrorMsg)
	}

	if e.Error_ != "" {
		return fmt.Sprintf("error: %s ,message: %s", e.ErrorCode, e.Message)
	}
	return ""
}

// 登陆需要的参数
type LoginParam struct {
	// 加密后的用户名和密码
	RsaUsername string
	RsaPassword string

	// rsa密钥
	jRsaKey string

	// 请求头参数
	Lt    string
	ReqId string

	// 表单参数
	ParamId string

	// 验证码
	CaptchaToken string
}

// 登陆加密相关
type EncryptConfResp struct {
	Result int `json:"result"`
	Data   struct {
		UpSmsOn   string `json:"upSmsOn"`
		Pre       string `json:"pre"`
		PreDomain string `json:"preDomain"`
		PubKey    string `json:"pubKey"`
	} `json:"data"`
}

type LoginResp struct {
	Msg    string `json:"msg"`
	Result int    `json:"result"`
	ToUrl  string `json:"toUrl"`
}

// 刷新session返回
type UserSessionResp struct {
	ResCode    int    `json:"res_code"`
	ResMessage string `json:"res_message"`

	LoginName string `json:"loginName"`

	KeepAlive       int `json:"keepAlive"`
	GetFileDiffSpan int `json:"getFileDiffSpan"`
	GetUserInfoSpan int `json:"getUserInfoSpan"`

	// 个人云
	SessionKey    string `json:"sessionKey"`
	SessionSecret string `json:"sessionSecret"`
	// 家庭云
	FamilySessionKey    string `json:"familySessionKey"`
	FamilySessionSecret string `json:"familySessionSecret"`
}

// 登录返回
type AppSessionResp struct {
	UserSessionResp

	IsSaveName string `json:"isSaveName"`

	// 会话刷新Token
	AccessToken string `json:"accessToken"`
	//Token刷新
	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 {
	ID   String `json:"id"`
	Name string `json:"name"`
	Size int64  `json:"size"`
	Md5  string `json:"md5"`

	LastOpTime Time `json:"lastOpTime"`
	CreateDate Time `json:"createDate"`
	Icon       struct {
		//iconOption 5
		SmallUrl string `json:"smallUrl"`
		LargeUrl string `json:"largeUrl"`

		// iconOption 10
		Max600    string `json:"max600"`
		MediumURL string `json:"mediumUrl"`
	} `json:"icon"`

	// Orientation int64  `json:"orientation"`
	// FileCata   int64  `json:"fileCata"`
	// MediaType   int    `json:"mediaType"`
	// Rev         string `json:"rev"`
	// StarLabel   int64  `json:"starLabel"`
}

func (c *Cloud189File) CreateTime() time.Time {
	return time.Time(c.CreateDate)
}

func (c *Cloud189File) GetHash() utils.HashInfo {
	return utils.NewHashInfo(utils.MD5, c.Md5)
}

func (c *Cloud189File) GetSize() int64     { return c.Size }
func (c *Cloud189File) GetName() string    { return c.Name }
func (c *Cloud189File) ModTime() time.Time { return time.Time(c.LastOpTime) }
func (c *Cloud189File) IsDir() bool        { return false }
func (c *Cloud189File) GetID() string      { return string(c.ID) }
func (c *Cloud189File) GetPath() string    { return "" }
func (c *Cloud189File) Thumb() string      { return c.Icon.SmallUrl }

// 文件夹
type Cloud189Folder struct {
	ID       String `json:"id"`
	ParentID int64  `json:"parentId"`
	Name     string `json:"name"`

	LastOpTime Time `json:"lastOpTime"`
	CreateDate Time `json:"createDate"`

	// FileListSize int64 `json:"fileListSize"`
	// FileCount int64 `json:"fileCount"`
	// FileCata  int64 `json:"fileCata"`
	// Rev          string `json:"rev"`
	// StarLabel    int64  `json:"starLabel"`
}

func (c *Cloud189Folder) CreateTime() time.Time {
	return time.Time(c.CreateDate)
}

func (c *Cloud189Folder) GetHash() utils.HashInfo {
	return utils.HashInfo{}
}

func (c *Cloud189Folder) GetSize() int64     { return 0 }
func (c *Cloud189Folder) GetName() string    { return c.Name }
func (c *Cloud189Folder) ModTime() time.Time { return time.Time(c.LastOpTime) }
func (c *Cloud189Folder) IsDir() bool        { return true }
func (c *Cloud189Folder) GetID() string      { return string(c.ID) }
func (c *Cloud189Folder) GetPath() string    { return "" }

type Cloud189FilesResp struct {
	//ResCode    int    `json:"res_code"`
	//ResMessage string `json:"res_message"`
	FileListAO struct {
		Count      int              `json:"count"`
		FileList   []Cloud189File   `json:"fileList"`
		FolderList []Cloud189Folder `json:"folderList"`
	} `json:"fileListAO"`
}

// TaskInfo 任务信息
type BatchTaskInfo struct {
	// FileId 文件ID
	FileId string `json:"fileId"`
	// FileName 文件名
	FileName string `json:"fileName"`
	// IsFolder 是否是文件夹,0-否,1-是
	IsFolder int `json:"isFolder"`
	// SrcParentId 文件所在父目录ID
	SrcParentId string `json:"srcParentId,omitempty"`

	/* 冲突管理 */
	// 1 -> 跳过 2 -> 保留 3 -> 覆盖
	DealWay    int `json:"dealWay,omitempty"`
	IsConflict int `json:"isConflict,omitempty"`
}

/* 上传部分 */
type InitMultiUploadResp struct {
	//Code string `json:"code"`
	Data struct {
		UploadType     int    `json:"uploadType"`
		UploadHost     string `json:"uploadHost"`
		UploadFileID   string `json:"uploadFileId"`
		FileDataExists int    `json:"fileDataExists"`
	} `json:"data"`
}
type UploadUrlsResp struct {
	Code string                    `json:"code"`
	Data map[string]UploadUrlsData `json:"uploadUrls"`
}
type UploadUrlsData struct {
	RequestURL    string `json:"requestURL"`
	RequestHeader string `json:"requestHeader"`
}

type UploadUrlInfo struct {
	PartNumber int
	Headers    map[string]string
	UploadUrlsData
}

type UploadProgress struct {
	UploadInfo  InitMultiUploadResp
	UploadParts []string
}

/* 第二种上传方式 */
type CreateUploadFileResp struct {
	// 上传文件请求ID
	UploadFileId int64 `json:"uploadFileId"`
	// 上传文件数据的URL路径
	FileUploadUrl string `json:"fileUploadUrl"`
	// 上传文件完成后确认路径
	FileCommitUrl string `json:"fileCommitUrl"`
	// 文件是否已存在云盘中,0-未存在,1-已存在
	FileDataExists int `json:"fileDataExists"`
}

type GetUploadFileStatusResp struct {
	CreateUploadFileResp

	// 已上传的大小
	DataSize int64 `json:"dataSize"`
	Size     int64 `json:"size"`
}

func (r *GetUploadFileStatusResp) GetSize() int64 {
	return r.DataSize + r.Size
}

type CommitMultiUploadFileResp struct {
	File struct {
		UserFileID String `json:"userFileId"`
		FileName   string `json:"fileName"`
		FileSize   int64  `json:"fileSize"`
		FileMd5    string `json:"fileMd5"`
		CreateDate Time   `json:"createDate"`
	} `json:"file"`
}

func (f *CommitMultiUploadFileResp) toFile() *Cloud189File {
	return &Cloud189File{
		ID:         f.File.UserFileID,
		Name:       f.File.FileName,
		Size:       f.File.FileSize,
		Md5:        f.File.FileMd5,
		LastOpTime: f.File.CreateDate,
		CreateDate: f.File.CreateDate,
	}
}

type OldCommitUploadFileResp struct {
	XMLName    xml.Name `xml:"file"`
	ID         String   `xml:"id"`
	Name       string   `xml:"name"`
	Size       int64    `xml:"size"`
	Md5        string   `xml:"md5"`
	CreateDate Time     `xml:"createDate"`
}

func (f *OldCommitUploadFileResp) toFile() *Cloud189File {
	return &Cloud189File{
		ID:         f.ID,
		Name:       f.Name,
		Size:       f.Size,
		Md5:        f.Md5,
		CreateDate: f.CreateDate,
		LastOpTime: f.CreateDate,
	}
}

type CreateBatchTaskResp struct {
	TaskID string `json:"taskId"`
}

type BatchTaskStateResp struct {
	FailedCount         int     `json:"failedCount"`
	Process             int     `json:"process"`
	SkipCount           int     `json:"skipCount"`
	SubTaskCount        int     `json:"subTaskCount"`
	SuccessedCount      int     `json:"successedCount"`
	SuccessedFileIDList []int64 `json:"successedFileIdList"`
	TaskID              string  `json:"taskId"`
	TaskStatus          int     `json:"taskStatus"` //1 初始化 2 存在冲突 3 执行中,4 完成
}

type BatchTaskConflictTaskInfoResp struct {
	SessionKey     string `json:"sessionKey"`
	TargetFolderID int    `json:"targetFolderId"`
	TaskID         string `json:"taskId"`
	TaskInfos      []BatchTaskInfo
	TaskType       int `json:"taskType"`
}

/* query 加密参数*/
type Params map[string]string

func (p Params) Set(k, v string) {
	p[k] = v
}

func (p Params) Encode() string {
	if p == nil {
		return ""
	}
	var buf strings.Builder
	keys := make([]string, 0, len(p))
	for k := range p {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for i := range keys {
		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(keys[i])
		buf.WriteByte('=')
		buf.WriteString(p[keys[i]])
	}
	return buf.String()
}