add sync file finish callback for plugin #166

This commit is contained in:
xiaoyaofenfen 2022-10-10 11:35:40 +08:00
parent 072e7e9261
commit f90829aaab
6 changed files with 173 additions and 1 deletions

View File

@ -151,4 +151,59 @@ function syncScanPanFilePrepareCallback(context, params) {
// }
return result;
}
// ------------------------------------------------------------------------------------------
// 函数说明:同步备份-同步文件后的回调函数
//
// 参数说明
// context - 当前调用的上下文信息
// {
// "appName": "aliyunpan",
// "version": "v0.1.3",
// "userId": "11001d48564f43b3bc5662874f04bb11",
// "nickname": "tickstep",
// "fileDriveId": "19519111",
// "albumDriveId": "29519122"
// }
// appName - 应用名称当前固定为aliyunpan
// version - 版本号
// userId - 当前登录用户的ID
// nickname - 用户昵称
// fileDriveId - 用户文件网盘ID
// albumDriveId - 用户相册网盘ID
//
// params - 同步文件后的参数
// {
// "action": "upload",
// "actionResult": "success",
// "driveId": "19519221",
// "fileName": "1.txt",
// "filePath": "D:/goprojects/dev/upload/1.txt",
// "fileSha1": "294C8F24C56042710813E95C55A0B018299BA9A7",
// "fileSize": "28077",
// "fileType": "file",
// "fileUpdatedAt": "2022-03-04 15:19:47"
// }
// action - 同步动作,
// download-下载文件,
// upload-上传文件,
// delete_local-删除本地文件,
// delete_pan-删除云盘文件,
// create_local_folder-创建本地文件夹,
// create_pan_folder-创建云盘文件夹
// actionResult - 同步结果success-成功fail-失败
// driveId - 网盘ID
// fileName - 文件名称
// filePath - 文件完整路径
// fileSha1 - 文件SHA1
// fileSize - 文件大小单位B
// fileType - 文件类型file-文件folder-文件夹
// fileUpdatedAt - 文件修改时间
//
// 返回值说明
// (无)
// ------------------------------------------------------------------------------------------
function syncFileFinishCallback(context, params) {
console.log(params)
}

View File

@ -40,6 +40,10 @@ func (p *IdlePlugin) SyncScanPanFilePrepareCallback(context *Context, params *Sy
return nil, nil
}
func (p *IdlePlugin) SyncFileFinishCallback(context *Context, params *SyncFileFinishParams) error {
return nil
}
func (p *IdlePlugin) Stop() error {
return nil
}

View File

@ -190,6 +190,25 @@ func (js *JsPlugin) SyncScanPanFilePrepareCallback(context *Context, params *Syn
return r, nil
}
// SyncFileFinishCallback 同步备份-同步文件完成的回调函数
func (js *JsPlugin) SyncFileFinishCallback(context *Context, params *SyncFileFinishParams) error {
var fn func(*Context, *SyncFileFinishParams) error
if !js.isHandlerFuncExisted("syncFileFinishCallback") {
return nil
}
err := js.vm.ExportTo(js.vm.Get("syncFileFinishCallback"), &fn)
if err != nil {
logger.Verboseln("Js函数映射到 Go 函数失败!")
return nil
}
er := fn(context, params)
if er != nil {
logger.Verboseln(er)
return nil
}
return nil
}
func (js *JsPlugin) Stop() error {
return nil
}

View File

@ -122,6 +122,19 @@ type (
SyncScanPanApproved string `json:"syncScanPanApproved"`
}
// SyncFileFinishParams 同步备份-文件同步结束-回调参数
SyncFileFinishParams struct {
Action string `json:"action"`
ActionResult string `json:"actionResult"`
DriveId string `json:"driveId"`
FileName string `json:"fileName"`
FilePath string `json:"filePath"`
FileSha1 string `json:"fileSha1"`
FileSize int64 `json:"fileSize"`
FileType string `json:"fileType"`
FileUpdatedAt string `json:"fileUpdatedAt"`
}
// Plugin 插件接口
Plugin interface {
// Start 启动
@ -145,6 +158,9 @@ type (
// SyncScanPanFilePrepareCallback 同步备份-扫描本地文件的回调函数
SyncScanPanFilePrepareCallback(context *Context, params *SyncScanPanFilePrepareParams) (*SyncScanPanFilePrepareResult, error)
// SyncFileFinishCallback 同步备份-同步文件完成的回调函数
SyncFileFinishCallback(context *Context, params *SyncFileFinishParams) error
// Stop 停止
Stop() error
}

View File

@ -637,7 +637,7 @@ func (f *FileActionTask) deletePanFile(ctx context.Context) error {
// 删除
var fileDeleteResult []*aliyunpan.FileBatchActionResult
var err *apierror.ApiError
var err *apierror.ApiError = nil
fileDeleteResult, err = f.panClient.FileDelete([]*aliyunpan.FileBatchActionParam{{DriveId: driveId, FileId: panFileId}})
time.Sleep(1 * time.Second)
if err != nil || len(fileDeleteResult) == 0 {
@ -647,6 +647,9 @@ func (f *FileActionTask) deletePanFile(ctx context.Context) error {
}
f.syncItem.StatusUpdateTime = utils.NowTimeStr()
f.syncFileDb.Update(f.syncItem)
if err == nil {
return nil
}
return err
}

View File

@ -5,7 +5,9 @@ import (
"fmt"
mapset "github.com/deckarep/golang-set"
"github.com/tickstep/aliyunpan-api/aliyunpan"
"github.com/tickstep/aliyunpan/internal/config"
"github.com/tickstep/aliyunpan/internal/localfile"
"github.com/tickstep/aliyunpan/internal/plugins"
"github.com/tickstep/aliyunpan/internal/waitgroup"
"github.com/tickstep/aliyunpan/library/collection"
"github.com/tickstep/library-go/logger"
@ -36,6 +38,12 @@ type (
panFolderModifyCount int // 云盘文件扫描变更记录次数作为后续文件对比进程的参考以节省CPU资源
syncActionModifyCount int // 文件对比进程检测的文件上传下载删除变更记录次数作为后续文件上传下载处理进程的参考以节省CPU资源
resourceModifyMutex *sync.Mutex
panUser *config.PanUser
// 插件
plugin plugins.Plugin
pluginMutex *sync.Mutex
}
localFileSet struct {
@ -62,6 +70,8 @@ func NewFileActionTaskManager(task *SyncTask) *FileActionTaskManager {
panFolderModifyCount: 1,
syncActionModifyCount: 1,
resourceModifyMutex: &sync.Mutex{},
panUser: task.panUser,
}
}
@ -140,6 +150,14 @@ func (f *FileActionTaskManager) Start() error {
f.ctx, cancel = context.WithCancel(context.Background())
f.cancelFunc = cancel
if f.plugin == nil {
pluginManger := plugins.NewPluginManager(config.GetPluginDir())
f.plugin, _ = pluginManger.GetPlugin()
}
if f.pluginMutex == nil {
f.pluginMutex = &sync.Mutex{}
}
go f.doLocalFileDiffRoutine(f.ctx)
go f.doPanFileDiffRoutine(f.ctx)
go f.fileActionTaskExecutor(f.ctx)
@ -798,9 +816,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := uploadItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(uploadItem.syncItem)
f.doPluginCallback(uploadItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(uploadItem.syncItem)
f.doPluginCallback(uploadItem.syncItem, "fail")
}
uploadWaitGroup.Done()
}()
@ -818,9 +838,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := downloadItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(downloadItem.syncItem)
f.doPluginCallback(downloadItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(downloadItem.syncItem)
f.doPluginCallback(downloadItem.syncItem, "fail")
}
downloadWaitGroup.Done()
}()
@ -838,9 +860,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := deleteLocalItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(deleteLocalItem.syncItem)
f.doPluginCallback(deleteLocalItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(deleteLocalItem.syncItem)
f.doPluginCallback(deleteLocalItem.syncItem, "fail")
}
localFileWaitGroup.Done()
}()
@ -858,9 +882,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := deletePanItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(deletePanItem.syncItem)
f.doPluginCallback(deletePanItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(deletePanItem.syncItem)
f.doPluginCallback(deletePanItem.syncItem, "fail")
}
panFileWaitGroup.Done()
}()
@ -878,9 +904,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := createLocalFolderItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(createLocalFolderItem.syncItem)
f.doPluginCallback(createLocalFolderItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(createLocalFolderItem.syncItem)
f.doPluginCallback(createLocalFolderItem.syncItem, "fail")
}
localFileWaitGroup.Done()
}()
@ -898,9 +926,11 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
if e := createPanFolderItem.DoAction(ctx); e == nil {
// success
f.fileInProcessQueue.Remove(createPanFolderItem.syncItem)
f.doPluginCallback(createPanFolderItem.syncItem, "success")
} else {
// retry?
f.fileInProcessQueue.Remove(createPanFolderItem.syncItem)
f.doPluginCallback(createPanFolderItem.syncItem, "fail")
}
panFileWaitGroup.Done()
}()
@ -920,6 +950,51 @@ func (f *FileActionTaskManager) fileActionTaskExecutor(ctx context.Context) {
}
}
func (f *FileActionTaskManager) doPluginCallback(syncFile *SyncFileItem, actionResult string) bool {
// 插件回调
var pluginParam *plugins.SyncFileFinishParams
if syncFile.Action == SyncFileActionUpload ||
syncFile.Action == SyncFileActionCreatePanFolder ||
syncFile.Action == SyncFileActionDeletePan {
file := syncFile.LocalFile
pluginParam = &plugins.SyncFileFinishParams{
Action: string(syncFile.Action),
ActionResult: actionResult,
DriveId: syncFile.DriveId,
FileName: file.FileName,
FilePath: syncFile.getPanFileFullPath(),
FileSha1: file.Sha1Hash,
FileSize: file.FileSize,
FileType: file.FileType,
FileUpdatedAt: file.UpdatedAt,
}
} else if syncFile.Action == SyncFileActionDownload ||
syncFile.Action == SyncFileActionCreateLocalFolder ||
syncFile.Action == SyncFileActionDeleteLocal {
file := syncFile.PanFile
pluginParam = &plugins.SyncFileFinishParams{
Action: string(syncFile.Action),
ActionResult: actionResult,
DriveId: syncFile.DriveId,
FileName: file.FileName,
FilePath: syncFile.getLocalFileFullPath(),
FileSha1: file.Sha1Hash,
FileSize: file.FileSize,
FileType: file.FileType,
FileUpdatedAt: file.UpdatedAt,
}
} else {
return false
}
f.pluginMutex.Lock()
defer f.pluginMutex.Unlock()
if er := f.plugin.SyncFileFinishCallback(plugins.GetContext(f.panUser), pluginParam); er == nil {
return true
}
return false
}
// getRelativePath 获取文件的相对路径
func (l *localFileSet) getRelativePath(localPath string) string {
localPath = strings.ReplaceAll(localPath, "\\", "/")