diff --git a/drivers/lanzou/driver.go b/drivers/lanzou/driver.go index 1ca451ce..810b0193 100644 --- a/drivers/lanzou/driver.go +++ b/drivers/lanzou/driver.go @@ -2,7 +2,9 @@ package lanzou import ( "context" + "fmt" "net/http" + "regexp" "time" "github.com/alist-org/alist/v3/drivers/base" @@ -17,6 +19,7 @@ var upClient = base.NewRestyClient().SetTimeout(120 * time.Second) type LanZou struct { Addition model.Storage + uid string } func (d *LanZou) Config() driver.Config { @@ -32,11 +35,17 @@ func (d *LanZou) Init(ctx context.Context) error { if d.RootFolderID == "" { d.RootFolderID = "-1" } + ylogin := regexp.MustCompile("ylogin=(.*?);").FindStringSubmatch(d.Cookie) + if len(ylogin) < 2 { + return fmt.Errorf("cookie does not contain ylogin") + } + d.uid = ylogin[1] } return nil } func (d *LanZou) Drop(ctx context.Context) error { + d.uid = "" return nil } @@ -75,7 +84,7 @@ func (d *LanZou) Link(ctx context.Context, file model.Obj, args model.LinkArgs) func (d *LanZou) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { if d.IsCookie() { - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "2", @@ -92,7 +101,7 @@ func (d *LanZou) MakeDir(ctx context.Context, parentDir model.Obj, dirName strin func (d *LanZou) Move(ctx context.Context, srcObj, dstDir model.Obj) error { if d.IsCookie() { if !srcObj.IsDir() { - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "20", @@ -109,7 +118,7 @@ func (d *LanZou) Move(ctx context.Context, srcObj, dstDir model.Obj) error { func (d *LanZou) Rename(ctx context.Context, srcObj model.Obj, newName string) error { if d.IsCookie() { if !srcObj.IsDir() { - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "46", @@ -130,7 +139,7 @@ func (d *LanZou) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { func (d *LanZou) Remove(ctx context.Context, obj model.Obj) error { if d.IsCookie() { - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) if obj.IsDir() { req.SetFormData(map[string]string{ diff --git a/drivers/lanzou/help.go b/drivers/lanzou/help.go index b019ea0d..f48a936f 100644 --- a/drivers/lanzou/help.go +++ b/drivers/lanzou/help.go @@ -8,10 +8,13 @@ import ( "strings" "time" "unicode" + + log "github.com/sirupsen/logrus" ) const DAY time.Duration = 84600000000000 +// 解析时间 var timeSplitReg = regexp.MustCompile("([0-9.]*)\\s*([\u4e00-\u9fa5]+)") func MustParseTime(str string) time.Time { @@ -41,6 +44,7 @@ func MustParseTime(str string) time.Time { return lastOpTime } +// 解析大小 var sizeSplitReg = regexp.MustCompile(`(?i)([0-9.]+)\s*([bkm]+)`) func SizeStrToInt64(size string) int64 { @@ -71,6 +75,7 @@ var findAcwScV2Reg = regexp.MustCompile(`arg1='([0-9A-Z]+)'`) // 在页面被过多访问或其他情况下,有时候会先返回一个加密的页面,其执行计算出一个acw_sc__v2后放入页面后再重新访问页面才能获得正常页面 // 若该页面进行了js加密,则进行解密,计算acw_sc__v2,并加入cookie func CalcAcwScV2(html string) (string, error) { + log.Debugln("acw_sc__v2", html) acwScV2s := findAcwScV2Reg.FindStringSubmatch(html) if len(acwScV2s) != 2 { return "", fmt.Errorf("无法匹配acw_sc__v2") diff --git a/drivers/lanzou/util.go b/drivers/lanzou/util.go index 4836bdf9..7b5d01fd 100644 --- a/drivers/lanzou/util.go +++ b/drivers/lanzou/util.go @@ -13,8 +13,16 @@ import ( "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/pkg/utils" "github.com/go-resty/resty/v2" + log "github.com/sirupsen/logrus" ) +func (d *LanZou) doupload(callback base.ReqCallback, resp interface{}) ([]byte, error) { + return d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + req.SetQueryParam("uid", d.uid) + callback(req) + }, resp) +} + func (d *LanZou) get(url string, callback base.ReqCallback, resp interface{}) ([]byte, error) { return d.request(url, http.MethodGet, callback, false) } @@ -68,7 +76,7 @@ func (d *LanZou) request(url string, method string, callback base.ReqCallback, u if err != nil { return nil, err } - + log.Debugf("lanzou request: url=>%s ,stats=>%d ,body => %s\n", res.Request.URL, res.StatusCode(), res.String()) return res.Body(), err } @@ -86,21 +94,19 @@ func (d *LanZou) GetFiles(ctx context.Context, folderID string) ([]model.Obj, er if err != nil { return nil, err } - objs := make([]model.Obj, 0, len(folders)+len(files)) - for _, folder := range folders { - objs = append(objs, folder.ToObj()) - } - - for _, file := range files { - objs = append(objs, file.ToObj()) - } - return objs, nil + return append( + utils.MustSliceConvert(folders, func(folder FileOrFolder) model.Obj { + return folder.ToObj() + }), utils.MustSliceConvert(files, func(file FileOrFolder) model.Obj { + return file.ToObj() + })..., + ), nil } // 通过ID获取文件夹 func (d *LanZou) getFolders(ctx context.Context, folderID string) ([]FileOrFolder, error) { var resp FilesOrFoldersResp - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "47", @@ -118,7 +124,7 @@ func (d *LanZou) getFiles(ctx context.Context, folderID string) ([]FileOrFolder, files := make([]FileOrFolder, 0) for pg := 1; ; pg++ { var resp FilesOrFoldersResp - _, err := d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err := d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "5", @@ -140,7 +146,7 @@ func (d *LanZou) getFiles(ctx context.Context, folderID string) ([]FileOrFolder, // 通过ID获取文件夹分享地址 func (d *LanZou) getFolderShareUrlByID(ctx context.Context, fileID string) (share FileShare, err error) { var resp FileShareResp - _, err = d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err = d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "18", @@ -157,7 +163,7 @@ func (d *LanZou) getFolderShareUrlByID(ctx context.Context, fileID string) (shar // 通过ID获取文件分享地址 func (d *LanZou) getFileShareUrlByID(ctx context.Context, fileID string) (share FileShare, err error) { var resp FileShareResp - _, err = d.post(d.BaseUrl+"/doupload.php", func(req *resty.Request) { + _, err = d.doupload(func(req *resty.Request) { req.SetContext(ctx) req.SetFormData(map[string]string{ "task": "22", @@ -197,24 +203,21 @@ func (d *LanZou) GetFileOrFolderByShareUrl(ctx context.Context, downID, pwd stri } pageData = RemoveNotes(pageData) - var objs []model.Obj if !isFileReg.Match(pageData) { files, err := d.getFolderByShareUrl(ctx, downID, pwd, pageData) if err != nil { return nil, err } - objs = make([]model.Obj, 0, len(files)) - for _, file := range files { - objs = append(objs, file.ToObj()) - } + return utils.MustSliceConvert(files, func(file FileOrFolderByShareUrl) model.Obj { + return file.ToObj() + }), nil } else { file, err := d.getFilesByShareUrl(ctx, downID, pwd, pageData) if err != nil { return nil, err } - objs = []model.Obj{file.ToObj()} + return []model.Obj{file.ToObj()}, nil } - return objs, nil } // 通过分享链接获取文件(下载链接也使用此方法)