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