feat: add `UC` driver (close #1127 in #4459)

Co-authored-by: lj98568 <lj98568@alibaba-inc.com>
Co-authored-by: Andy Hsu <i@nn.ci>
pull/4492/head
zqxiaojin 2023-05-27 19:36:14 +08:00 committed by GitHub
parent ef68f84787
commit 89f76d7899
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 89 additions and 56 deletions

View File

@ -62,6 +62,7 @@ English | [中文](./README_cn.md) | [Contributing](./CONTRIBUTING.md) | [CODE_O
- [x] [YandexDisk](https://disk.yandex.com/)
- [x] [BaiduNetdisk](http://pan.baidu.com/)
- [x] [Terabox](https://www.terabox.com/main)
- [x] [UC](https://drive.uc.cn)
- [x] [Quark](https://pan.quark.cn)
- [x] [Thunder](https://pan.xunlei.com)
- [x] [Lanzou](https://www.lanzou.com/)

View File

@ -61,6 +61,7 @@
- [x] [和彩云](https://yun.139.com/) (个人云, 家庭云)
- [x] [Yandex.Disk](https://disk.yandex.com/)
- [x] [百度网盘](http://pan.baidu.com/)
- [x] [UC网盘](https://drive.uc.cn)
- [x] [夸克网盘](https://pan.quark.cn)
- [x] [迅雷网盘](https://pan.xunlei.com)
- [x] [蓝奏云](https://www.lanzou.com/)

View File

@ -28,7 +28,7 @@ import (
_ "github.com/alist-org/alist/v3/drivers/onedrive_app"
_ "github.com/alist-org/alist/v3/drivers/pikpak"
_ "github.com/alist-org/alist/v3/drivers/pikpak_share"
_ "github.com/alist-org/alist/v3/drivers/quark"
_ "github.com/alist-org/alist/v3/drivers/quark_uc"
_ "github.com/alist-org/alist/v3/drivers/s3"
_ "github.com/alist-org/alist/v3/drivers/seafile"
_ "github.com/alist-org/alist/v3/drivers/sftp"

View File

@ -1,26 +0,0 @@
package quark
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Cookie string `json:"cookie" required:"true"`
driver.RootID
OrderBy string `json:"order_by" type:"select" options:"none,file_type,file_name,updated_at" default:"none"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
}
var config = driver.Config{
Name: "Quark",
OnlyLocal: true,
DefaultRoot: "0",
NoOverwriteUpload: true,
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &Quark{}
})
}

View File

@ -22,29 +22,31 @@ import (
log "github.com/sirupsen/logrus"
)
type Quark struct {
type QuarkOrUC struct {
model.Storage
Addition
config driver.Config
conf Conf
}
func (d *Quark) Config() driver.Config {
return config
func (d *QuarkOrUC) Config() driver.Config {
return d.config
}
func (d *Quark) GetAddition() driver.Additional {
func (d *QuarkOrUC) GetAddition() driver.Additional {
return &d.Addition
}
func (d *Quark) Init(ctx context.Context) error {
func (d *QuarkOrUC) Init(ctx context.Context) error {
_, err := d.request("/config", http.MethodGet, nil, nil)
return err
}
func (d *Quark) Drop(ctx context.Context) error {
func (d *QuarkOrUC) Drop(ctx context.Context) error {
return nil
}
func (d *Quark) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
func (d *QuarkOrUC) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
files, err := d.GetFiles(dir.GetID())
if err != nil {
return nil, err
@ -54,12 +56,12 @@ func (d *Quark) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([
})
}
func (d *Quark) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
func (d *QuarkOrUC) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
data := base.Json{
"fids": []string{file.GetID()},
}
var resp DownResp
ua := "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch"
ua := d.conf.ua
_, err := d.request("/file/download", http.MethodPost, func(req *resty.Request) {
req.SetHeader("User-Agent", ua).
SetBody(data)
@ -103,7 +105,7 @@ func (d *Quark) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
req.Header.Set("Range", _range)
req.Header.Set("User-Agent", ua)
req.Header.Set("Cookie", d.Cookie)
req.Header.Set("Referer", "https://pan.quark.cn")
req.Header.Set("Referer", d.conf.referer)
resp, err := base.HttpClient.Do(req)
if err != nil {
return err
@ -125,7 +127,7 @@ func (d *Quark) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
return &link, nil
}
func (d *Quark) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
func (d *QuarkOrUC) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
data := base.Json{
"dir_init_lock": false,
"dir_path": "",
@ -141,7 +143,7 @@ func (d *Quark) MakeDir(ctx context.Context, parentDir model.Obj, dirName string
return err
}
func (d *Quark) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
func (d *QuarkOrUC) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
data := base.Json{
"action_type": 1,
"exclude_fids": []string{},
@ -154,7 +156,7 @@ func (d *Quark) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
return err
}
func (d *Quark) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
func (d *QuarkOrUC) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
data := base.Json{
"fid": srcObj.GetID(),
"file_name": newName,
@ -165,11 +167,11 @@ func (d *Quark) Rename(ctx context.Context, srcObj model.Obj, newName string) er
return err
}
func (d *Quark) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
func (d *QuarkOrUC) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errs.NotSupport
}
func (d *Quark) Remove(ctx context.Context, obj model.Obj) error {
func (d *QuarkOrUC) Remove(ctx context.Context, obj model.Obj) error {
data := base.Json{
"action_type": 1,
"exclude_fids": []string{},
@ -181,7 +183,7 @@ func (d *Quark) Remove(ctx context.Context, obj model.Obj) error {
return err
}
func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
func (d *QuarkOrUC) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
tempFile, err := utils.CreateTempFile(stream.GetReadCloser())
if err != nil {
return err
@ -266,4 +268,4 @@ func (d *Quark) Put(ctx context.Context, dstDir model.Obj, stream model.FileStre
return d.upFinish(pre)
}
var _ driver.Driver = (*Quark)(nil)
var _ driver.Driver = (*QuarkOrUC)(nil)

55
drivers/quark_uc/meta.go Normal file
View File

@ -0,0 +1,55 @@
package quark
import (
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/op"
)
type Addition struct {
Cookie string `json:"cookie" required:"true"`
driver.RootID
OrderBy string `json:"order_by" type:"select" options:"none,file_type,file_name,updated_at" default:"none"`
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
}
type Conf struct {
ua string
referer string
api string
pr string
}
func init() {
op.RegisterDriver(func() driver.Driver {
return &QuarkOrUC{
config: driver.Config{
Name: "Quark",
OnlyLocal: true,
DefaultRoot: "0",
NoOverwriteUpload: true,
},
conf: Conf{
ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch",
referer: "https://pan.quark.cn",
api: "https://drive.quark.cn/1/clouddrive",
pr: "ucpro",
},
}
})
op.RegisterDriver(func() driver.Driver {
return &QuarkOrUC{
config: driver.Config{
Name: "UC",
OnlyLocal: true,
DefaultRoot: "0",
NoOverwriteUpload: true,
},
conf: Conf{
ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) uc-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch",
referer: "https://drive.uc.cn",
api: "https://pc-api.uc.cn/1/clouddrive",
pr: "UCBrowser",
},
}
})
}

View File

@ -22,15 +22,15 @@ import (
// do others that not defined in Driver interface
func (d *Quark) request(pathname string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
u := "https://drive.quark.cn/1/clouddrive" + pathname
func (d *QuarkOrUC) request(pathname string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
u := d.conf.api + pathname
req := base.RestyClient.R()
req.SetHeaders(map[string]string{
"Cookie": d.Cookie,
"Accept": "application/json, text/plain, */*",
"Referer": "https://pan.quark.cn/",
"Referer": d.conf.referer,
})
req.SetQueryParam("pr", "ucpro")
req.SetQueryParam("pr", d.conf.pr)
req.SetQueryParam("fr", "pc")
if callback != nil {
callback(req)
@ -55,7 +55,7 @@ func (d *Quark) request(pathname string, method string, callback base.ReqCallbac
return res.Body(), nil
}
func (d *Quark) GetFiles(parent string) ([]File, error) {
func (d *QuarkOrUC) GetFiles(parent string) ([]File, error) {
files := make([]File, 0)
page := 1
size := 100
@ -85,7 +85,7 @@ func (d *Quark) GetFiles(parent string) ([]File, error) {
return files, nil
}
func (d *Quark) upPre(file model.FileStreamer, parentId string) (UpPreResp, error) {
func (d *QuarkOrUC) upPre(file model.FileStreamer, parentId string) (UpPreResp, error) {
now := time.Now()
data := base.Json{
"ccp_hash_update": true,
@ -105,7 +105,7 @@ func (d *Quark) upPre(file model.FileStreamer, parentId string) (UpPreResp, erro
return resp, err
}
func (d *Quark) upHash(md5, sha1, taskId string) (bool, error) {
func (d *QuarkOrUC) upHash(md5, sha1, taskId string) (bool, error) {
data := base.Json{
"md5": md5,
"sha1": sha1,
@ -119,8 +119,8 @@ func (d *Quark) upHash(md5, sha1, taskId string) (bool, error) {
return resp.Data.Finish, err
}
func (d *Quark) upPart(ctx context.Context, pre UpPreResp, mineType string, partNumber int, bytes []byte) (string, error) {
//func (driver Quark) UpPart(pre UpPreResp, mineType string, partNumber int, bytes []byte, account *model.Account, md5Str, sha1Str string) (string, error) {
func (d *QuarkOrUC) upPart(ctx context.Context, pre UpPreResp, mineType string, partNumber int, bytes []byte) (string, error) {
//func (driver QuarkOrUC) UpPart(pre UpPreResp, mineType string, partNumber int, bytes []byte, account *model.Account, md5Str, sha1Str string) (string, error) {
timeStr := time.Now().UTC().Format(http.TimeFormat)
data := base.Json{
"auth_info": pre.Data.AuthInfo,
@ -169,7 +169,7 @@ x-oss-user-agent:aliyun-sdk-js/6.6.1 Chrome 98.0.4758.80 on Windows 10 64-bit
return res.Header().Get("ETag"), nil
}
func (d *Quark) upCommit(pre UpPreResp, md5s []string) error {
func (d *QuarkOrUC) upCommit(pre UpPreResp, md5s []string) error {
timeStr := time.Now().UTC().Format(http.TimeFormat)
log.Debugf("md5s: %+v", md5s)
bodyBuilder := strings.Builder{}
@ -236,7 +236,7 @@ x-oss-user-agent:aliyun-sdk-js/6.6.1 Chrome 98.0.4758.80 on Windows 10 64-bit
return nil
}
func (d *Quark) upFinish(pre UpPreResp) error {
func (d *QuarkOrUC) upFinish(pre UpPreResp) error {
data := base.Json{
"obj_key": pre.Data.ObjKey,
"task_id": pre.Data.TaskId,

View File

@ -19,7 +19,7 @@ type LinkArgs struct {
type Link struct {
URL string `json:"url"`
Header http.Header `json:"header"` // needed header
Header http.Header `json:"header"` // needed header (for url) or response header(for data or writer)
Data io.ReadCloser // return file reader directly
Status int // status maybe 200 or 206, etc
FilePath *string // local file, return the filepath