-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Admin <[email protected]>
- Loading branch information
Showing
7 changed files
with
540 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,261 @@ | ||
package template | ||
|
||
import ( | ||
"fmt" | ||
"github.com/Xhofe/alist/conf" | ||
"github.com/Xhofe/alist/drivers/base" | ||
"github.com/Xhofe/alist/model" | ||
"github.com/Xhofe/alist/utils" | ||
"github.com/robfig/cron/v3" | ||
log "github.com/sirupsen/logrus" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
type ChaoxingDrive struct { | ||
base.Base | ||
} | ||
|
||
func (driver ChaoxingDrive) Config() base.DriverConfig { | ||
return base.DriverConfig{ | ||
Name: "ChaoXing", | ||
OnlyProxy: true, | ||
OnlyLocal: false, | ||
ApiProxy: false, | ||
NoNeedSetLink: false, | ||
NoCors: false, | ||
LocalSort: false, | ||
} | ||
} | ||
|
||
func (driver ChaoxingDrive) Items() []base.Item { | ||
// TODO fill need info | ||
return []base.Item{ | ||
{ | ||
Name: "username", | ||
Label: "手机号/超星号", | ||
Type: base.TypeString, | ||
Required: true, | ||
}, | ||
{ | ||
Name: "password", | ||
Label: "enc (加密后的密码)", | ||
Type: base.TypeString, | ||
Required: true, | ||
}, | ||
{ | ||
Name: "root_folder", | ||
Label: "根目录id", | ||
Type: base.TypeString, | ||
Default: "", | ||
Required: false, | ||
}, | ||
{ | ||
Name: "limit", | ||
Label: "目录文件上限", | ||
Type: base.TypeNumber, | ||
Default: "50", | ||
Required: false, | ||
}, | ||
} | ||
} | ||
|
||
// Save 用户更新账号信息 | ||
func (driver ChaoxingDrive) Save(account *model.Account, old *model.Account) error { | ||
// TODO test available or init | ||
if old != nil { | ||
conf.Cron.Remove(cron.EntryID(old.CronId)) | ||
} | ||
if account == nil { | ||
return nil | ||
} | ||
if account.Limit <= 0 { | ||
account.Limit = 50 | ||
} | ||
|
||
// 登录网盘并取得 Enc 字符串 ( enc保存在 account.AccessSecret 中; cookie 以键值对的形式保存在 account.AccessToken 中) | ||
err := driver.GetEnc(account) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// 每隔一天重新获取一次 Enc(和 | ||
cronId, err := conf.Cron.AddFunc("@every 24h", func() { | ||
id := account.ID | ||
log.Debugf("ali account id: %d", id) | ||
newAccount, err := model.GetAccountById(id) | ||
log.Debugf("ali account: %+v", newAccount) | ||
if err != nil { | ||
return | ||
} | ||
err = driver.GetEnc(newAccount) | ||
_ = model.SaveAccount(newAccount) | ||
}) | ||
|
||
// 记录当前计划任务的id | ||
account.CronId = int(cronId) | ||
err = model.SaveAccount(account) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
// File 通过用户路径获取到文件对象(主要是id号) | ||
func (driver ChaoxingDrive) File(path string, account *model.Account) (*model.File, error) { | ||
path = utils.ParsePath(path) | ||
if path == "/" { | ||
return &model.File{ | ||
Id: "", | ||
Name: account.Name, | ||
Size: 0, | ||
Type: conf.FOLDER, | ||
Driver: driver.Config().Name, | ||
UpdatedAt: account.UpdatedAt, | ||
}, nil | ||
} | ||
// 将路径分割成 父文件夹 和 文件名 | ||
dir, name := filepath.Split(path) | ||
// 等同于访问上级目录 | ||
files, err := driver.Files(dir, account) | ||
if err != nil { | ||
return nil, err | ||
} | ||
for _, file := range files { | ||
if file.Name == name { | ||
return &file, nil | ||
} | ||
} | ||
return nil, base.ErrPathNotFound | ||
} | ||
|
||
// Files 列出所有文件 | ||
func (driver ChaoxingDrive) Files(path string, account *model.Account) ([]model.File, error) { | ||
path = utils.ParsePath(path) | ||
// 先从缓存中获取结果 | ||
cache, err := base.GetCache(path, account) | ||
var fileList []model.File | ||
if err == nil { | ||
// 缓存命中,将目录信息保存到变量中 | ||
fileList = cache.([]model.File) | ||
} else { | ||
// 缓存未命中 | ||
//尝试获取上级目录的id(递归地尝试从上级目录的缓存中读取信息,直到获取到根目录为止) | ||
file, err := driver.File(path, account) | ||
if err != nil { | ||
return nil, err | ||
} | ||
//列出上级目录的文件 | ||
fileList, err = driver.ListFile(file.Id, account) | ||
if err != nil { | ||
return nil, err | ||
} | ||
// 缓存数据 | ||
if len(fileList) > 0 { | ||
_ = base.SetCache(path, fileList, account) | ||
} | ||
} | ||
files := make([]model.File, 0) | ||
for _, file := range fileList { | ||
files = append(files, file) | ||
} | ||
return files, nil | ||
} | ||
|
||
var api_file_link = "https://pan-yz.chaoxing.com/download/downloadfile?fleid=%s&puid=1" | ||
|
||
// Link 返回传入路径对应的文件的直链(本地除外),并包含需要携带的请求头 | ||
func (driver ChaoxingDrive) Link(args base.Args, account *model.Account) (*base.Link, error) { | ||
// TODO get file link | ||
file, e := driver.File(args.Path, account) | ||
if e != nil { | ||
return nil, e | ||
} | ||
url := fmt.Sprintf(api_file_link, file.Id[:strings.Index(file.Id, "_")]) | ||
//var resp base.Json | ||
//var err Resp | ||
|
||
// https://pan-yz.chaoxing.com/download/downloadfile?fleid=582519780768600064&puid=1 | ||
//_, e = chaoxingClient.R().SetResult(&resp).SetError(&err). | ||
// SetHeader("Cookie", account.AccessToken). | ||
// SetHeader("Referer", "https://pan-yz.chaoxing.com/"). | ||
// Get(url) | ||
return &base.Link{ | ||
Headers: []base.Header{ | ||
{ | ||
Name: "Referer", | ||
Value: "https://pan-yz.chaoxing.com/", | ||
}, | ||
//{ | ||
// Name: "Cookie", | ||
// Value: account.AccessToken, | ||
//}, | ||
}, | ||
Url: url, | ||
}, nil | ||
} | ||
|
||
// Path 通过调用上述的File与Files函数判断是文件还是文件夹,并进行返回,当是文件时附带文件的直链。 | ||
func (driver ChaoxingDrive) Path(path string, account *model.Account) (*model.File, []model.File, error) { | ||
path = utils.ParsePath(path) | ||
file, err := driver.File(path, account) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
if !file.IsDir() { | ||
return file, nil, nil | ||
} | ||
files, err := driver.Files(path, account) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
return nil, files, nil | ||
} | ||
|
||
// Optional function | ||
//func (driver ChaoxingDrive) Preview(path string, account *model.Account) (interface{}, error) { | ||
// //TODO preview interface if driver support | ||
// return nil, base.ErrNotImplement | ||
//} | ||
|
||
func (driver ChaoxingDrive) MakeDir(path string, account *model.Account) error { | ||
// 三个参数缺一不可,均不能写死 | ||
// https://pan-yz.chaoxing.com/opt/newfolder?parentId=205255741446029312&name=test&puid=54351295 | ||
|
||
return base.ErrNotImplement | ||
} | ||
|
||
func (driver ChaoxingDrive) Move(src string, dst string, account *model.Account) error { | ||
// 注意 folderid 是由 {id}_{puid} 组成的(截取前两段即可) | ||
// https://pan-yz.chaoxing.com/opt/moveres?folderid=762268051373813760_54351295&resids=762263362701209600, | ||
return base.ErrNotImplement | ||
} | ||
|
||
func (driver ChaoxingDrive) Rename(src string, dst string, account *model.Account) error { | ||
// resid 就是 fileid | ||
// https://pan-yz.chaoxing.com/opt/rename?resid=762263362701209600&name=test.pdf&puid=54351295 | ||
return base.ErrNotImplement | ||
} | ||
|
||
// 超星网盘不支持复制 | ||
//func (driver ChaoxingDrive) Copy(src string, dst string, account *model.Account) error { | ||
// //TODO copy file/dir | ||
// return base.ErrNotImplement | ||
//} | ||
|
||
// Delete 这个函数太危险了,不想实现 | ||
func (driver ChaoxingDrive) Delete(path string, account *model.Account) error { | ||
// 删除单个文件 | ||
// https://pan-yz.chaoxing.com/opt/delres?resids=762268051373813760&resourcetype=0&puids=54351295 | ||
// 删除多个文件 | ||
// https://pan-yz.chaoxing.com/opt/delres?resids=762269933587513344,762269920078848000,&resourcetype=0,0,&puids=54351295,54351295, | ||
return base.ErrNotImplement | ||
} | ||
|
||
//func (driver ChaoxingDrive) Upload(file *model.FileStream, account *model.Account) error { | ||
// //TODO upload file | ||
// return base.ErrNotImplement | ||
//} | ||
|
||
var _ base.Driver = (*ChaoxingDrive)(nil) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"` | ||
} |
Oops, something went wrong.