262 lines
7.0 KiB
Go
262 lines
7.0 KiB
Go
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)
|