feat: add chaoxing support (#1457)

Co-authored-by: Admin <kbtxwer@qq.com>
This commit is contained in:
kbtxwer
2022-08-13 11:25:50 +08:00
committed by GitHub
parent 51b8b4380d
commit cc74effd30
7 changed files with 540 additions and 1 deletions
+2 -1
View File
@@ -8,7 +8,9 @@ import (
_ "github.com/Xhofe/alist/drivers/alidrive"
_ "github.com/Xhofe/alist/drivers/alist"
_ "github.com/Xhofe/alist/drivers/baidu"
_ "github.com/Xhofe/alist/drivers/baiduphoto"
"github.com/Xhofe/alist/drivers/base"
_ "github.com/Xhofe/alist/drivers/chaoxing"
_ "github.com/Xhofe/alist/drivers/ftp"
_ "github.com/Xhofe/alist/drivers/google"
_ "github.com/Xhofe/alist/drivers/lanzou"
@@ -25,7 +27,6 @@ import (
_ "github.com/Xhofe/alist/drivers/webdav"
_ "github.com/Xhofe/alist/drivers/xunlei"
_ "github.com/Xhofe/alist/drivers/yandex"
_ "github.com/Xhofe/alist/drivers/baiduphoto"
log "github.com/sirupsen/logrus"
"strings"
)
+90
View File
@@ -0,0 +1,90 @@
package template
import (
"errors"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers/base"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/go-resty/resty/v2"
"path"
)
func LoginOrRefreshToken(account *model.Account) error {
return nil
}
func Request(u string, method int, headers, query, form map[string]string, data interface{}, resp interface{}, account *model.Account) ([]byte, error) {
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
"Authorization": "Bearer" + account.AccessToken,
"Accept": "application/json, text/plain, */*",
})
if headers != nil {
req.SetHeaders(headers)
}
if query != nil {
req.SetQueryParams(query)
}
if form != nil {
req.SetFormData(form)
}
if data != nil {
req.SetBody(data)
}
if resp != nil {
req.SetResult(resp)
}
var e Resp
var err error
var res *resty.Response
req.SetError(&e)
switch method {
case base.Get:
res, err = req.Get(u)
case base.Post:
res, err = req.Post(u)
case base.Delete:
res, err = req.Delete(u)
case base.Patch:
res, err = req.Patch(u)
case base.Put:
res, err = req.Put(u)
default:
return nil, base.ErrNotSupport
}
if err != nil {
return nil, err
}
if e.Code >= 400 {
if e.Code == 401 {
err = LoginOrRefreshToken(account)
if err != nil {
return nil, err
}
return Request(u, method, headers, query, form, data, resp, account)
}
return nil, errors.New(e.Message)
}
return res.Body(), nil
}
func (driver ChaoxingDrive) formatFile(f *File) *model.File {
file := model.File{
Id: f.Id,
Name: f.FileName,
Size: f.Size,
Driver: driver.Config().Name,
UpdatedAt: f.UpdatedAt,
}
if f.File {
file.Type = utils.GetFileType(path.Ext(f.FileName))
} else {
file.Type = conf.FOLDER
}
return &file
}
func init() {
base.RegisterDriver(&ChaoxingDrive{})
}
File diff suppressed because it is too large Load Diff
+27
View File
@@ -0,0 +1,27 @@
package template
import "time"
// write all struct here
// TYPE_CX_FILE type=1 文件
var TYPE_CX_FILE = int64(1)
// TYPE_CX_FOLDER type=2 文件夹
var TYPE_CX_FOLDER = int64(2)
// TYPE_CX_SHARED_ROOT type=4 共享文件的根目录
var TYPE_CX_SHARED_ROOT = int64(4)
type Resp struct {
Code int `json:"code"`
Message string `json:"message"`
}
type File struct {
Id string `json:"id"`
FileName string `json:"file_name"`
Size int64 `json:"size"`
File bool `json:"file"`
UpdatedAt *time.Time `json:"updated_at"`
}
+151
View File
@@ -0,0 +1,151 @@
package template
import (
"encoding/json"
"fmt"
"github.com/Xhofe/alist/conf"
"github.com/Xhofe/alist/drivers/base"
"github.com/Xhofe/alist/model"
"github.com/Xhofe/alist/utils"
"github.com/bitly/go-simplejson"
"github.com/go-resty/resty/v2"
"regexp"
"strconv"
"strings"
"time"
)
// write util func here, such as cal sign
var chaoxingClient = resty.New()
var form_login_fmt = "fid=-1&uname=%s&password=%s&t=true&forbidotherlogin=0&validate=&doubleFactorLogin=0"
var api_list_root = "https://pan-yz.chaoxing.com/opt/listres?page=1&size=%d&enc=%s"
var api_list_file = "https://pan-yz.chaoxing.com/opt/listres?puid=%s&shareid=%s&parentId=%s&page=1&size=%d&enc=%s"
var api_list_shared_root = "https://pan-yz.chaoxing.com/opt/listres?puid=0&shareid=-1&parentId=0&page=1&size=%d&enc=%s"
var reg_enc_fmt = regexp.MustCompile("enc[ ]*=\"(.*)\"")
func (driver ChaoxingDrive) Login(account *model.Account) error {
url := "https://passport2.chaoxing.com/fanyalogin"
var resp base.Json
var err Resp
req_body := fmt.Sprintf(form_login_fmt, account.Username, account.Password)
loginReq, e := chaoxingClient.R().SetBody(req_body).
SetResult(&resp).SetError(&err).
SetHeader("Content-Length", strconv.FormatInt(int64(len(req_body)), 10)).
SetHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").
SetHeader("Host", "passport2.chaoxing.com").
SetHeader("User-Agent", " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36").
SetHeader("X-Requested-With", "XMLHttpRequest").
Post(url)
if e != nil {
return e
}
account.AccessToken = ""
for _, cookie := range loginReq.Cookies() {
//route=9d169c0aea4b7c89fa0d073417b5645f;
account.AccessToken += fmt.Sprintf("%s=%s; ", cookie.Name, cookie.Value)
}
return nil
}
func (driver ChaoxingDrive) GetEnc(account *model.Account) error {
url := "https://pan-yz.chaoxing.com/"
encReq, e := chaoxingClient.R().SetHeader("Cookie", account.AccessToken).Get(url)
if e != nil {
return e
}
//直接读取响应
sresp := string(encReq.Body())
submatch := reg_enc_fmt.FindAllStringSubmatch(sresp, 1)
//第一次获取失败,可能是未登录
if len(submatch) == 0 {
e = driver.Login(account)
if e != nil {
return e
}
encReq, e = chaoxingClient.R().SetHeader("Cookie", account.AccessToken).Get(url)
if e != nil {
return e
}
sresp = string(encReq.Body())
submatch = reg_enc_fmt.FindAllStringSubmatch(sresp, 1)
if len(submatch) == 0 {
account.Status = "failed"
return fmt.Errorf("登录失败,服务器返回信息:%s", sresp)
}
}
enc := submatch[0][1]
account.AccessSecret = enc
account.Status = "work"
return nil
}
func (driver ChaoxingDrive) ListFile(folder_id string, account *model.Account) ([]model.File, error) {
var url string
//按规则解析 id 号
folder_id_info := strings.Split(folder_id, "_")
if len(folder_id_info) == 3 {
folder_id = folder_id_info[0]
folder_puid := folder_id_info[1]
folder_shareid := folder_id_info[2]
if folder_id == "0" {
//访问“共享给我的文件夹”
url = fmt.Sprintf(api_list_shared_root, account.Limit, account.AccessSecret)
} else {
//访问其他目录
url = fmt.Sprintf(api_list_file, folder_puid, folder_shareid, folder_id, account.Limit, account.AccessSecret)
}
} else {
//id无法解析为三段,应当是访问根目录(此时为 "")
url = fmt.Sprintf(api_list_root, account.Limit, account.AccessSecret)
}
listFileReq, e := chaoxingClient.R().SetHeader("Cookie", account.AccessToken).Post(url)
resp, e := simplejson.NewJson(listFileReq.Body())
if e != nil || resp == nil {
return nil, e
}
files := make([]model.File, 0)
array, _ := resp.Get("list").Array()
for _, file := range array {
var f = model.File{}
file_ := file.(map[string]interface{})
//f.Id = file_["id"].(string)
f.Id = fmt.Sprintf("%s_%s_%s", file_["id"].(string), file_["puid"].(json.Number).String(), file_["shareid"].(json.Number).String())
f.Name = file_["name"].(string)
f_server_type, _ := file_["type"].(json.Number).Int64()
if f_server_type != TYPE_CX_SHARED_ROOT {
f.Size, _ = file_["filesize"].(json.Number).Int64()
}
// 为文件分配类型
switch f_server_type {
case TYPE_CX_FILE:
{
f.Type = utils.GetFileType(file_["suffix"].(string))
}
case TYPE_CX_FOLDER:
f.Type = conf.FOLDER
case TYPE_CX_SHARED_ROOT:
f.Type = conf.FOLDER
}
modifyDate, e := time.Parse("2006-01-02 15:04:05", file_["modifyDate"].(string))
if e == nil {
f.UpdatedAt = &modifyDate
}
f.Thumbnail = file_["thumbnail"].(string)
files = append(files, f)
}
return files, nil
}
+5
View File
@@ -87,3 +87,8 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/apimachinery v0.0.0-20191123233150-4c4803ed55e3 // indirect
)
require (
github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
)
+4
View File
@@ -1010,3 +1010,7 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=