mirror of
https://gitee.com/zhangsken/aliyunpan.git
synced 2026-10-16 10:29:42 +08:00
change login routine
This commit is contained in:
+17
-17
@@ -303,7 +303,7 @@ func CmdAlbum() cli.Command {
|
||||
|
||||
func RunAlbumList() {
|
||||
activeUser := GetActiveUser()
|
||||
records, err := activeUser.PanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
records, err := activeUser.PanClient().WebapiPanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
if err != nil {
|
||||
fmt.Printf("获取相簿列表失败: %s\n", err)
|
||||
return
|
||||
@@ -326,7 +326,7 @@ func RunAlbumCreate(name, description string) {
|
||||
}
|
||||
|
||||
activeUser := GetActiveUser()
|
||||
_, err := activeUser.PanClient().AlbumCreate(&aliyunpan.AlbumCreateParam{
|
||||
_, err := activeUser.PanClient().WebapiPanClient().AlbumCreate(&aliyunpan.AlbumCreateParam{
|
||||
Name: name,
|
||||
Description: description,
|
||||
})
|
||||
@@ -344,7 +344,7 @@ func RunAlbumDelete(nameList []string) {
|
||||
}
|
||||
|
||||
activeUser := GetActiveUser()
|
||||
records, err := activeUser.PanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
records, err := activeUser.PanClient().WebapiPanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
if err != nil {
|
||||
fmt.Printf("获取相簿列表失败: %s\n", err)
|
||||
return
|
||||
@@ -354,7 +354,7 @@ func RunAlbumDelete(nameList []string) {
|
||||
for i, name := range nameList {
|
||||
if name == record.Name {
|
||||
nameList = append(nameList[:i], nameList[i+1:]...)
|
||||
_, err := activeUser.PanClient().AlbumDelete(&aliyunpan.AlbumDeleteParam{
|
||||
_, err := activeUser.PanClient().WebapiPanClient().AlbumDelete(&aliyunpan.AlbumDeleteParam{
|
||||
AlbumId: record.AlbumId,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -370,7 +370,7 @@ func RunAlbumDelete(nameList []string) {
|
||||
}
|
||||
|
||||
func getAlbumFromName(activeUser *config.PanUser, name string) *aliyunpan.AlbumEntity {
|
||||
records, err := activeUser.PanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
records, err := activeUser.PanClient().WebapiPanClient().AlbumListGetAll(&aliyunpan.AlbumListParam{})
|
||||
if err != nil {
|
||||
fmt.Printf("获取相簿列表失败: %s\n", err)
|
||||
return nil
|
||||
@@ -399,7 +399,7 @@ func RunAlbumRename(name, newName string) {
|
||||
if record == nil {
|
||||
return
|
||||
}
|
||||
_, err := activeUser.PanClient().AlbumEdit(&aliyunpan.AlbumEditParam{
|
||||
_, err := activeUser.PanClient().WebapiPanClient().AlbumEdit(&aliyunpan.AlbumEditParam{
|
||||
AlbumId: record.AlbumId,
|
||||
Description: record.Description,
|
||||
Name: newName,
|
||||
@@ -424,7 +424,7 @@ func RunAlbumListFile(name string) {
|
||||
return
|
||||
}
|
||||
|
||||
fileList, er := activeUser.PanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
fileList, er := activeUser.PanClient().WebapiPanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
AlbumId: record.AlbumId,
|
||||
})
|
||||
if er != nil {
|
||||
@@ -450,7 +450,7 @@ func RunAlbumRmFile(name string, nameList []string) {
|
||||
return
|
||||
}
|
||||
|
||||
fileList, er := activeUser.PanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
fileList, er := activeUser.PanClient().WebapiPanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
AlbumId: album.AlbumId,
|
||||
})
|
||||
if er != nil {
|
||||
@@ -480,7 +480,7 @@ func RunAlbumRmFile(name string, nameList []string) {
|
||||
return
|
||||
}
|
||||
// delete file
|
||||
_, e := activeUser.PanClient().AlbumDeleteFile(param)
|
||||
_, e := activeUser.PanClient().WebapiPanClient().AlbumDeleteFile(param)
|
||||
if e != nil {
|
||||
fmt.Printf("删除相簿文件失败:%s\n", e)
|
||||
return
|
||||
@@ -519,7 +519,7 @@ func RunAlbumAddFile(albumName string, filePathList []string, filterOption Album
|
||||
}
|
||||
for k := range paths {
|
||||
filePath := paths[k]
|
||||
fileInfo, apierr := activeUser.PanClient().FileInfoByPath(activeUser.ActiveDriveId, filePath)
|
||||
fileInfo, apierr := activeUser.PanClient().WebapiPanClient().FileInfoByPath(activeUser.ActiveDriveId, filePath)
|
||||
if apierr != nil {
|
||||
fmt.Printf("获取文件信息失败: %s\n", filePath)
|
||||
continue
|
||||
@@ -531,7 +531,7 @@ func RunAlbumAddFile(albumName string, filePathList []string, filterOption Album
|
||||
}
|
||||
} else {
|
||||
// folder
|
||||
activeUser.PanClient().FilesDirectoriesRecurseList(activeUser.ActiveDriveId, fileInfo.Path, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
activeUser.PanClient().WebapiPanClient().FilesDirectoriesRecurseList(activeUser.ActiveDriveId, fileInfo.Path, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
if apiError != nil {
|
||||
logger.Verbosef("%s\n", apiError)
|
||||
return true
|
||||
@@ -553,7 +553,7 @@ func RunAlbumAddFile(albumName string, filePathList []string, filterOption Album
|
||||
return
|
||||
}
|
||||
// add file
|
||||
_, e := activeUser.PanClient().AlbumAddFile(param)
|
||||
_, e := activeUser.PanClient().WebapiPanClient().AlbumAddFile(param)
|
||||
if e != nil {
|
||||
fmt.Printf("增加相簿文件失败:%s\n", e)
|
||||
return
|
||||
@@ -584,9 +584,9 @@ func RunAlbumDownloadFile(albumNames []string, options *DownloadOptions) {
|
||||
}
|
||||
|
||||
activeUser := GetActiveUser()
|
||||
activeUser.PanClient().EnableCache()
|
||||
activeUser.PanClient().ClearCache()
|
||||
defer activeUser.PanClient().DisableCache()
|
||||
activeUser.PanClient().WebapiPanClient().EnableCache()
|
||||
activeUser.PanClient().WebapiPanClient().ClearCache()
|
||||
defer activeUser.PanClient().WebapiPanClient().DisableCache()
|
||||
// pan token expired checker
|
||||
continueFlag := int32(0)
|
||||
atomic.StoreInt32(&continueFlag, 0)
|
||||
@@ -681,7 +681,7 @@ func RunAlbumDownloadFile(albumNames []string, options *DownloadOptions) {
|
||||
continue
|
||||
}
|
||||
// 获取相簿下的所有文件
|
||||
fileList, er := activeUser.PanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
fileList, er := activeUser.PanClient().WebapiPanClient().AlbumListFileGetAll(&aliyunpan.AlbumListFileParam{
|
||||
AlbumId: record.AlbumId,
|
||||
})
|
||||
if er != nil {
|
||||
@@ -700,7 +700,7 @@ func RunAlbumDownloadFile(albumNames []string, options *DownloadOptions) {
|
||||
newCfg := *cfg
|
||||
unit := pandownload.DownloadTaskUnit{
|
||||
Cfg: &newCfg, // 复制一份新的cfg
|
||||
PanClient: panClient,
|
||||
PanClient: panClient.WebapiPanClient(),
|
||||
VerbosePrinter: panCommandVerbose,
|
||||
PrintFormat: downloadPrintFormat(options.Load),
|
||||
ParentTaskExecutor: &executor,
|
||||
|
||||
@@ -96,7 +96,7 @@ func RunChangeDirectory(driveId, targetPath string) {
|
||||
user := config.Config.ActiveUser()
|
||||
targetPath = user.PathJoin(driveId, targetPath)
|
||||
|
||||
//targetPathInfo, err := user.PanClient().FileInfoByPath(driveId, targetPath)
|
||||
//targetPathInfo, err := user.PanClient().WebapiPanClient().FileInfoByPath(driveId, targetPath)
|
||||
files, err := matchPathByShellPattern(driveId, targetPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
||||
@@ -58,7 +58,7 @@ const (
|
||||
var ErrBadArgs = errors.New("参数错误")
|
||||
var ErrNotLogined = errors.New("未登录账号")
|
||||
|
||||
func GetActivePanClient() *aliyunpan.PanClient {
|
||||
func GetActivePanClient() *config.PanClient {
|
||||
return config.Config.ActiveUser().PanClient()
|
||||
}
|
||||
|
||||
|
||||
@@ -219,9 +219,9 @@ func downloadPrintFormat(load int) string {
|
||||
// RunDownload 执行下载网盘内文件
|
||||
func RunDownload(paths []string, options *DownloadOptions) {
|
||||
activeUser := GetActiveUser()
|
||||
activeUser.PanClient().EnableCache()
|
||||
activeUser.PanClient().ClearCache()
|
||||
defer activeUser.PanClient().DisableCache()
|
||||
activeUser.PanClient().WebapiPanClient().EnableCache()
|
||||
activeUser.PanClient().WebapiPanClient().ClearCache()
|
||||
defer activeUser.PanClient().WebapiPanClient().DisableCache()
|
||||
// pan token expired checker
|
||||
continueFlag := int32(0)
|
||||
atomic.StoreInt32(&continueFlag, 0)
|
||||
@@ -347,7 +347,7 @@ func RunDownload(paths []string, options *DownloadOptions) {
|
||||
// 匹配的文件
|
||||
unit := pandownload.DownloadTaskUnit{
|
||||
Cfg: &newCfg, // 复制一份新的cfg
|
||||
PanClient: panClient,
|
||||
PanClient: panClient.WebapiPanClient(),
|
||||
VerbosePrinter: panCommandVerbose,
|
||||
PrintFormat: downloadPrintFormat(options.Load),
|
||||
ParentTaskExecutor: &executor,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -117,7 +117,7 @@ func RunExportFiles(driveId string, overwrite bool, panPaths []string, saveLocal
|
||||
|
||||
for _, panPath := range panPaths {
|
||||
panPath = activeUser.PathJoin(driveId, panPath)
|
||||
panClient.FilesDirectoriesRecurseList(driveId, panPath, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
panClient.WebapiPanClient().FilesDirectoriesRecurseList(driveId, panPath, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
if apiError != nil {
|
||||
logger.Verbosef("%s\n", apiError)
|
||||
return true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -199,7 +199,7 @@ func processOneImport(driveId string, isOverwrite bool, dirMap map[string]*dirFi
|
||||
}
|
||||
if efi != nil && efi.FileId != "" {
|
||||
// existed, delete it
|
||||
fdr, err := panClient.FileDelete([]*aliyunpan.FileBatchActionParam{
|
||||
fdr, err := panClient.WebapiPanClient().FileDelete([]*aliyunpan.FileBatchActionParam{
|
||||
{
|
||||
DriveId: driveId,
|
||||
FileId: efi.FileId,
|
||||
@@ -221,7 +221,7 @@ func processOneImport(driveId string, isOverwrite bool, dirMap map[string]*dirFi
|
||||
ContentHash: item.FileSha1,
|
||||
ParentFileId: dataItem.Dir.FileId,
|
||||
}
|
||||
uploadOpEntity, apierr := panClient.CreateUploadFile(appCreateUploadFileParam)
|
||||
uploadOpEntity, apierr := panClient.WebapiPanClient().CreateUploadFile(appCreateUploadFileParam)
|
||||
if apierr != nil {
|
||||
fmt.Println("创建秒传任务失败:" + apierr.Error())
|
||||
return false, true
|
||||
@@ -247,7 +247,7 @@ func prepareMkdir(driveId string, importFileItems []RapidUploadItem) map[string]
|
||||
continue
|
||||
}
|
||||
if panDir != "/" {
|
||||
rs, apierr = panClient.MkdirRecursive(driveId, "", "", 0, strings.Split(path.Clean(panDir), "/"))
|
||||
rs, apierr = panClient.WebapiPanClient().MkdirRecursive(driveId, "", "", 0, strings.Split(path.Clean(panDir), "/"))
|
||||
if apierr != nil || rs.FileId == "" {
|
||||
logger.Verboseln("创建云盘文件夹失败")
|
||||
continue
|
||||
@@ -263,7 +263,7 @@ func prepareMkdir(driveId string, importFileItems []RapidUploadItem) map[string]
|
||||
param := &aliyunpan.FileListParam{}
|
||||
param.DriveId = driveId
|
||||
param.ParentFileId = rs.FileId
|
||||
allFileInfo, err1 := panClient.FileListGetAll(param, 0)
|
||||
allFileInfo, err1 := panClient.WebapiPanClient().FileListGetAll(param, 0)
|
||||
if err1 != nil {
|
||||
logger.Verboseln("获取文件信息出错")
|
||||
continue
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -80,9 +80,9 @@ func CmdLocateUrl() cli.Command {
|
||||
func RunLocateUrl(driveId string, paths []string, saveFilePath string) {
|
||||
useInternalUrl := config.Config.TransferUrlType == 2
|
||||
activeUser := GetActiveUser()
|
||||
activeUser.PanClient().EnableCache()
|
||||
activeUser.PanClient().ClearCache()
|
||||
defer activeUser.PanClient().DisableCache()
|
||||
activeUser.PanClient().WebapiPanClient().EnableCache()
|
||||
activeUser.PanClient().WebapiPanClient().ClearCache()
|
||||
defer activeUser.PanClient().WebapiPanClient().DisableCache()
|
||||
|
||||
paths, err := makePathAbsolute(driveId, paths...)
|
||||
if err != nil {
|
||||
@@ -116,7 +116,7 @@ func RunLocateUrl(driveId string, paths []string, saveFilePath string) {
|
||||
}
|
||||
fileInfo := item.(*aliyunpan.FileEntity)
|
||||
if fileInfo.IsFolder() { // 文件夹,获取下面所有文件
|
||||
allFilesInFolder, er := activeUser.PanClient().FileListGetAll(&aliyunpan.FileListParam{
|
||||
allFilesInFolder, er := activeUser.PanClient().WebapiPanClient().FileListGetAll(&aliyunpan.FileListParam{
|
||||
DriveId: driveId,
|
||||
ParentFileId: fileInfo.FileId,
|
||||
}, 300)
|
||||
@@ -131,7 +131,7 @@ func RunLocateUrl(driveId string, paths []string, saveFilePath string) {
|
||||
fileEntityQueue.Push(f)
|
||||
continue
|
||||
}
|
||||
durl, apierr := activeUser.PanClient().GetFileDownloadUrl(&aliyunpan.GetFileDownloadUrlParam{
|
||||
durl, apierr := activeUser.PanClient().WebapiPanClient().GetFileDownloadUrl(&aliyunpan.GetFileDownloadUrlParam{
|
||||
DriveId: driveId,
|
||||
FileId: f.FileId,
|
||||
})
|
||||
@@ -151,7 +151,7 @@ func RunLocateUrl(driveId string, paths []string, saveFilePath string) {
|
||||
}
|
||||
}
|
||||
} else { // 文件
|
||||
durl, apierr := activeUser.PanClient().GetFileDownloadUrl(&aliyunpan.GetFileDownloadUrlParam{
|
||||
durl, apierr := activeUser.PanClient().WebapiPanClient().GetFileDownloadUrl(&aliyunpan.GetFileDownloadUrlParam{
|
||||
DriveId: driveId,
|
||||
FileId: fileInfo.FileId,
|
||||
})
|
||||
|
||||
+43
-79
@@ -15,14 +15,12 @@ package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan/cmder/cmdliner"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/functions/panlogin"
|
||||
"github.com/tickstep/library-go/logger"
|
||||
_ "github.com/tickstep/library-go/requester"
|
||||
"github.com/urfave/cli"
|
||||
"time"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func CmdLogin() cli.Command {
|
||||
@@ -34,55 +32,36 @@ func CmdLogin() cli.Command {
|
||||
1.常规登录,按提示一步一步来即可
|
||||
aliyunpan login
|
||||
|
||||
2.直接指定RefreshToken进行登录
|
||||
aliyunpan login -RefreshToken=8B12CBBCE89CA8DFC3445985B63B511B5E7EC7...
|
||||
|
||||
3.使用二维码方式进行登录
|
||||
aliyunpan login -QrCode
|
||||
`,
|
||||
Category: "阿里云盘账号",
|
||||
Before: ReloadConfigFunc, // 每次进行登录动作的时候需要调用刷新配置
|
||||
After: SaveConfigFunc, // 登录完成需要调用保存配置
|
||||
Action: func(c *cli.Context) error {
|
||||
refreshTokenStr := ""
|
||||
if refreshTokenStr == "" {
|
||||
refreshTokenStr = c.String("RefreshToken")
|
||||
}
|
||||
useQrCode := c.Bool("QrCode")
|
||||
|
||||
tokenId := ""
|
||||
webToken := aliyunpan.WebLoginToken{}
|
||||
refreshToken := ""
|
||||
ticketId := ""
|
||||
openToken := &config.PanClientToken{}
|
||||
webToken := &config.PanClientToken{}
|
||||
var err error
|
||||
tokenId, refreshToken, webToken, err = RunLogin(useQrCode, refreshTokenStr)
|
||||
ticketId, openToken, webToken, err = RunLogin()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
cloudUser, err := config.SetupUserByCookie(&webToken, config.Config.DeviceId, config.Config.DeviceName)
|
||||
cloudUser, err := config.SetupUserByCookie(openToken, webToken,
|
||||
ticketId, "",
|
||||
config.Config.DeviceId, config.Config.DeviceName,
|
||||
config.Config.ClientId, config.Config.ClientSecret)
|
||||
if cloudUser == nil {
|
||||
fmt.Println("登录失败: ", err)
|
||||
return nil
|
||||
}
|
||||
cloudUser.RefreshToken = refreshToken
|
||||
cloudUser.TokenId = tokenId
|
||||
cloudUser.TicketId = ticketId
|
||||
config.Config.SetActiveUser(cloudUser)
|
||||
fmt.Println("阿里云盘登录成功: ", cloudUser.Nickname)
|
||||
return nil
|
||||
},
|
||||
// 命令的附加options参数说明,使用 help panlogin 命令即可查看
|
||||
Flags: []cli.Flag{
|
||||
// aliyunpan panlogin -RefreshToken=8B12CBBCE89CA8DFC3445985B63B511B5E7EC7...
|
||||
cli.StringFlag{
|
||||
Name: "RefreshToken",
|
||||
Usage: "使用RefreshToken Cookie来登录帐号",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "QrCode",
|
||||
Usage: "使用二维码登录",
|
||||
},
|
||||
},
|
||||
Flags: []cli.Flag{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +96,7 @@ func CmdLogout() cli.Command {
|
||||
}
|
||||
|
||||
// 云端注销登录
|
||||
//if _, e := activeUser.PanClient().DeviceLogout(); e != nil {
|
||||
//if _, e := activeUser.PanClient().WebapiPanClient().DeviceLogout(); e != nil {
|
||||
// fmt.Printf("登出设备失败,请手动在网页端进行登出: %s\n", e.String())
|
||||
//}
|
||||
|
||||
@@ -139,55 +118,40 @@ func CmdLogout() cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func RunLogin(useQrCodeLogin bool, refreshToken string) (tokenId, refreshTokenStr string, webToken aliyunpan.WebLoginToken, error error) {
|
||||
if useQrCodeLogin {
|
||||
h := panlogin.NewLoginHelper(config.DefaultTokenServiceWebHost)
|
||||
qrCodeUrlResult, err := h.GetQRCodeLoginUrl("")
|
||||
if err != nil {
|
||||
fmt.Println("二维码登录错误:", err)
|
||||
return "", "", aliyunpan.WebLoginToken{}, err
|
||||
}
|
||||
fmt.Printf("请在浏览器打开以下链接进行扫码登录,链接有效时间为5分钟\n%s\n\n", qrCodeUrlResult.TokenUrl+"&deviceId="+config.Config.DeviceId)
|
||||
func RunLogin() (ticketId string, openapiToken, webapiToken *config.PanClientToken, error error) {
|
||||
h := panlogin.NewLoginHelper(config.DefaultTokenServiceWebHost)
|
||||
|
||||
// handler waiting
|
||||
line := cmdliner.NewLiner()
|
||||
var qrCodeLoginResult *panlogin.QRCodeLoginResult
|
||||
queryResult := true
|
||||
defer line.Close()
|
||||
// web login request
|
||||
qrCodeUrlResult, err := h.GetQRCodeLoginUrl("")
|
||||
if err != nil {
|
||||
fmt.Println("登录出错:", err)
|
||||
return "", nil, nil, err
|
||||
}
|
||||
ticketId = qrCodeUrlResult.TokenId
|
||||
loginUrl := &strings.Builder{}
|
||||
fmt.Fprintf(loginUrl, "https://openapi.alipan.com/oauth/authorize?client_id=%s&redirect_uri=https%%3A%%2F%%2Fapi.tickstep.com%%2Fauth%%2Ftickstep%%2Faliyunpan%%2Ftoken%%2Fopenapi%%2F%s%%2Fauth&scope=user:base,file:all:read,file:all:write",
|
||||
config.Config.ClientId, ticketId)
|
||||
fmt.Printf("请在浏览器打开以下链接进行扫码登录,链接有效时间为5分钟\n%s\n\n", loginUrl)
|
||||
|
||||
go func() {
|
||||
for queryResult {
|
||||
time.Sleep(3 * time.Second)
|
||||
qr, er := h.GetQRCodeLoginResult(qrCodeUrlResult.TokenId)
|
||||
if er != nil {
|
||||
continue
|
||||
}
|
||||
logger.Verboseln(qr)
|
||||
if qr.QrCodeStatus == "CONFIRMED" {
|
||||
// login successfully
|
||||
qrCodeLoginResult = qr
|
||||
break
|
||||
} else if qr.QrCodeStatus == "EXPIRED" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
// handler waiting
|
||||
line := cmdliner.NewLiner()
|
||||
defer line.Close()
|
||||
line.State.Prompt("请在浏览器里面完成扫码登录,然后再按Enter键继续...")
|
||||
|
||||
line.State.Prompt("请在浏览器里面完成扫码登录,然后再按Enter键继续...")
|
||||
if qrCodeLoginResult == nil {
|
||||
queryResult = false
|
||||
return "", "", aliyunpan.WebLoginToken{}, fmt.Errorf("二维码登录失败")
|
||||
}
|
||||
|
||||
tokenStr, er := h.ParseSecureRefreshToken("", qrCodeLoginResult.SecureRefreshToken)
|
||||
if er != nil {
|
||||
fmt.Println("解析Token错误:", er)
|
||||
return "", "", aliyunpan.WebLoginToken{}, er
|
||||
}
|
||||
refreshToken = tokenStr
|
||||
tokenId = qrCodeUrlResult.TokenId
|
||||
// get login token
|
||||
comToken, er := h.GetLoginToken(ticketId)
|
||||
if er != nil {
|
||||
return ticketId, nil, nil, fmt.Errorf("登录失败,请稍后尝试重新登录")
|
||||
}
|
||||
|
||||
refreshTokenStr, webToken, error = DoLoginHelper(refreshToken)
|
||||
return
|
||||
return ticketId,
|
||||
&config.PanClientToken{
|
||||
AccessToken: comToken.Openapi.AccessToken,
|
||||
Expired: comToken.Openapi.Expired,
|
||||
},
|
||||
&config.PanClientToken{
|
||||
AccessToken: comToken.Webapi.AccessToken,
|
||||
Expired: comToken.Webapi.Expired,
|
||||
},
|
||||
nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -169,7 +169,7 @@ func RunLs(driveId, targetPath string, lsOptions *LsOptions,
|
||||
fileListParam.OrderBy = orderBy
|
||||
fileListParam.OrderDirection = orderDirection
|
||||
if targetPathInfo.IsFolder() {
|
||||
fileResult, err1 := activeUser.PanClient().FileListGetAll(fileListParam, 200)
|
||||
fileResult, err1 := activeUser.PanClient().WebapiPanClient().FileListGetAll(fileListParam, 200)
|
||||
if err1 != nil {
|
||||
fmt.Println(err1)
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -56,7 +56,7 @@ func RunMkdir(driveId, name string) {
|
||||
fullpath := activeUser.PathJoin(driveId, name)
|
||||
rs := &aliyunpan.MkdirResult{}
|
||||
err := apierror.NewFailedApiError("")
|
||||
rs, err = activeUser.PanClient().Mkdir(driveId, "", fullpath)
|
||||
rs, err = activeUser.PanClient().WebapiPanClient().Mkdir(driveId, "", fullpath)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("创建文件夹失败:" + err.Error())
|
||||
|
||||
@@ -98,7 +98,7 @@ func RunMove(driveId string, paths ...string) {
|
||||
})
|
||||
cacheCleanPaths = append(cacheCleanPaths, path.Dir(mfi.Path))
|
||||
}
|
||||
fmr, er := activeUser.PanClient().FileMove(moveFileParamList)
|
||||
fmr, er := activeUser.PanClient().WebapiPanClient().FileMove(moveFileParamList)
|
||||
|
||||
for _, rs := range fmr {
|
||||
if !rs.Success {
|
||||
@@ -138,7 +138,7 @@ func getFileInfo(driveId string, paths ...string) (opFileList []*aliyunpan.FileE
|
||||
// the last one is the target file path
|
||||
targetFilePath := path.Clean(paths[len(paths)-1])
|
||||
absolutePath := activeUser.PathJoin(driveId, targetFilePath)
|
||||
targetFile, err := activeUser.PanClient().FileInfoByPath(driveId, absolutePath)
|
||||
targetFile, err := activeUser.PanClient().WebapiPanClient().FileInfoByPath(driveId, absolutePath)
|
||||
if err != nil || !targetFile.IsFolder() {
|
||||
return nil, nil, nil, fmt.Errorf("指定目标文件夹不存在")
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func CmdQuota() cli.Command {
|
||||
}
|
||||
|
||||
func RunGetQuotaInfo() (quotaInfo *QuotaInfo, error error) {
|
||||
user, err := GetActivePanClient().GetUserInfo()
|
||||
user, err := GetActivePanClient().WebapiPanClient().GetUserInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ func CmdRecycle() cli.Command {
|
||||
// RunRecycleList 执行列出回收站文件列表
|
||||
func RunRecycleList(driveId string) {
|
||||
panClient := GetActivePanClient()
|
||||
fdl, err := panClient.RecycleBinFileListGetAll(&aliyunpan.RecycleBinFileListParam{
|
||||
fdl, err := panClient.WebapiPanClient().RecycleBinFileListGetAll(&aliyunpan.RecycleBinFileListParam{
|
||||
DriveId: driveId,
|
||||
Limit: 100,
|
||||
})
|
||||
@@ -174,7 +174,7 @@ func RunRecycleRestore(driveId string, fidStrList ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
rbfr, err := panClient.RecycleBinFileRestore(restoreFileList)
|
||||
rbfr, err := panClient.WebapiPanClient().RecycleBinFileRestore(restoreFileList)
|
||||
if rbfr != nil && len(rbfr) > 0 {
|
||||
fmt.Printf("还原文件成功\n")
|
||||
return
|
||||
@@ -203,7 +203,7 @@ func RunRecycleDelete(driveId string, fidStrList ...string) {
|
||||
return
|
||||
}
|
||||
|
||||
rbfr, err := panClient.RecycleBinFileDelete(deleteFileList)
|
||||
rbfr, err := panClient.WebapiPanClient().RecycleBinFileDelete(deleteFileList)
|
||||
if rbfr != nil && len(rbfr) > 0 {
|
||||
fmt.Printf("彻底删除文件成功\n")
|
||||
return
|
||||
@@ -220,7 +220,7 @@ func RunRecycleClear(driveId string) {
|
||||
panClient := GetActivePanClient()
|
||||
|
||||
// 提交清空回收站异步任务
|
||||
r, err := panClient.RecycleBinFileClear(&aliyunpan.RecycleBinFileClearParam{
|
||||
r, err := panClient.WebapiPanClient().RecycleBinFileClear(&aliyunpan.RecycleBinFileClearParam{
|
||||
DriveId: driveId,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -229,7 +229,7 @@ func RunRecycleClear(driveId string) {
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
ar, err1 := panClient.AsyncTaskQueryStatus(&aliyunpan.AsyncTaskQueryStatusParam{
|
||||
ar, err1 := panClient.WebapiPanClient().AsyncTaskQueryStatus(&aliyunpan.AsyncTaskQueryStatusParam{
|
||||
AsyncTaskId: r.AsyncTaskId,
|
||||
})
|
||||
if err1 != nil {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -136,14 +136,14 @@ func RunRename(driveId string, oldName string, newName string) {
|
||||
}
|
||||
|
||||
fileId := ""
|
||||
r, err := GetActivePanClient().FileInfoByPath(driveId, activeUser.PathJoin(driveId, oldName))
|
||||
r, err := GetActivePanClient().WebapiPanClient().FileInfoByPath(driveId, activeUser.PathJoin(driveId, oldName))
|
||||
if err != nil {
|
||||
fmt.Printf("原文件不存在: %s, %s\n", oldName, err)
|
||||
return
|
||||
}
|
||||
fileId = r.FileId
|
||||
|
||||
b, e := activeUser.PanClient().FileRename(driveId, fileId, path.Base(newName))
|
||||
b, e := activeUser.PanClient().WebapiPanClient().FileRename(driveId, fileId, path.Base(newName))
|
||||
if e != nil {
|
||||
fmt.Println(e.Err)
|
||||
return
|
||||
@@ -234,7 +234,7 @@ func RunRenameBatch(skipConfirm bool, driveId string, expression, replacement, f
|
||||
|
||||
// 重命名
|
||||
for _, file := range files {
|
||||
b, e := activeUser.PanClient().FileRename(driveId, file.file.FileId, file.newFileName)
|
||||
b, e := activeUser.PanClient().WebapiPanClient().FileRename(driveId, file.file.FileId, file.newFileName)
|
||||
if e != nil {
|
||||
fmt.Println(e.Err)
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -106,7 +106,7 @@ func RunRemove(driveId string, paths ...string) {
|
||||
|
||||
// delete
|
||||
successDelFileEntity := []*aliyunpan.FileEntity{}
|
||||
fdr, err := activeUser.PanClient().FileDelete(delFileInfos)
|
||||
fdr, err := activeUser.PanClient().WebapiPanClient().FileDelete(delFileInfos)
|
||||
if fdr != nil {
|
||||
for _, item := range fdr {
|
||||
if !item.Success {
|
||||
|
||||
@@ -72,7 +72,7 @@ func RunSave(driveId string, args ...string) {
|
||||
|
||||
targetFilePath := path.Clean(args[len(args)-1])
|
||||
absolutePath := activeUser.PathJoin(driveId, targetFilePath)
|
||||
targetFile, err := activeUser.PanClient().FileInfoByPath(driveId, absolutePath)
|
||||
targetFile, err := activeUser.PanClient().WebapiPanClient().FileInfoByPath(driveId, absolutePath)
|
||||
if err != nil || !targetFile.IsFolder() {
|
||||
fmt.Println("指定目标文件夹不存在")
|
||||
return
|
||||
@@ -88,19 +88,19 @@ func RunSave(driveId string, args ...string) {
|
||||
sharePwd = args[1]
|
||||
}
|
||||
|
||||
token, err := activeUser.PanClient().GetShareToken(shareID, sharePwd)
|
||||
token, err := activeUser.PanClient().WebapiPanClient().GetShareToken(shareID, sharePwd)
|
||||
if err != nil {
|
||||
fmt.Println("读取分享链接失败:", err)
|
||||
return
|
||||
}
|
||||
|
||||
list, err := activeUser.PanClient().GetListByShare(token.ShareToken, shareID, "")
|
||||
list, err := activeUser.PanClient().WebapiPanClient().GetListByShare(token.ShareToken, shareID, "")
|
||||
if err != nil {
|
||||
fmt.Println("读取分享文件列表失败:", err)
|
||||
return
|
||||
}
|
||||
for list.NextMarker != "" {
|
||||
list2, err := activeUser.PanClient().GetListByShare(token.ShareToken, shareID, "")
|
||||
list2, err := activeUser.PanClient().WebapiPanClient().GetListByShare(token.ShareToken, shareID, "")
|
||||
if err != nil {
|
||||
fmt.Println("读取分享文件列表失败:", err)
|
||||
return
|
||||
@@ -129,7 +129,7 @@ func RunSave(driveId string, args ...string) {
|
||||
}
|
||||
fmt.Println()
|
||||
|
||||
result, err := activeUser.PanClient().FileCopy(token.ShareToken, params)
|
||||
result, err := activeUser.PanClient().WebapiPanClient().FileCopy(token.ShareToken, params)
|
||||
if err != nil {
|
||||
fmt.Println("保存分享文件失败:", err)
|
||||
return
|
||||
@@ -148,7 +148,7 @@ func RunSave(driveId string, args ...string) {
|
||||
}
|
||||
}
|
||||
if ids != nil {
|
||||
result2, err := activeUser.PanClient().AsyncTaskGet(token.ShareToken, ids)
|
||||
result2, err := activeUser.PanClient().WebapiPanClient().AsyncTaskGet(token.ShareToken, ids)
|
||||
if err != nil {
|
||||
fmt.Println("读取保存结果失败:", err)
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ func RunShareSet(modeFlag, driveId string, paths []string, expiredTime string, s
|
||||
|
||||
if modeFlag == "3" {
|
||||
// 快传
|
||||
r, err1 := panClient.FastShareLinkCreate(aliyunpan.FastShareCreateParam{
|
||||
r, err1 := panClient.WebapiPanClient().FastShareLinkCreate(aliyunpan.FastShareCreateParam{
|
||||
DriveId: driveId,
|
||||
FileIdList: fidList,
|
||||
})
|
||||
@@ -303,7 +303,7 @@ func RunShareSet(modeFlag, driveId string, paths []string, expiredTime string, s
|
||||
fmt.Printf("链接:%s\n", r.ShareUrl)
|
||||
} else {
|
||||
// 分享
|
||||
r, err1 := panClient.ShareLinkCreate(aliyunpan.ShareCreateParam{
|
||||
r, err1 := panClient.WebapiPanClient().ShareLinkCreate(aliyunpan.ShareCreateParam{
|
||||
DriveId: driveId,
|
||||
SharePwd: sharePwd,
|
||||
Expiration: expiredTime,
|
||||
@@ -330,7 +330,7 @@ func RunShareSet(modeFlag, driveId string, paths []string, expiredTime string, s
|
||||
// RunShareList 执行列出分享列表
|
||||
func RunShareList() {
|
||||
activeUser := GetActiveUser()
|
||||
records, err := activeUser.PanClient().ShareLinkList(activeUser.UserId)
|
||||
records, err := activeUser.PanClient().WebapiPanClient().ShareLinkList(activeUser.UserId)
|
||||
if err != nil {
|
||||
fmt.Printf("获取分享列表失败: %s\n", err)
|
||||
return
|
||||
@@ -378,7 +378,7 @@ func RunShareCancel(shareIdList []string) {
|
||||
}
|
||||
|
||||
activeUser := GetActiveUser()
|
||||
r, err := activeUser.PanClient().ShareLinkCancel(shareIdList)
|
||||
r, err := activeUser.PanClient().WebapiPanClient().ShareLinkCancel(shareIdList)
|
||||
if err != nil {
|
||||
fmt.Printf("取消分享操作失败: %s\n", err)
|
||||
return
|
||||
@@ -393,7 +393,7 @@ func RunShareCancel(shareIdList []string) {
|
||||
|
||||
func RunShareExport(option, saveFilePath string) {
|
||||
activeUser := GetActiveUser()
|
||||
records, err := activeUser.PanClient().ShareLinkList(activeUser.UserId)
|
||||
records, err := activeUser.PanClient().WebapiPanClient().ShareLinkList(activeUser.UserId)
|
||||
if err != nil {
|
||||
fmt.Printf("获取分享列表失败: %s\n", err)
|
||||
return
|
||||
@@ -467,7 +467,7 @@ func RunShareMc(driveId string, hideRelativePath bool, panPaths []string) {
|
||||
totalCount := 0
|
||||
for _, panPath := range panPaths {
|
||||
panPath = activeUser.PathJoin(driveId, panPath)
|
||||
panClient.FilesDirectoriesRecurseList(driveId, panPath, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
panClient.WebapiPanClient().FilesDirectoriesRecurseList(driveId, panPath, func(depth int, _ string, fd *aliyunpan.FileEntity, apiError *apierror.ApiError) bool {
|
||||
if apiError != nil {
|
||||
logger.Verbosef("%s\n", apiError)
|
||||
return true
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan/cmder"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/global"
|
||||
"github.com/tickstep/aliyunpan/internal/log"
|
||||
"github.com/tickstep/aliyunpan/internal/syncdrive"
|
||||
"github.com/tickstep/aliyunpan/internal/utils"
|
||||
@@ -302,7 +303,7 @@ func RunSync(defaultTask *syncdrive.SyncTask, fileDownloadParallel, fileUploadPa
|
||||
maxUploadRate := config.Config.MaxUploadRate
|
||||
activeUser := GetActiveUser()
|
||||
panClient := activeUser.PanClient()
|
||||
panClient.DisableCache()
|
||||
panClient.WebapiPanClient().DisableCache()
|
||||
|
||||
// pan token expired checker
|
||||
continueFlag := int32(0)
|
||||
@@ -315,7 +316,8 @@ func RunSync(defaultTask *syncdrive.SyncTask, fileDownloadParallel, fileUploadPa
|
||||
time.Sleep(time.Duration(1) * time.Minute)
|
||||
if RefreshTokenInNeed(activeUser, config.Config.DeviceName) {
|
||||
logger.Verboseln("update access token for sync task")
|
||||
panClient.UpdateToken(activeUser.WebToken)
|
||||
userWebToken := NewWebLoginToken(activeUser.WebapiToken.AccessToken, activeUser.WebapiToken.Expired)
|
||||
panClient.WebapiPanClient().UpdateToken(userWebToken)
|
||||
}
|
||||
}
|
||||
}(&continueFlag)
|
||||
@@ -354,7 +356,7 @@ func RunSync(defaultTask *syncdrive.SyncTask, fileDownloadParallel, fileUploadPa
|
||||
LocalFileModifiedCheckIntervalSec: localDelayTime,
|
||||
FileRecorder: fileRecorder,
|
||||
}
|
||||
syncMgr := syncdrive.NewSyncTaskManager(activeUser, activeUser.DriveList.GetFileDriveId(), panClient, syncFolderRootPath, option)
|
||||
syncMgr := syncdrive.NewSyncTaskManager(activeUser, activeUser.DriveList.GetFileDriveId(), panClient.WebapiPanClient(), syncFolderRootPath, option)
|
||||
syncConfigFile := syncMgr.ConfigFilePath()
|
||||
if tasks != nil {
|
||||
syncConfigFile = "(使用命令行配置)"
|
||||
@@ -377,7 +379,7 @@ func RunSync(defaultTask *syncdrive.SyncTask, fileDownloadParallel, fileUploadPa
|
||||
time.Sleep(60 * time.Second)
|
||||
}
|
||||
} else {
|
||||
if config.IsAppInCliMode {
|
||||
if global.IsAppInCliMode {
|
||||
// in cmd mode
|
||||
c := ""
|
||||
fmt.Println("本命令不会退出,如需要结束同步备份进程请输入y,然后按Enter键进行停止。")
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
// Copyright (c) 2020 tickstep.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan/cmder"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/plugins"
|
||||
"github.com/tickstep/aliyunpan/internal/utils"
|
||||
"github.com/tickstep/library-go/logger"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func CmdToken() cli.Command {
|
||||
return cli.Command{
|
||||
Name: "token",
|
||||
Usage: "Token相关操作",
|
||||
UsageText: cmder.App().Name + " token",
|
||||
Category: "阿里云盘账号",
|
||||
Before: ReloadConfigFunc,
|
||||
Action: func(c *cli.Context) error {
|
||||
cli.ShowCommandHelp(c, c.Command.Name)
|
||||
return nil
|
||||
},
|
||||
Subcommands: []cli.Command{
|
||||
{
|
||||
Name: "update",
|
||||
Usage: "更新Token",
|
||||
UsageText: cmder.App().Name + " token update",
|
||||
Description: `
|
||||
示例:
|
||||
|
||||
更新当前登录用户的Token
|
||||
aliyunpan token update -mode 1
|
||||
|
||||
更新全部登录用户的Token
|
||||
aliyunpan token update -mode 2
|
||||
`,
|
||||
Action: func(c *cli.Context) error {
|
||||
if config.Config.ActiveUser() == nil {
|
||||
fmt.Println("未登录账号,无需刷新Token")
|
||||
return nil
|
||||
}
|
||||
|
||||
modeFlag := "1"
|
||||
if c.IsSet("mode") {
|
||||
modeFlag = c.String("mode")
|
||||
}
|
||||
RunTokenUpdate(modeFlag)
|
||||
return nil
|
||||
},
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "mode",
|
||||
Usage: "模式,1-登录用户,2-全部用户",
|
||||
Value: "1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// RunTokenUpdate 执行Token更新
|
||||
func RunTokenUpdate(modeFlag string) {
|
||||
ReloadConfigFunc(nil)
|
||||
|
||||
// 获取当前插件
|
||||
pluginManger := plugins.NewPluginManager(config.GetPluginDir())
|
||||
plugin, _ := pluginManger.GetPlugin()
|
||||
params := &plugins.UserTokenRefreshFinishParams{
|
||||
Result: "success",
|
||||
Message: "",
|
||||
OldToken: "",
|
||||
NewToken: "",
|
||||
UpdatedAt: utils.NowTimeStr(),
|
||||
}
|
||||
|
||||
userList := config.Config.UserList
|
||||
if userList == nil || len(userList) == 0 {
|
||||
fmt.Printf("没有登录用户,无需刷新Token\n")
|
||||
return
|
||||
}
|
||||
for _, user := range userList {
|
||||
params.Result = "success"
|
||||
|
||||
if modeFlag == "1" {
|
||||
if user.UserId != config.Config.ActiveUID {
|
||||
continue
|
||||
}
|
||||
}
|
||||
newToken, e := aliyunpan.GetAccessTokenFromRefreshToken(user.RefreshToken)
|
||||
if e != nil {
|
||||
params.Result = "fail"
|
||||
params.Message = e.Error()
|
||||
fmt.Printf("无法为%s用户获取新的RefreshToken,可能需要重新登录\n", user.Nickname)
|
||||
continue
|
||||
}
|
||||
if newToken != nil && newToken.RefreshToken != "" {
|
||||
params.OldToken = user.RefreshToken
|
||||
params.NewToken = newToken.RefreshToken
|
||||
|
||||
user.RefreshToken = newToken.RefreshToken
|
||||
user.WebToken = *newToken
|
||||
fmt.Printf("成功刷新%s用户的RefreshToken\n", user.Nickname)
|
||||
} else {
|
||||
params.Result = "fail"
|
||||
}
|
||||
|
||||
// plugin callback
|
||||
if er := plugin.UserTokenRefreshFinishCallback(plugins.GetContext(user), params); er != nil {
|
||||
logger.Verbosef("UserTokenRefreshFinishCallback error: " + er.Error())
|
||||
}
|
||||
}
|
||||
SaveConfigFunc(nil)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ func getTree(driveId, pathStr string, depth int, statistic *treeStatistic, setti
|
||||
fileListParam.OrderBy = aliyunpan.FileOrderByName
|
||||
fileListParam.OrderDirection = aliyunpan.FileOrderDirectionAsc
|
||||
if targetPathInfo.IsFolder() {
|
||||
fileResult, err := activeUser.PanClient().FileListGetAll(fileListParam, 500)
|
||||
fileResult, err := activeUser.PanClient().WebapiPanClient().FileListGetAll(fileListParam, 500)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
@@ -214,9 +214,9 @@ func getTree(driveId, pathStr string, depth int, statistic *treeStatistic, setti
|
||||
// RunTree 列出树形图
|
||||
func RunTree(driveId, pathStr string, showFullPath, showFileSize bool, minSize, maxSize int64) {
|
||||
activeUser := config.Config.ActiveUser()
|
||||
activeUser.PanClient().ClearCache()
|
||||
activeUser.PanClient().EnableCache()
|
||||
defer activeUser.PanClient().DisableCache()
|
||||
activeUser.PanClient().WebapiPanClient().ClearCache()
|
||||
activeUser.PanClient().WebapiPanClient().EnableCache()
|
||||
defer activeUser.PanClient().WebapiPanClient().DisableCache()
|
||||
pathStr = activeUser.PathJoin(driveId, pathStr)
|
||||
statistic := &treeStatistic{
|
||||
CountOfDir: 0,
|
||||
|
||||
+12
-12
@@ -273,9 +273,9 @@ func CmdRapidUpload() cli.Command {
|
||||
// RunUpload 执行文件上传
|
||||
func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
|
||||
activeUser := GetActiveUser()
|
||||
activeUser.PanClient().EnableCache()
|
||||
activeUser.PanClient().ClearCache()
|
||||
defer activeUser.PanClient().DisableCache()
|
||||
activeUser.PanClient().WebapiPanClient().EnableCache()
|
||||
activeUser.PanClient().WebapiPanClient().ClearCache()
|
||||
defer activeUser.PanClient().WebapiPanClient().DisableCache()
|
||||
// pan token expired checker
|
||||
continueFlag := int32(0)
|
||||
atomic.StoreInt32(&continueFlag, 0)
|
||||
@@ -316,13 +316,13 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
|
||||
|
||||
// 超时时间
|
||||
if opt.MaxTimeoutSec > 0 {
|
||||
activeUser.PanClient().SetTimeout(time.Duration(opt.MaxTimeoutSec) * time.Second)
|
||||
activeUser.PanClient().WebapiPanClient().SetTimeout(time.Duration(opt.MaxTimeoutSec) * time.Second)
|
||||
}
|
||||
|
||||
fmt.Printf("\n[0] 当前文件上传最大并发量为: %d, 上传分片大小为: %s\n", opt.AllParallel, converter.ConvertFileSize(opt.BlockSize, 2))
|
||||
|
||||
savePath = activeUser.PathJoin(opt.DriveId, savePath)
|
||||
_, err1 := activeUser.PanClient().FileInfoByPath(opt.DriveId, savePath)
|
||||
_, err1 := activeUser.PanClient().WebapiPanClient().FileInfoByPath(opt.DriveId, savePath)
|
||||
if err1 != nil {
|
||||
fmt.Printf("警告: 上传文件, 获取云盘路径 %s 错误, %s\n", savePath, err1)
|
||||
}
|
||||
@@ -441,7 +441,7 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
|
||||
LocalFileChecksum: localfile.NewLocalSymlinkFileEntity(file),
|
||||
SavePath: subSavePath,
|
||||
DriveId: opt.DriveId,
|
||||
PanClient: activeUser.PanClient(),
|
||||
PanClient: activeUser.PanClient().WebapiPanClient(),
|
||||
UploadingDatabase: uploadDatabase,
|
||||
FolderCreateMutex: folderCreateMutex,
|
||||
Parallel: opt.Parallel,
|
||||
@@ -463,11 +463,11 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
|
||||
if saveFilePath != "/" {
|
||||
folderCreateMutex.Lock()
|
||||
fmt.Printf("正在检测和创建云盘文件夹: %s\n", saveFilePath)
|
||||
_, apierr1 := activeUser.PanClient().FileInfoByPath(opt.DriveId, saveFilePath)
|
||||
_, apierr1 := activeUser.PanClient().WebapiPanClient().FileInfoByPath(opt.DriveId, saveFilePath)
|
||||
time.Sleep(1 * time.Second)
|
||||
if apierr1 != nil && apierr1.Code == apierror.ApiCodeFileNotFoundCode {
|
||||
logger.Verbosef("%s 创建云盘文件夹: %s\n", utils.NowTimeStr(), saveFilePath)
|
||||
rs, apierr := activeUser.PanClient().Mkdir(opt.DriveId, "root", saveFilePath)
|
||||
rs, apierr := activeUser.PanClient().WebapiPanClient().Mkdir(opt.DriveId, "root", saveFilePath)
|
||||
if apierr != nil || rs.FileId == "" {
|
||||
fmt.Printf("创建云盘文件夹失败: %s\n", saveFilePath)
|
||||
}
|
||||
@@ -565,7 +565,7 @@ func doRapidUpload(driveId string, isOverwrite bool, item *RapidUploadItem) erro
|
||||
panDir, panFileName := path.Split(item.FilePath)
|
||||
saveFilePath = item.FilePath
|
||||
if panDir != "/" {
|
||||
rs, apierr = panClient.MkdirRecursive(driveId, "", "", 0, strings.Split(path.Clean(panDir), "/"))
|
||||
rs, apierr = panClient.WebapiPanClient().MkdirRecursive(driveId, "", "", 0, strings.Split(path.Clean(panDir), "/"))
|
||||
if apierr != nil || rs.FileId == "" {
|
||||
return fmt.Errorf("创建云盘文件夹失败")
|
||||
}
|
||||
@@ -578,13 +578,13 @@ func doRapidUpload(driveId string, isOverwrite bool, item *RapidUploadItem) erro
|
||||
if isOverwrite {
|
||||
// 标记覆盖旧同名文件
|
||||
// 检查同名文件是否存在
|
||||
efi, apierr := panClient.FileInfoByPath(driveId, saveFilePath)
|
||||
efi, apierr := panClient.WebapiPanClient().FileInfoByPath(driveId, saveFilePath)
|
||||
if apierr != nil && apierr.Code != apierror.ApiCodeFileNotFoundCode {
|
||||
return fmt.Errorf("检测同名文件失败,请稍后重试")
|
||||
}
|
||||
if efi != nil && efi.FileId != "" {
|
||||
// existed, delete it
|
||||
fileDeleteResult, err1 := panClient.FileDelete([]*aliyunpan.FileBatchActionParam{{DriveId: efi.DriveId, FileId: efi.FileId}})
|
||||
fileDeleteResult, err1 := panClient.WebapiPanClient().FileDelete([]*aliyunpan.FileBatchActionParam{{DriveId: efi.DriveId, FileId: efi.FileId}})
|
||||
if err1 != nil || len(fileDeleteResult) == 0 {
|
||||
return fmt.Errorf("无法删除文件,请稍后重试")
|
||||
}
|
||||
@@ -604,7 +604,7 @@ func doRapidUpload(driveId string, isOverwrite bool, item *RapidUploadItem) erro
|
||||
ContentHash: item.FileSha1,
|
||||
ParentFileId: rs.FileId,
|
||||
}
|
||||
uploadOpEntity, apierr := panClient.CreateUploadFile(appCreateUploadFileParam)
|
||||
uploadOpEntity, apierr := panClient.WebapiPanClient().CreateUploadFile(appCreateUploadFileParam)
|
||||
if apierr != nil {
|
||||
return fmt.Errorf("创建秒传任务失败:" + apierr.Error())
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -137,5 +137,5 @@ func CmdWho() cli.Command {
|
||||
}
|
||||
|
||||
func RunGetUserInfo() (userInfo *aliyunpan.UserInfo, error error) {
|
||||
return GetActivePanClient().GetUserInfo()
|
||||
return GetActivePanClient().WebapiPanClient().GetUserInfo()
|
||||
}
|
||||
|
||||
+46
-110
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -16,8 +16,6 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan/apierror"
|
||||
"github.com/tickstep/aliyunpan/cmder/cmdliner"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/functions/panlogin"
|
||||
"github.com/tickstep/aliyunpan/internal/plugins"
|
||||
@@ -60,7 +58,7 @@ var (
|
||||
// RunTestShellPattern 执行测试通配符
|
||||
func RunTestShellPattern(driveId string, pattern string) {
|
||||
acUser := GetActiveUser()
|
||||
files, err := acUser.PanClient().MatchPathByShellPattern(driveId, GetActiveUser().PathJoin(driveId, pattern))
|
||||
files, err := acUser.PanClient().WebapiPanClient().MatchPathByShellPattern(driveId, GetActiveUser().PathJoin(driveId, pattern))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
@@ -75,7 +73,7 @@ func RunTestShellPattern(driveId string, pattern string) {
|
||||
func matchPathByShellPattern(driveId string, patterns ...string) (files []*aliyunpan.FileEntity, e error) {
|
||||
acUser := GetActiveUser()
|
||||
for k := range patterns {
|
||||
ps, err := acUser.PanClient().MatchPathByShellPattern(driveId, acUser.PathJoin(driveId, patterns[k]))
|
||||
ps, err := acUser.PanClient().WebapiPanClient().MatchPathByShellPattern(driveId, acUser.PathJoin(driveId, patterns[k]))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -128,7 +126,21 @@ func UnescapeStr(s string) string {
|
||||
return r
|
||||
}
|
||||
|
||||
// RefreshTokenInNeed 刷新refresh token
|
||||
func NewWebLoginToken(accessToken string, expired int64) aliyunpan.WebLoginToken {
|
||||
webapiToken := &config.PanClientToken{
|
||||
AccessToken: accessToken,
|
||||
Expired: expired,
|
||||
}
|
||||
return aliyunpan.WebLoginToken{
|
||||
AccessTokenType: "Bearer",
|
||||
AccessToken: webapiToken.AccessToken,
|
||||
RefreshToken: "",
|
||||
ExpiresIn: 7200,
|
||||
ExpireTime: webapiToken.GetExpiredTimeCstStr(),
|
||||
}
|
||||
}
|
||||
|
||||
// RefreshTokenInNeed 刷新webapi access token
|
||||
func RefreshTokenInNeed(activeUser *config.PanUser, deviceName string) bool {
|
||||
if activeUser == nil {
|
||||
return false
|
||||
@@ -136,11 +148,11 @@ func RefreshTokenInNeed(activeUser *config.PanUser, deviceName string) bool {
|
||||
|
||||
// refresh expired token
|
||||
if activeUser.PanClient() != nil {
|
||||
if len(activeUser.WebToken.RefreshToken) > 0 {
|
||||
if len(activeUser.WebapiToken.AccessToken) > 0 {
|
||||
cz := time.FixedZone("CST", 8*3600) // 东8区
|
||||
expiredTime, _ := time.ParseInLocation("2006-01-02 15:04:05", activeUser.WebToken.ExpireTime, cz)
|
||||
expiredTime := time.Unix(activeUser.WebapiToken.Expired, 0).In(cz)
|
||||
now := time.Now()
|
||||
if (expiredTime.Unix() - now.Unix()) <= (20 * 60) { // 20min
|
||||
if (expiredTime.Unix() - now.Unix()) <= (5 * 60) { // 有效期小于5min就刷新
|
||||
pluginManger := plugins.NewPluginManager(config.GetPluginDir())
|
||||
plugin, _ := pluginManger.GetPlugin()
|
||||
params := &plugins.UserTokenRefreshFinishParams{
|
||||
@@ -152,15 +164,23 @@ func RefreshTokenInNeed(activeUser *config.PanUser, deviceName string) bool {
|
||||
}
|
||||
|
||||
// need update refresh token
|
||||
logger.Verboseln("access token expired, get new from refresh token")
|
||||
if wt, er := aliyunpan.GetAccessTokenFromRefreshToken(activeUser.RefreshToken); er == nil {
|
||||
logger.Verboseln("access token expired, get new from server")
|
||||
loginHelper := panlogin.NewLoginHelper(config.DefaultTokenServiceWebHost)
|
||||
wt, e := loginHelper.GetWebapiNewToken(activeUser.TicketId, activeUser.UserId)
|
||||
if e != nil {
|
||||
logger.Verboseln("get web token from server error: ", e)
|
||||
}
|
||||
if wt != nil {
|
||||
params.Result = "success"
|
||||
params.OldToken = activeUser.RefreshToken
|
||||
params.NewToken = wt.RefreshToken
|
||||
params.OldToken = activeUser.WebapiToken.AccessToken
|
||||
params.NewToken = wt.AccessToken
|
||||
|
||||
activeUser.RefreshToken = wt.RefreshToken
|
||||
activeUser.WebToken = *wt
|
||||
activeUser.PanClient().UpdateToken(*wt)
|
||||
userWebToken := NewWebLoginToken(wt.AccessToken, wt.Expired)
|
||||
activeUser.WebapiToken = &config.PanClientToken{
|
||||
AccessToken: wt.AccessToken,
|
||||
Expired: wt.Expired,
|
||||
}
|
||||
activeUser.PanClient().WebapiPanClient().UpdateToken(userWebToken)
|
||||
logger.Verboseln("get new access token success")
|
||||
|
||||
// plugin callback
|
||||
@@ -169,7 +189,7 @@ func RefreshTokenInNeed(activeUser *config.PanUser, deviceName string) bool {
|
||||
}
|
||||
|
||||
// create new signature
|
||||
_, e := activeUser.PanClient().CreateSession(nil)
|
||||
_, e := activeUser.PanClient().WebapiPanClient().CreateSession(nil)
|
||||
if e != nil {
|
||||
logger.Verboseln("call CreateSession error in RefreshTokenInNeed: " + e.Error())
|
||||
}
|
||||
@@ -179,8 +199,8 @@ func RefreshTokenInNeed(activeUser *config.PanUser, deviceName string) bool {
|
||||
// if token has expired, callback plugin api for notify
|
||||
if now.Unix() >= expiredTime.Unix() {
|
||||
params.Result = "fail"
|
||||
params.Message = er.Error()
|
||||
params.OldToken = activeUser.RefreshToken
|
||||
params.Message = e.Error()
|
||||
params.OldToken = activeUser.WebapiToken.AccessToken
|
||||
if er1 := plugin.UserTokenRefreshFinishCallback(plugins.GetContext(activeUser), params); er1 != nil {
|
||||
logger.Verbosef("UserTokenRefreshFinishCallback error: " + er1.Error())
|
||||
}
|
||||
@@ -205,110 +225,26 @@ func isMatchWildcardPattern(name string) bool {
|
||||
return strings.ContainsAny(name, "*") || strings.ContainsAny(name, "?") || strings.ContainsAny(name, "[")
|
||||
}
|
||||
|
||||
// DoLoginHelper 登录助手,使用token进行登录
|
||||
func DoLoginHelper(refreshToken string) (refreshTokenStr string, webToken aliyunpan.WebLoginToken, error error) {
|
||||
line := cmdliner.NewLiner()
|
||||
defer line.Close()
|
||||
|
||||
if refreshToken == "" {
|
||||
refreshToken, error = line.State.Prompt("请输入RefreshToken, 回车键提交 > ")
|
||||
if error != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// app login
|
||||
atoken, apperr := aliyunpan.GetAccessTokenFromRefreshToken(refreshToken)
|
||||
if apperr != nil {
|
||||
if apperr.Code == apierror.ApiCodeTokenExpiredCode || apperr.Code == apierror.ApiCodeRefreshTokenExpiredCode {
|
||||
fmt.Println("Token过期,需要重新登录")
|
||||
} else {
|
||||
fmt.Println("Token登录失败:", apperr)
|
||||
}
|
||||
return "", webToken, fmt.Errorf("登录失败")
|
||||
}
|
||||
refreshTokenStr = refreshToken
|
||||
return refreshTokenStr, *atoken, nil
|
||||
}
|
||||
|
||||
// TryLogin 尝试登录,基础应用支持的各类登录方式进行尝试成功登录
|
||||
func TryLogin() *config.PanUser {
|
||||
// 获取当前插件
|
||||
pluginManger := plugins.NewPluginManager(config.GetPluginDir())
|
||||
plugin, _ := pluginManger.GetPlugin()
|
||||
params := &plugins.UserTokenRefreshFinishParams{
|
||||
Result: "success",
|
||||
Message: "",
|
||||
OldToken: "",
|
||||
NewToken: "",
|
||||
UpdatedAt: utils.NowTimeStr(),
|
||||
}
|
||||
|
||||
// can do automatically login?
|
||||
for _, u := range config.Config.UserList {
|
||||
if u.UserId == config.Config.ActiveUID {
|
||||
// login
|
||||
_, webToken, err := DoLoginHelper(u.RefreshToken)
|
||||
if err != nil {
|
||||
logger.Verboseln("automatically login use saved refresh token error ", err)
|
||||
if u.TokenId != "" {
|
||||
logger.Verboseln("try to login use tokenId")
|
||||
h := panlogin.NewLoginHelper(config.DefaultTokenServiceWebHost)
|
||||
r, e := h.GetRefreshToken(u.TokenId)
|
||||
if e != nil {
|
||||
logger.Verboseln("try to login use tokenId error", e)
|
||||
// login fail plugin callback
|
||||
params.Result = "fail"
|
||||
params.OldToken = u.RefreshToken
|
||||
params.NewToken = ""
|
||||
if er := plugin.UserTokenRefreshFinishCallback(plugins.GetContext(u), params); er != nil {
|
||||
logger.Verbosef("UserTokenRefreshFinishCallback error: " + er.Error())
|
||||
}
|
||||
break
|
||||
}
|
||||
refreshToken, e := h.ParseSecureRefreshToken("", r.SecureRefreshToken)
|
||||
if e != nil {
|
||||
logger.Verboseln("try to parse refresh token error", e)
|
||||
break
|
||||
}
|
||||
_, webToken, err = DoLoginHelper(refreshToken)
|
||||
if err != nil {
|
||||
logger.Verboseln("try to use refresh token from tokenId error", e)
|
||||
break
|
||||
}
|
||||
fmt.Println("Token重新自动登录成功")
|
||||
// save new refresh token
|
||||
u.RefreshToken = refreshToken
|
||||
} else {
|
||||
// login fail plugin callback
|
||||
params.Result = "fail"
|
||||
params.OldToken = u.RefreshToken
|
||||
params.NewToken = ""
|
||||
if er := plugin.UserTokenRefreshFinishCallback(plugins.GetContext(u), params); er != nil {
|
||||
logger.Verbosef("UserTokenRefreshFinishCallback error: " + er.Error())
|
||||
}
|
||||
}
|
||||
break
|
||||
cloudUser, err := config.SetupUserByCookie(u.OpenapiToken, u.WebapiToken,
|
||||
u.TicketId, u.UserId,
|
||||
config.Config.DeviceId, config.Config.DeviceName,
|
||||
config.Config.ClientId, config.Config.ClientSecret)
|
||||
if cloudUser == nil {
|
||||
fmt.Println("尝试登录失败: ", err)
|
||||
return nil
|
||||
}
|
||||
// plugin param
|
||||
params.Result = "success"
|
||||
params.OldToken = u.RefreshToken
|
||||
params.NewToken = webToken.RefreshToken
|
||||
|
||||
// success login, save new token and access token
|
||||
u.RefreshToken = webToken.RefreshToken
|
||||
u.WebToken = webToken
|
||||
|
||||
// save
|
||||
SaveConfigFunc(nil)
|
||||
// reload
|
||||
ReloadConfigFunc(nil)
|
||||
|
||||
// do plugin callback
|
||||
if er := plugin.UserTokenRefreshFinishCallback(plugins.GetContext(u), params); er != nil {
|
||||
logger.Verbosef("UserTokenRefreshFinishCallback error: " + er.Error())
|
||||
}
|
||||
|
||||
return config.Config.ActiveUser()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func RunXCopy(srcDriveId, dstDriveId string, paths ...string) {
|
||||
copyFileParamList = append(copyFileParamList, mfi.FileId)
|
||||
cacheCleanPaths = append(cacheCleanPaths, path.Dir(mfi.Path))
|
||||
}
|
||||
fccr, er := activeUser.PanClient().FileCrossDriveCopy(&aliyunpan.FileCrossCopyParam{
|
||||
fccr, er := activeUser.PanClient().WebapiPanClient().FileCrossDriveCopy(&aliyunpan.FileCrossCopyParam{
|
||||
FromDriveId: srcDriveId,
|
||||
FromFileIds: copyFileParamList,
|
||||
ToDriveId: dstDriveId,
|
||||
@@ -151,7 +151,7 @@ func getCrossCopyFileInfo(srcDriveId, dstDriveId string, paths ...string) (opFil
|
||||
// the last one is the target file path
|
||||
targetFilePath := path.Clean(paths[len(paths)-1])
|
||||
absolutePath := activeUser.PathJoin(dstDriveId, targetFilePath)
|
||||
targetFile, err := activeUser.PanClient().FileInfoByPath(dstDriveId, absolutePath)
|
||||
targetFile, err := activeUser.PanClient().WebapiPanClient().FileInfoByPath(dstDriveId, absolutePath)
|
||||
if err != nil || !targetFile.IsFolder() {
|
||||
return nil, nil, nil, fmt.Errorf("指定目标文件夹不存在")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func (pu *PanUser) DeleteOneCache(dirPath string) {
|
||||
func (pu *PanUser) CacheFilesDirectoriesList(pathStr string) (fdl aliyunpan.FileList, apiError *apierror.ApiError) {
|
||||
data := pu.cacheOpMap.CacheOperation(pu.ActiveDriveId, pathStr+"_OrderByName", func() expires.DataExpires {
|
||||
var fi *aliyunpan.FileEntity
|
||||
fi, apiError = pu.panClient.FileInfoByPath(pu.ActiveDriveId, pathStr)
|
||||
fi, apiError = pu.panClient.WebapiPanClient().FileInfoByPath(pu.ActiveDriveId, pathStr)
|
||||
if apiError != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -38,7 +38,7 @@ func (pu *PanUser) CacheFilesDirectoriesList(pathStr string) (fdl aliyunpan.File
|
||||
DriveId: pu.ActiveDriveId,
|
||||
ParentFileId: fi.FileId,
|
||||
}
|
||||
fdl, apiError = pu.panClient.FileListGetAll(fileListParam, 100)
|
||||
fdl, apiError = pu.panClient.WebapiPanClient().FileListGetAll(fileListParam, 100)
|
||||
if apiError != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan_open"
|
||||
)
|
||||
|
||||
type (
|
||||
// PanClient 云盘客户端
|
||||
PanClient struct {
|
||||
// 网页WEB接口客户端
|
||||
webapiPanClient *aliyunpan.PanClient
|
||||
// 阿里openapi接口客户端
|
||||
openapiPanClient *aliyunpan_open.OpenPanClient
|
||||
}
|
||||
)
|
||||
|
||||
func NewPanClient(webClient *aliyunpan.PanClient, openClient *aliyunpan_open.OpenPanClient) *PanClient {
|
||||
return &PanClient{
|
||||
webapiPanClient: webClient,
|
||||
openapiPanClient: openClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PanClient) WebapiPanClient() *aliyunpan.PanClient {
|
||||
return p.webapiPanClient
|
||||
}
|
||||
|
||||
func (p *PanClient) OpenapiPanClient() *aliyunpan_open.OpenPanClient {
|
||||
return p.openapiPanClient
|
||||
}
|
||||
@@ -61,6 +61,9 @@ const (
|
||||
|
||||
// DefaultDeviceName 默认客户端名称
|
||||
DefaultDeviceName = "Chrome浏览器"
|
||||
|
||||
// DefaultClientId 默认的clientId
|
||||
DefaultClientId = "cf9f70e8fc61430f8ec5ab5cadf31375"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -69,11 +72,6 @@ var (
|
||||
|
||||
// Config 配置信息, 由外部调用
|
||||
Config = NewConfig(configFilePath)
|
||||
|
||||
AppVersion string
|
||||
|
||||
// IsAppInCliMode 是否在交互模式
|
||||
IsAppInCliMode = false
|
||||
)
|
||||
|
||||
type UpdateCheckInfo struct {
|
||||
@@ -110,6 +108,10 @@ type PanConfig struct {
|
||||
DeviceId string `json:"deviceId"` // 客户端ID,用于标识登录客户端,阿里单个账号最多允许10个客户端同时登录
|
||||
DeviceName string `json:"deviceName"` // 客户端名称,默认为:Chrome浏览器
|
||||
|
||||
// Openapi客户端信息
|
||||
ClientId string `json:"clientId"`
|
||||
ClientSecret string `json:"clientSecret"`
|
||||
|
||||
configFilePath string
|
||||
configFile *os.File
|
||||
fileMu sync.Mutex
|
||||
@@ -270,6 +272,9 @@ func (c *PanConfig) loadConfigFromFile() (err error) {
|
||||
if c.DeviceName == "" {
|
||||
c.DeviceName = DefaultDeviceName
|
||||
}
|
||||
if c.ClientId == "" {
|
||||
c.ClientId = DefaultClientId
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -294,6 +299,7 @@ func (c *PanConfig) initDefaultConfig() {
|
||||
c.VideoFileExtensions = DefaultVideoFileExtensions
|
||||
c.DeviceId = RandomDeviceId() // 生成默认客户端ID
|
||||
c.DeviceName = DefaultDeviceName
|
||||
c.ClientId = DefaultClientId
|
||||
c.FileRecordConfig = "1" // 默认开启
|
||||
c.PreferIPType = "ipv4" // 默认优先IPv4
|
||||
}
|
||||
@@ -390,7 +396,10 @@ func (c *PanConfig) ActiveUser() *PanUser {
|
||||
if u.UserId == c.ActiveUID {
|
||||
if u.PanClient() == nil {
|
||||
// restore client
|
||||
user, err := SetupUserByCookie(&u.WebToken, c.DeviceId, c.DeviceName)
|
||||
user, err := SetupUserByCookie(u.OpenapiToken, u.WebapiToken,
|
||||
u.TicketId, u.UserId,
|
||||
c.DeviceId, c.DeviceName,
|
||||
c.ClientId, c.ClientSecret)
|
||||
if err != nil {
|
||||
logger.Verboseln("setup user error")
|
||||
return nil
|
||||
@@ -401,7 +410,7 @@ func (c *PanConfig) ActiveUser() *PanUser {
|
||||
u.DriveList = user.DriveList
|
||||
// check workdir valid or not
|
||||
if user.IsFileDriveActive() {
|
||||
fe, err1 := u.PanClient().FileInfoByPath(u.ActiveDriveId, u.Workdir)
|
||||
fe, err1 := u.PanClient().WebapiPanClient().FileInfoByPath(u.ActiveDriveId, u.Workdir)
|
||||
if err1 != nil {
|
||||
// default to root
|
||||
u.Workdir = "/"
|
||||
@@ -410,7 +419,7 @@ func (c *PanConfig) ActiveUser() *PanUser {
|
||||
u.WorkdirFileEntity = *fe
|
||||
}
|
||||
} else if user.IsResourceDriveActive() {
|
||||
fe, err1 := u.PanClient().FileInfoByPath(u.ActiveDriveId, u.ResourceWorkdir)
|
||||
fe, err1 := u.PanClient().WebapiPanClient().FileInfoByPath(u.ActiveDriveId, u.ResourceWorkdir)
|
||||
if err1 != nil {
|
||||
// default to root
|
||||
u.ResourceWorkdir = "/"
|
||||
@@ -419,7 +428,7 @@ func (c *PanConfig) ActiveUser() *PanUser {
|
||||
u.ResourceWorkdirFileEntity = *fe
|
||||
}
|
||||
} else if user.IsAlbumDriveActive() {
|
||||
fe, err1 := u.PanClient().FileInfoByPath(u.ActiveDriveId, u.AlbumWorkdir)
|
||||
fe, err1 := u.PanClient().WebapiPanClient().FileInfoByPath(u.ActiveDriveId, u.AlbumWorkdir)
|
||||
if err1 != nil {
|
||||
// default to root
|
||||
u.AlbumWorkdir = "/"
|
||||
@@ -444,9 +453,9 @@ func (c *PanConfig) SetActiveUser(user *PanUser) *PanUser {
|
||||
if u.UserId == user.UserId {
|
||||
// update user info
|
||||
u.Nickname = user.Nickname
|
||||
u.WebToken = user.WebToken
|
||||
u.RefreshToken = user.RefreshToken
|
||||
u.TokenId = user.TokenId
|
||||
u.WebapiToken = user.WebapiToken
|
||||
u.OpenapiToken = user.OpenapiToken
|
||||
u.TicketId = user.TicketId
|
||||
needToInsert = false
|
||||
break
|
||||
}
|
||||
|
||||
+157
-66
@@ -17,10 +17,14 @@ import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan/apierror"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan_open"
|
||||
"github.com/tickstep/aliyunpan-api/aliyunpan_open/openapi"
|
||||
"github.com/tickstep/aliyunpan/internal/functions/panlogin"
|
||||
"github.com/tickstep/library-go/expires/cachemap"
|
||||
"github.com/tickstep/library-go/logger"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DriveInfo struct {
|
||||
@@ -57,12 +61,28 @@ func (d DriveInfoList) GetResourceDriveId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// PanClientToken 授权Token
|
||||
type PanClientToken struct {
|
||||
// AccessToken AccessToken
|
||||
AccessToken string `json:"accessToken"`
|
||||
// Expired 过期时间戳,单位秒
|
||||
Expired int64 `json:"expired"`
|
||||
}
|
||||
|
||||
// GetExpiredTimeCstStr 获取东八区时间字符串
|
||||
func (t *PanClientToken) GetExpiredTimeCstStr() string {
|
||||
cz := time.FixedZone("CST", 8*3600) // 东8区
|
||||
tm := time.Unix(t.Expired, 0).In(cz)
|
||||
return tm.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
type PanUser struct {
|
||||
// 用户信息
|
||||
UserId string `json:"userId"`
|
||||
Nickname string `json:"nickname"`
|
||||
AccountName string `json:"accountName"`
|
||||
|
||||
// 文件/备份盘
|
||||
// 文件(备份盘)
|
||||
Workdir string `json:"workdir"`
|
||||
WorkdirFileEntity aliyunpan.FileEntity `json:"workdirFileEntity"`
|
||||
|
||||
@@ -74,89 +94,115 @@ type PanUser struct {
|
||||
AlbumWorkdir string `json:"albumWorkdir"`
|
||||
AlbumWorkdirFileEntity aliyunpan.FileEntity `json:"albumWorkdirFileEntity"`
|
||||
|
||||
// 用户网盘信息
|
||||
ActiveDriveId string `json:"activeDriveId"`
|
||||
DriveList DriveInfoList `json:"driveList"`
|
||||
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
WebToken aliyunpan.WebLoginToken `json:"webToken"`
|
||||
TokenId string `json:"tokenId"`
|
||||
// 授权Token信息
|
||||
TicketId string `json:"ticketId"`
|
||||
WebapiToken *PanClientToken `json:"webapiToken"`
|
||||
OpenapiToken *PanClientToken `json:"openapiToken"`
|
||||
|
||||
panClient *aliyunpan.PanClient
|
||||
cacheOpMap cachemap.CacheOpMap
|
||||
// API客户端
|
||||
//panClient *aliyunpan.PanClient `json:"-"`
|
||||
panClient *PanClient `json:"-"`
|
||||
cacheOpMap cachemap.CacheOpMap `json:"-"`
|
||||
}
|
||||
|
||||
type PanUserList []*PanUser
|
||||
|
||||
func SetupUserByCookie(webToken *aliyunpan.WebLoginToken, deviceId, deviceName string) (user *PanUser, err *apierror.ApiError) {
|
||||
func SetupUserByCookie(openapiToken, webapiToken *PanClientToken, ticketId, userId, deviceId, deviceName, clientId, clientSecret string) (user *PanUser, err *apierror.ApiError) {
|
||||
tryRefreshWebToken := true
|
||||
tryRefreshOpenToken := true
|
||||
loginHelper := panlogin.NewLoginHelper(DefaultTokenServiceWebHost)
|
||||
|
||||
if webToken == nil {
|
||||
return nil, apierror.NewFailedApiError("web token is empty")
|
||||
if openapiToken == nil {
|
||||
return nil, apierror.NewFailedApiError("openapi token is empty")
|
||||
}
|
||||
if webapiToken == nil {
|
||||
return nil, apierror.NewFailedApiError("webapi token is empty")
|
||||
}
|
||||
|
||||
doLoginAct:
|
||||
appConfig := aliyunpan.AppConfig{
|
||||
AppId: "25dzX3vbYqktVxyX",
|
||||
DeviceId: deviceId,
|
||||
UserId: "",
|
||||
Nonce: 0,
|
||||
PublicKey: "",
|
||||
}
|
||||
panClient := aliyunpan.NewPanClient(*webToken, aliyunpan.AppLoginToken{}, appConfig, aliyunpan.SessionConfig{
|
||||
DeviceName: deviceName,
|
||||
ModelName: "Windows网页版",
|
||||
doOpenLoginAct:
|
||||
// setup openapi client
|
||||
openPanClient := aliyunpan_open.NewOpenPanClient(openapi.ApiConfig{
|
||||
TicketId: ticketId,
|
||||
UserId: userId,
|
||||
ClientId: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
}, openapi.ApiToken{
|
||||
AccessToken: openapiToken.AccessToken,
|
||||
ExpiredAt: openapiToken.Expired,
|
||||
}, func(newToken openapi.ApiToken) error {
|
||||
// TODO: save & refresh new token
|
||||
return nil
|
||||
})
|
||||
u := &PanUser{
|
||||
WebToken: *webToken,
|
||||
panClient: panClient,
|
||||
Workdir: "/",
|
||||
WorkdirFileEntity: *aliyunpan.NewFileEntityForRootDir(),
|
||||
}
|
||||
|
||||
// web api token maybe expired
|
||||
userInfo, err := panClient.GetUserInfo()
|
||||
// open api token maybe expired
|
||||
// check & refresh new one
|
||||
openUserInfo, err := openPanClient.GetUserInfo()
|
||||
if err != nil {
|
||||
if err.Code == apierror.ApiCodeTokenExpiredCode && tryRefreshWebToken {
|
||||
tryRefreshWebToken = false
|
||||
webCookie, _ := aliyunpan.GetAccessTokenFromRefreshToken(webToken.RefreshToken)
|
||||
if webCookie != nil {
|
||||
webToken = webCookie
|
||||
goto doLoginAct
|
||||
if err.Code == apierror.ApiCodeTokenExpiredCode && tryRefreshOpenToken {
|
||||
tryRefreshOpenToken = false
|
||||
wt, e := loginHelper.GetOpenapiNewToken(ticketId, userId)
|
||||
if e != nil {
|
||||
logger.Verboseln("get openapi token from server error: ", e)
|
||||
return nil, apierror.NewFailedApiError("get new openapi token error, try login again")
|
||||
}
|
||||
if wt != nil {
|
||||
openapiToken = &PanClientToken{
|
||||
AccessToken: wt.AccessToken,
|
||||
Expired: wt.Expired,
|
||||
}
|
||||
goto doOpenLoginAct
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
name := "Unknown"
|
||||
if userInfo != nil {
|
||||
if userInfo.Nickname != "" {
|
||||
name = userInfo.Nickname
|
||||
}
|
||||
|
||||
// update user
|
||||
u.UserId = userInfo.UserId
|
||||
u.Nickname = name
|
||||
u.AccountName = userInfo.UserName
|
||||
|
||||
// default file drive
|
||||
if u.ActiveDriveId == "" {
|
||||
u.ActiveDriveId = userInfo.FileDriveId
|
||||
doWebLoginAct:
|
||||
// setup webapi client
|
||||
appConfig := aliyunpan.AppConfig{
|
||||
AppId: "25dzX3vbYqktVxyX",
|
||||
DeviceId: deviceId,
|
||||
UserId: userId,
|
||||
Nonce: 0,
|
||||
PublicKey: "",
|
||||
}
|
||||
webPanClient := aliyunpan.NewPanClient(aliyunpan.WebLoginToken{
|
||||
AccessTokenType: "Bearer",
|
||||
AccessToken: webapiToken.AccessToken,
|
||||
RefreshToken: "",
|
||||
ExpiresIn: 7200,
|
||||
ExpireTime: webapiToken.GetExpiredTimeCstStr(),
|
||||
}, aliyunpan.AppLoginToken{}, appConfig, aliyunpan.SessionConfig{
|
||||
DeviceName: deviceName,
|
||||
ModelName: "Windows网页版",
|
||||
})
|
||||
// web api token maybe expired
|
||||
// check & refresh new one
|
||||
webUserInfo, err2 := webPanClient.GetUserInfo()
|
||||
if err != nil {
|
||||
if err2.Code == apierror.ApiCodeTokenExpiredCode && tryRefreshWebToken {
|
||||
tryRefreshWebToken = false
|
||||
wt, e := loginHelper.GetWebapiNewToken(ticketId, userId)
|
||||
if e != nil {
|
||||
logger.Verboseln("get web token from server error: ", e)
|
||||
}
|
||||
if wt != nil {
|
||||
webapiToken = &PanClientToken{
|
||||
AccessToken: wt.AccessToken,
|
||||
Expired: wt.Expired,
|
||||
}
|
||||
goto doWebLoginAct
|
||||
}
|
||||
}
|
||||
|
||||
// drive list
|
||||
u.DriveList = DriveInfoList{
|
||||
{DriveId: userInfo.FileDriveId, DriveTag: "File", DriveName: "备份盘"},
|
||||
{DriveId: userInfo.ResourceDriveId, DriveTag: "Resource", DriveName: "资源库"},
|
||||
{DriveId: userInfo.AlbumDriveId, DriveTag: "Album", DriveName: "相册"},
|
||||
}
|
||||
} else {
|
||||
// error, maybe the token has expired
|
||||
return nil, apierror.NewFailedApiError("cannot get user info, the token has expired")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create session
|
||||
appConfig.UserId = u.UserId
|
||||
panClient.UpdateAppConfig(appConfig)
|
||||
r, e := panClient.CreateSession(nil)
|
||||
// web create session
|
||||
appConfig.UserId = webUserInfo.UserId
|
||||
webPanClient.UpdateAppConfig(appConfig)
|
||||
r, e := webPanClient.CreateSession(nil)
|
||||
if e != nil {
|
||||
logger.Verboseln("call CreateSession error in SetupUserByCookie: " + e.Error())
|
||||
}
|
||||
@@ -164,10 +210,56 @@ doLoginAct:
|
||||
logger.Verboseln("上传签名秘钥失败,可能是你账号登录的设备已超最大数量")
|
||||
}
|
||||
|
||||
//
|
||||
// setup PanUser
|
||||
//
|
||||
u := &PanUser{
|
||||
WebapiToken: webapiToken,
|
||||
OpenapiToken: openapiToken,
|
||||
panClient: NewPanClient(webPanClient, openPanClient),
|
||||
Workdir: "/",
|
||||
WorkdirFileEntity: *aliyunpan.NewFileEntityForRootDir(),
|
||||
}
|
||||
|
||||
// setup user info
|
||||
name := "Unknown"
|
||||
if openUserInfo != nil {
|
||||
// fill userId for client
|
||||
u.PanClient().OpenapiPanClient().UpdateUserId(openUserInfo.UserId)
|
||||
u.PanClient().WebapiPanClient().UpdateUserId(openUserInfo.UserId)
|
||||
|
||||
// update user
|
||||
if openUserInfo.Nickname != "" {
|
||||
name = openUserInfo.Nickname
|
||||
}
|
||||
u.UserId = openUserInfo.UserId
|
||||
u.Nickname = name
|
||||
u.AccountName = openUserInfo.UserName
|
||||
|
||||
// default file drive
|
||||
if u.ActiveDriveId == "" {
|
||||
u.ActiveDriveId = openUserInfo.FileDriveId
|
||||
}
|
||||
|
||||
// drive list
|
||||
u.DriveList = DriveInfoList{
|
||||
{DriveId: openUserInfo.FileDriveId, DriveTag: "File", DriveName: "备份盘"},
|
||||
{DriveId: openUserInfo.ResourceDriveId, DriveTag: "Resource", DriveName: "资源库"},
|
||||
}
|
||||
if webUserInfo != nil {
|
||||
u.AccountName = webUserInfo.UserName
|
||||
u.DriveList = append(u.DriveList, &DriveInfo{DriveId: webUserInfo.AlbumDriveId, DriveTag: "Album", DriveName: "相册"})
|
||||
}
|
||||
} else {
|
||||
// error, maybe the token has expired
|
||||
return nil, apierror.NewFailedApiError("cannot get user info, the token has expired. please login again")
|
||||
}
|
||||
|
||||
// return user
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (pu *PanUser) PanClient() *aliyunpan.PanClient {
|
||||
func (pu *PanUser) PanClient() *PanClient {
|
||||
return pu.panClient
|
||||
}
|
||||
|
||||
@@ -192,21 +284,20 @@ func (pu *PanUser) PathJoin(driveId, p string) string {
|
||||
|
||||
func (pu *PanUser) FreshWorkdirInfo() {
|
||||
if pu.IsFileDriveActive() {
|
||||
fe, err := pu.PanClient().FileInfoById(pu.ActiveDriveId, pu.WorkdirFileEntity.FileId)
|
||||
fe, err := pu.PanClient().WebapiPanClient().FileInfoById(pu.ActiveDriveId, pu.WorkdirFileEntity.FileId)
|
||||
if err != nil {
|
||||
logger.Verboseln("刷新工作目录信息失败")
|
||||
return
|
||||
}
|
||||
pu.WorkdirFileEntity = *fe
|
||||
} else if pu.IsAlbumDriveActive() {
|
||||
fe, err := pu.PanClient().FileInfoById(pu.ActiveDriveId, pu.AlbumWorkdirFileEntity.FileId)
|
||||
fe, err := pu.PanClient().WebapiPanClient().FileInfoById(pu.ActiveDriveId, pu.AlbumWorkdirFileEntity.FileId)
|
||||
if err != nil {
|
||||
logger.Verboseln("刷新工作目录信息失败")
|
||||
return
|
||||
}
|
||||
pu.AlbumWorkdirFileEntity = *fe
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// GetSavePath 根据提供的网盘文件路径 panpath, 返回本地储存路径,
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/global"
|
||||
"github.com/tickstep/aliyunpan/internal/utils"
|
||||
"github.com/tickstep/library-go/crypto"
|
||||
"github.com/tickstep/library-go/getip"
|
||||
@@ -40,6 +40,17 @@ type QRCodeLoginResult struct {
|
||||
SecureRefreshToken string `json:"secureRefreshToken"`
|
||||
}
|
||||
|
||||
// LoginTokenResult Token结果
|
||||
type LoginTokenResult struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
Expired int64 `json:"expired"`
|
||||
}
|
||||
|
||||
type CommonTokenEntity struct {
|
||||
Openapi *LoginTokenResult `json:"openapi"`
|
||||
Webapi *LoginTokenResult `json:"webapi"`
|
||||
}
|
||||
|
||||
func NewLoginHelper(webHost string) *LoginHelper {
|
||||
return &LoginHelper{
|
||||
webHost: webHost,
|
||||
@@ -57,13 +68,13 @@ func (h *LoginHelper) GetQRCodeLoginUrl(keyStr string) (*QRCodeUrlResult, error)
|
||||
ipAddr = "127.0.0.1"
|
||||
}
|
||||
fmt.Fprintf(&fullUrl, "%s/auth/tickstep/aliyunpan/token/qrcode/create?ip=%s&os=%s&arch=%s&version=%s&key=%s",
|
||||
h.webHost, ipAddr, runtime.GOOS, runtime.GOARCH, config.AppVersion, keyStr)
|
||||
h.webHost, ipAddr, runtime.GOOS, runtime.GOARCH, global.AppVersion, keyStr)
|
||||
|
||||
logger.Verboseln("do request url: " + fullUrl.String())
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + config.AppVersion,
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
@@ -114,7 +125,7 @@ func (h *LoginHelper) GetQRCodeLoginResult(tokenId string) (*QRCodeLoginResult,
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + config.AppVersion,
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
@@ -154,7 +165,7 @@ func (h *LoginHelper) GetRefreshToken(tokenId string) (*QRCodeLoginResult, error
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + config.AppVersion,
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
@@ -220,3 +231,123 @@ func (h *LoginHelper) ParseSecureRefreshToken(keyStr, secureRefreshToken string)
|
||||
}
|
||||
return refreshToken, nil
|
||||
}
|
||||
|
||||
// GetWebapiNewToken 获取Webapi Token
|
||||
func (h *LoginHelper) GetWebapiNewToken(ticketId, userId string) (*LoginTokenResult, error) {
|
||||
fullUrl := strings.Builder{}
|
||||
fmt.Fprintf(&fullUrl, "%s/auth/tickstep/aliyunpan/token/webapi/%s/refresh?userId=%s",
|
||||
h.webHost, ticketId, userId)
|
||||
logger.Verboseln("do request url: " + fullUrl.String())
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
client.SetTimeout(20 * time.Second)
|
||||
client.SetKeepAlive(false)
|
||||
body, err := client.Fetch("GET", fullUrl.String(), nil, header)
|
||||
if err != nil {
|
||||
logger.Verboseln("get web token result error ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
errResp := &LoginHttpResult{}
|
||||
if err1 := json.Unmarshal(body, errResp); err1 != nil {
|
||||
logger.Verboseln("parse result json error ", err1)
|
||||
return nil, err1
|
||||
}
|
||||
if errResp.Code != 0 {
|
||||
return nil, fmt.Errorf(errResp.Msg)
|
||||
}
|
||||
|
||||
// parse result
|
||||
r := &LoginHttpResult{}
|
||||
r.Data = &LoginTokenResult{}
|
||||
if err2 := json.Unmarshal(body, r); err2 != nil {
|
||||
logger.Verboseln("parse web token result json error ", err2)
|
||||
return nil, err2
|
||||
}
|
||||
return r.Data.(*LoginTokenResult), nil
|
||||
}
|
||||
|
||||
// GetOpenapiNewToken 获取Openapi Token
|
||||
func (h *LoginHelper) GetOpenapiNewToken(ticketId, userId string) (*LoginTokenResult, error) {
|
||||
fullUrl := strings.Builder{}
|
||||
fmt.Fprintf(&fullUrl, "%s/auth/tickstep/aliyunpan/token/openapi/%s/refresh?userId=%s",
|
||||
h.webHost, ticketId, userId)
|
||||
logger.Verboseln("do request url: " + fullUrl.String())
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
client.SetTimeout(20 * time.Second)
|
||||
client.SetKeepAlive(false)
|
||||
body, err := client.Fetch("GET", fullUrl.String(), nil, header)
|
||||
if err != nil {
|
||||
logger.Verboseln("get openapi token result error ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
errResp := &LoginHttpResult{}
|
||||
if err1 := json.Unmarshal(body, errResp); err1 != nil {
|
||||
logger.Verboseln("parse result json error ", err1)
|
||||
return nil, err1
|
||||
}
|
||||
if errResp.Code != 0 {
|
||||
return nil, fmt.Errorf(errResp.Msg)
|
||||
}
|
||||
|
||||
// parse result
|
||||
r := &LoginHttpResult{}
|
||||
r.Data = &LoginTokenResult{}
|
||||
if err2 := json.Unmarshal(body, r); err2 != nil {
|
||||
logger.Verboseln("parse openapi token result json error ", err2)
|
||||
return nil, err2
|
||||
}
|
||||
return r.Data.(*LoginTokenResult), nil
|
||||
}
|
||||
|
||||
// GetLoginToken 获取登录后的Token
|
||||
func (h *LoginHelper) GetLoginToken(ticketId string) (*CommonTokenEntity, error) {
|
||||
fullUrl := strings.Builder{}
|
||||
fmt.Fprintf(&fullUrl, "%s/auth/tickstep/aliyunpan/token/common/%s/login",
|
||||
h.webHost, ticketId)
|
||||
logger.Verboseln("do request url: " + fullUrl.String())
|
||||
header := map[string]string{
|
||||
"accept": "application/json, text/plain, */*",
|
||||
"content-type": "application/json;charset=UTF-8",
|
||||
"user-agent": "aliyunpan/" + global.AppVersion,
|
||||
}
|
||||
// request
|
||||
client := requester.NewHTTPClient()
|
||||
client.SetTimeout(20 * time.Second)
|
||||
client.SetKeepAlive(false)
|
||||
body, err := client.Fetch("GET", fullUrl.String(), nil, header)
|
||||
if err != nil {
|
||||
logger.Verboseln("get login token result error ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
errResp := &LoginHttpResult{}
|
||||
if err1 := json.Unmarshal(body, errResp); err1 != nil {
|
||||
logger.Verboseln("parse result json error ", err1)
|
||||
return nil, err1
|
||||
}
|
||||
if errResp.Code != 0 {
|
||||
return nil, fmt.Errorf(errResp.Msg)
|
||||
}
|
||||
|
||||
// parse result
|
||||
r := &LoginHttpResult{}
|
||||
r.Data = &CommonTokenEntity{}
|
||||
if err2 := json.Unmarshal(body, r); err2 != nil {
|
||||
logger.Verboseln("parse login token result json error ", err2)
|
||||
return nil, err2
|
||||
}
|
||||
return r.Data.(*CommonTokenEntity), nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package global
|
||||
|
||||
var (
|
||||
// AppVersion 应用版本
|
||||
AppVersion string
|
||||
|
||||
// IsAppInCliMode 是否在交互模式
|
||||
IsAppInCliMode = false
|
||||
)
|
||||
@@ -4,7 +4,7 @@
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/tickstep/aliyunpan/cmder/cmdliner"
|
||||
"github.com/tickstep/aliyunpan/cmder/cmdutil"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/global"
|
||||
"github.com/tickstep/aliyunpan/internal/utils"
|
||||
"github.com/tickstep/aliyunpan/library/requester/transfer"
|
||||
"github.com/tickstep/library-go/cachepool"
|
||||
@@ -66,7 +67,7 @@ func getReleaseFromTicstep(client *requester.HTTPClient, showPrompt bool) *Relea
|
||||
ipAddr = "127.0.0.1"
|
||||
}
|
||||
fmt.Fprintf(&fullUrl, "http://api.tickstep.com/update/tickstep/aliyunpan/releases/latest?ip=%s&os=%s&arch=%s&version=%s",
|
||||
ipAddr, runtime.GOOS, runtime.GOARCH, config.AppVersion)
|
||||
ipAddr, runtime.GOOS, runtime.GOARCH, global.AppVersion)
|
||||
resp, err := client.Req(http.MethodGet, fullUrl.String(), nil, nil)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -3,6 +3,7 @@ package plugins
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan/internal/config"
|
||||
"github.com/tickstep/aliyunpan/internal/global"
|
||||
"github.com/tickstep/library-go/logger"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -21,7 +22,7 @@ func GetContext(user *config.PanUser) *Context {
|
||||
if user == nil {
|
||||
return &Context{
|
||||
AppName: "aliyunpan",
|
||||
Version: config.AppVersion,
|
||||
Version: global.AppVersion,
|
||||
UserId: "",
|
||||
Nickname: "",
|
||||
FileDriveId: "",
|
||||
@@ -30,7 +31,7 @@ func GetContext(user *config.PanUser) *Context {
|
||||
}
|
||||
return &Context{
|
||||
AppName: "aliyunpan",
|
||||
Version: config.AppVersion,
|
||||
Version: global.AppVersion,
|
||||
UserId: user.UserId,
|
||||
Nickname: user.Nickname,
|
||||
FileDriveId: user.DriveList.GetFileDriveId(),
|
||||
|
||||
@@ -15,6 +15,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tickstep/aliyunpan/internal/global"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -61,7 +62,7 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
config.AppVersion = Version
|
||||
global.AppVersion = Version
|
||||
cmdutil.ChWorkDir()
|
||||
|
||||
err := config.Config.Init()
|
||||
@@ -147,7 +148,7 @@ func main() {
|
||||
|
||||
os.Setenv(config.EnvVerbose, c.String("verbose"))
|
||||
isCli = true
|
||||
config.IsAppInCliMode = true
|
||||
global.IsAppInCliMode = true
|
||||
logger.Verbosef("提示: 你已经开启VERBOSE调试日志\n\n")
|
||||
|
||||
var (
|
||||
@@ -309,9 +310,9 @@ func main() {
|
||||
// check update
|
||||
command.ReloadConfigFunc(c)
|
||||
if config.Config.UpdateCheckInfo.LatestVer != "" {
|
||||
if utils.ParseVersionNum(config.Config.UpdateCheckInfo.LatestVer) > utils.ParseVersionNum(config.AppVersion) {
|
||||
if utils.ParseVersionNum(config.Config.UpdateCheckInfo.LatestVer) > utils.ParseVersionNum(global.AppVersion) {
|
||||
fmt.Printf("\n当前的软件版本为:%s, 现在有新版本 %s 可供更新,强烈推荐进行更新!(可以输入 update 命令进行更新)\n\n",
|
||||
config.AppVersion, config.Config.UpdateCheckInfo.LatestVer)
|
||||
global.AppVersion, config.Config.UpdateCheckInfo.LatestVer)
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
@@ -415,7 +416,7 @@ func main() {
|
||||
command.CmdQuota(),
|
||||
|
||||
// Token操作
|
||||
command.CmdToken(),
|
||||
//command.CmdToken(),
|
||||
|
||||
// 切换工作目录 cd
|
||||
command.CmdCd(),
|
||||
|
||||
Reference in New Issue
Block a user