aliyunpan/internal/syncdrive/sync_task.go

633 lines
17 KiB
Go
Raw Normal View History

2022-05-22 16:42:57 +08:00
package syncdrive
import (
"context"
"fmt"
2022-05-22 17:47:48 +08:00
"github.com/tickstep/aliyunpan-api/aliyunpan"
2022-06-17 23:37:32 +08:00
"github.com/tickstep/aliyunpan-api/aliyunpan/apierror"
2022-06-14 21:05:40 +08:00
"github.com/tickstep/aliyunpan/internal/config"
"github.com/tickstep/aliyunpan/internal/plugins"
2022-05-22 16:42:57 +08:00
"github.com/tickstep/aliyunpan/internal/utils"
"github.com/tickstep/aliyunpan/internal/waitgroup"
"github.com/tickstep/aliyunpan/library/collection"
"github.com/tickstep/library-go/logger"
"io/ioutil"
"os"
"path"
"strings"
"sync"
2022-05-22 16:42:57 +08:00
"time"
)
type (
SyncMode string
// SyncTask 同步任务
SyncTask struct {
2022-05-24 19:56:06 +08:00
// Name 任务名称
Name string `json:"name"`
2022-05-22 16:42:57 +08:00
// Id 任务ID
Id string `json:"id"`
// DriveId 网盘ID目前支持文件网盘
2022-06-09 19:58:16 +08:00
DriveId string `json:"-"`
2022-05-22 16:42:57 +08:00
// LocalFolderPath 本地目录
LocalFolderPath string `json:"localFolderPath"`
// PanFolderPath 云盘目录
PanFolderPath string `json:"panFolderPath"`
// Mode 同步模式
Mode SyncMode `json:"mode"`
2022-08-13 18:38:29 +08:00
// Priority 优先级选项
Priority SyncPriorityOption `json:"priority"`
2022-05-22 16:42:57 +08:00
// LastSyncTime 上一次同步时间
LastSyncTime string `json:"lastSyncTime"`
syncDbFolderPath string
localFileDb LocalSyncDb
panFileDb PanSyncDb
2022-06-01 21:55:03 +08:00
syncFileDb SyncFileDb
2022-05-22 16:42:57 +08:00
wg *waitgroup.WaitGroup
ctx context.Context
cancelFunc context.CancelFunc
2022-05-22 17:47:48 +08:00
2022-06-14 21:05:40 +08:00
panUser *config.PanUser
2022-05-22 17:47:48 +08:00
panClient *aliyunpan.PanClient
2022-06-01 21:55:03 +08:00
2022-08-13 16:54:42 +08:00
syncOption SyncOption
2022-06-12 17:03:05 +08:00
2022-06-01 21:55:03 +08:00
fileActionTaskManager *FileActionTaskManager
2022-06-14 21:05:40 +08:00
plugin plugins.Plugin
pluginMutex *sync.Mutex
2022-05-22 16:42:57 +08:00
}
)
const (
2022-06-09 14:52:49 +08:00
// UploadOnly 单向上传,即备份本地文件到云盘
2022-05-22 16:42:57 +08:00
UploadOnly SyncMode = "upload"
2022-06-09 14:52:49 +08:00
// DownloadOnly 只下载,即备份云盘文件到本地
2022-05-22 16:42:57 +08:00
DownloadOnly SyncMode = "download"
2022-06-09 14:52:49 +08:00
// SyncTwoWay 双向同步,本地和云盘文件完全保持一致
2022-05-22 16:42:57 +08:00
SyncTwoWay SyncMode = "sync"
)
2022-05-24 19:56:06 +08:00
func (t *SyncTask) NameLabel() string {
return t.Name + "(" + t.Id + ")"
}
func (t *SyncTask) String() string {
builder := &strings.Builder{}
builder.WriteString("任务: " + t.NameLabel() + "\n")
2022-06-09 19:58:16 +08:00
mode := "双向备份"
2022-05-24 19:56:06 +08:00
if t.Mode == UploadOnly {
2022-06-09 19:58:16 +08:00
mode = "备份本地文件(只上传)"
2022-05-24 19:56:06 +08:00
}
2022-06-09 19:58:16 +08:00
if t.Mode == DownloadOnly {
mode = "备份云盘文件(只下载)"
2022-05-24 19:56:06 +08:00
}
builder.WriteString("同步模式: " + mode + "\n")
if t.Mode == SyncTwoWay {
priority := "时间优先"
if t.syncOption.SyncPriority == SyncPriorityLocalFirst {
priority = "本地文件优先"
} else if t.syncOption.SyncPriority == SyncPriorityPanFirst {
priority = "网盘文件优先"
} else {
priority = "时间优先"
}
builder.WriteString("优先选项: " + priority + "\n")
}
2022-05-24 19:56:06 +08:00
builder.WriteString("本地目录: " + t.LocalFolderPath + "\n")
builder.WriteString("云盘目录: " + t.PanFolderPath + "\n")
return builder.String()
}
2022-06-04 16:45:45 +08:00
func (t *SyncTask) setupDb() error {
2022-06-01 21:55:03 +08:00
t.localFileDb = NewLocalSyncDb(t.localSyncDbFullPath())
t.panFileDb = NewPanSyncDb(t.panSyncDbFullPath())
t.syncFileDb = NewSyncFileDb(t.syncFileDbFullPath())
if _, e := t.localFileDb.Open(); e != nil {
return e
}
if _, e := t.panFileDb.Open(); e != nil {
return e
}
2022-06-04 16:45:45 +08:00
if _, e := t.syncFileDb.Open(); e != nil {
return e
}
2022-06-01 21:55:03 +08:00
return nil
}
2022-05-22 16:42:57 +08:00
// Start 启动同步任务
2022-06-09 14:52:49 +08:00
// 扫描本地和云盘文件信息并存储到本地数据库
2022-05-22 16:42:57 +08:00
func (t *SyncTask) Start() error {
if t.ctx != nil {
return fmt.Errorf("task have starting")
}
2022-06-04 16:45:45 +08:00
t.setupDb()
2022-06-01 21:55:03 +08:00
2022-06-17 23:37:32 +08:00
// check root dir
if b, e := utils.PathExists(t.LocalFolderPath); e == nil {
if !b {
// create local root folder
os.MkdirAll(t.LocalFolderPath, 0755)
}
}
if _, er := t.panClient.FileInfoByPath(t.DriveId, t.PanFolderPath); er != nil {
if er.Code == apierror.ApiCodeFileNotFoundCode {
t.panClient.MkdirByFullPath(t.DriveId, t.PanFolderPath)
}
}
2022-06-01 21:55:03 +08:00
if t.fileActionTaskManager == nil {
2022-08-13 16:54:42 +08:00
t.fileActionTaskManager = NewFileActionTaskManager(t)
2022-06-01 21:55:03 +08:00
}
2022-05-22 16:42:57 +08:00
2022-06-14 21:05:40 +08:00
if t.plugin == nil {
pluginManger := plugins.NewPluginManager(config.GetPluginDir())
t.plugin, _ = pluginManger.GetPlugin()
}
if t.pluginMutex == nil {
t.pluginMutex = &sync.Mutex{}
}
2022-06-14 21:05:40 +08:00
2022-06-06 19:13:37 +08:00
t.wg = waitgroup.NewWaitGroup(0)
2022-05-22 16:42:57 +08:00
var cancel context.CancelFunc
t.ctx, cancel = context.WithCancel(context.Background())
t.cancelFunc = cancel
go t.scanLocalFile(t.ctx)
go t.scanPanFile(t.ctx)
2022-06-01 21:55:03 +08:00
2022-06-04 16:45:45 +08:00
// start file sync manager
if e := t.fileActionTaskManager.Start(); e != nil {
return e
}
2022-05-22 16:42:57 +08:00
return nil
}
// Stop 停止同步任务
func (t *SyncTask) Stop() error {
if t.ctx == nil {
return nil
}
// cancel all sub task & process
t.cancelFunc()
// wait for finished
t.wg.Wait()
t.ctx = nil
t.cancelFunc = nil
2022-06-01 21:55:03 +08:00
// stop file action task (block routine)
t.fileActionTaskManager.Stop()
2022-05-22 16:42:57 +08:00
// release resources
if t.localFileDb != nil {
t.localFileDb.Close()
}
if t.panFileDb != nil {
t.panFileDb.Close()
}
2022-06-01 21:55:03 +08:00
if t.syncFileDb != nil {
t.syncFileDb.Close()
}
2022-05-24 19:56:06 +08:00
// record the sync time
t.LastSyncTime = utils.NowTimeStr()
2022-05-22 16:42:57 +08:00
return nil
}
// panSyncDbFullPath 云盘文件数据库
func (t *SyncTask) panSyncDbFullPath() string {
dir := path.Join(t.syncDbFolderPath, t.Id)
if b, _ := utils.PathExists(dir); !b {
2022-06-16 22:30:12 +08:00
os.MkdirAll(dir, 0755)
2022-05-22 16:42:57 +08:00
}
return path.Join(dir, "pan.bolt")
}
// localSyncDbFullPath 本地文件数据库
func (t *SyncTask) localSyncDbFullPath() string {
dir := path.Join(t.syncDbFolderPath, t.Id)
if b, _ := utils.PathExists(dir); !b {
2022-06-16 22:30:12 +08:00
os.MkdirAll(dir, 0755)
2022-05-22 16:42:57 +08:00
}
return path.Join(dir, "local.bolt")
}
2022-06-01 21:55:03 +08:00
// syncFileDbFullPath 同步文件过程数据库
func (t *SyncTask) syncFileDbFullPath() string {
dir := path.Join(t.syncDbFolderPath, t.Id)
if b, _ := utils.PathExists(dir); !b {
2022-06-16 22:30:12 +08:00
os.MkdirAll(dir, 0755)
2022-06-01 21:55:03 +08:00
}
return path.Join(dir, "sync.bolt")
}
2022-05-22 16:42:57 +08:00
func newLocalFileItem(file os.FileInfo, fullPath string) *LocalFileItem {
ft := "file"
if file.IsDir() {
ft = "folder"
}
return &LocalFileItem{
FileName: file.Name(),
FileSize: file.Size(),
FileType: ft,
CreatedAt: file.ModTime().Format("2006-01-02 15:04:05"),
UpdatedAt: file.ModTime().Format("2006-01-02 15:04:05"),
FileExtension: path.Ext(file.Name()),
Sha1Hash: "",
Path: fullPath,
2022-06-04 13:20:33 +08:00
ScanTimeAt: utils.NowTimeStr(),
2022-06-09 14:52:49 +08:00
ScanStatus: ScanStatusNormal,
2022-06-04 13:20:33 +08:00
}
}
2022-06-09 14:52:49 +08:00
// discardLocalFileDb 清理本地数据库中无效的数据项
2022-06-23 16:40:10 +08:00
func (t *SyncTask) discardLocalFileDb(filePath string, startTimeUnix int64) bool {
2022-06-04 13:20:33 +08:00
files, e := t.localFileDb.GetFileList(filePath)
2022-06-23 16:40:10 +08:00
r := false
2022-06-04 13:20:33 +08:00
if e != nil {
2022-06-23 16:40:10 +08:00
return r
2022-06-04 13:20:33 +08:00
}
for _, file := range files {
if file.ScanTimeAt == "" || file.ScanTimeUnix() < startTimeUnix {
2022-06-23 16:40:10 +08:00
if t.Mode == DownloadOnly {
// delete discard local file info directly
t.localFileDb.Delete(file.Path)
logger.Verboseln("label discard local file from DB: ", utils.ObjectToJsonStr(file, false))
} else {
// label file discard
file.ScanStatus = ScanStatusDiscard
t.localFileDb.Update(file)
logger.Verboseln("label local file discard: ", utils.ObjectToJsonStr(file, false))
}
r = true
2022-06-04 13:20:33 +08:00
} else {
if file.IsFolder() {
2022-06-23 16:40:10 +08:00
b := t.discardLocalFileDb(file.Path, startTimeUnix)
if b {
r = b
}
2022-06-04 13:20:33 +08:00
}
}
2022-05-22 16:42:57 +08:00
}
2022-06-23 16:40:10 +08:00
return r
2022-05-22 16:42:57 +08:00
}
2022-06-14 21:05:40 +08:00
func (t *SyncTask) skipLocalFile(file *LocalFileItem) bool {
// 插件回调
pluginParam := &plugins.SyncScanLocalFilePrepareParams{
LocalFilePath: file.Path,
LocalFileName: file.FileName,
LocalFileSize: file.FileSize,
LocalFileType: file.FileType,
LocalFileUpdatedAt: file.UpdatedAt,
DriveId: t.DriveId,
}
t.pluginMutex.Lock()
defer t.pluginMutex.Unlock()
2022-06-14 21:05:40 +08:00
if result, er := t.plugin.SyncScanLocalFilePrepareCallback(plugins.GetContext(t.panUser), pluginParam); er == nil && result != nil {
if strings.Compare("no", result.SyncScanLocalApproved) == 0 {
// skip this file
return true
}
}
return false
}
2022-05-22 16:42:57 +08:00
// scanLocalFile 本地文件循环扫描进程
func (t *SyncTask) scanLocalFile(ctx context.Context) {
type folderItem struct {
fileInfo os.FileInfo
path string
}
// init the root folders info
pathParts := strings.Split(strings.ReplaceAll(t.LocalFolderPath, "\\", "/"), "/")
fullPath := ""
for _, p := range pathParts {
if p == "" {
continue
}
if strings.Contains(p, ":") {
// windows volume label, e.g: C:/ D:/
fullPath += p
continue
}
fullPath += "/" + p
fi, err := os.Stat(fullPath)
if err != nil {
// may be permission deny
continue
}
t.localFileDb.Add(newLocalFileItem(fi, fullPath))
}
folderQueue := collection.NewFifoQueue()
rootFolder, err := os.Stat(t.LocalFolderPath)
if err != nil {
return
}
2022-06-04 13:20:33 +08:00
folderQueue.Push(&folderItem{
2022-05-22 16:42:57 +08:00
fileInfo: rootFolder,
path: t.LocalFolderPath,
})
2022-06-04 13:20:33 +08:00
startTimeOfThisLoop := time.Now().Unix()
delayTimeCount := int64(0)
2022-06-23 16:40:10 +08:00
isLocalFolderModify := false
2022-06-04 13:20:33 +08:00
2022-05-22 16:42:57 +08:00
t.wg.AddDelta()
defer t.wg.Done()
for {
select {
case <-ctx.Done():
// cancel routine & done
logger.Verboseln("local file routine done")
return
default:
// 采用广度优先遍历(BFS)进行文件遍历
2022-06-04 13:20:33 +08:00
if delayTimeCount > 0 {
time.Sleep(1 * time.Second)
delayTimeCount -= 1
continue
} else if delayTimeCount == 0 {
delayTimeCount -= 1
startTimeOfThisLoop = time.Now().Unix()
logger.Verboseln("do scan local file process at ", utils.NowTimeStr())
}
2022-05-22 16:42:57 +08:00
obj := folderQueue.Pop()
if obj == nil {
2022-06-09 14:52:49 +08:00
// label discard file from DB
2022-06-23 16:40:10 +08:00
if t.discardLocalFileDb(t.LocalFolderPath, startTimeOfThisLoop) {
logger.Verboseln("notify local folder modify, need to do file action task")
t.fileActionTaskManager.AddLocalFolderModifyCount()
t.fileActionTaskManager.AddPanFolderModifyCount()
isLocalFolderModify = false // 重置标记
2022-06-23 16:40:10 +08:00
}
2022-06-04 13:20:33 +08:00
// restart scan loop over again
folderQueue.Push(&folderItem{
fileInfo: rootFolder,
path: t.LocalFolderPath,
})
2022-06-12 17:48:14 +08:00
delayTimeCount = TimeSecondsOf30Seconds
2022-06-23 16:40:10 +08:00
if isLocalFolderModify {
logger.Verboseln("notify local folder modify, need to do file action task")
t.fileActionTaskManager.AddLocalFolderModifyCount()
isLocalFolderModify = false // 重置标记
2022-06-23 16:40:10 +08:00
}
2022-06-04 13:20:33 +08:00
continue
2022-05-22 16:42:57 +08:00
}
2022-06-04 13:20:33 +08:00
item := obj.(*folderItem)
files, err1 := ioutil.ReadDir(item.path)
if err1 != nil {
2022-05-22 16:42:57 +08:00
continue
}
if len(files) == 0 {
continue
}
localFileAppendList := LocalFileList{}
for _, file := range files {
2022-06-01 21:55:03 +08:00
if strings.HasSuffix(file.Name(), DownloadingFileSuffix) {
// 下载中文件,跳过
continue
}
2022-05-22 16:42:57 +08:00
localFile := newLocalFileItem(file, item.path+"/"+file.Name())
2022-06-14 21:05:40 +08:00
if t.skipLocalFile(localFile) {
logger.Verboseln("插件禁止扫描本地文件: ", localFile.Path)
continue
}
2022-05-22 16:42:57 +08:00
localFileInDb, _ := t.localFileDb.Get(localFile.Path)
if localFileInDb == nil {
// append
2022-06-04 13:20:33 +08:00
localFile.ScanTimeAt = utils.NowTimeStr()
2022-05-22 16:42:57 +08:00
localFileAppendList = append(localFileAppendList, localFile)
2022-06-12 17:44:16 +08:00
logger.Verboseln("add local file to db: ", utils.ObjectToJsonStr(localFile, false))
2022-06-23 16:40:10 +08:00
isLocalFolderModify = true
2022-05-22 16:42:57 +08:00
} else {
// update newest info into DB
2022-06-23 16:40:10 +08:00
if localFile.UpdateTimeUnix() > localFileInDb.UpdateTimeUnix() || localFile.FileSize != localFileInDb.FileSize {
2022-06-01 21:55:03 +08:00
localFileInDb.Sha1Hash = ""
2022-06-23 16:40:10 +08:00
isLocalFolderModify = true
2022-06-01 21:55:03 +08:00
}
2022-06-23 16:40:10 +08:00
2022-05-22 16:42:57 +08:00
localFileInDb.UpdatedAt = localFile.UpdatedAt
localFileInDb.CreatedAt = localFile.CreatedAt
localFileInDb.FileSize = localFile.FileSize
localFileInDb.FileType = localFile.FileType
2022-06-04 13:20:33 +08:00
localFileInDb.ScanTimeAt = utils.NowTimeStr()
2022-06-09 14:52:49 +08:00
localFileInDb.ScanStatus = ScanStatusNormal
2022-06-12 17:44:16 +08:00
logger.Verboseln("update local file to db: ", utils.ObjectToJsonStr(localFileInDb, false))
2022-06-04 13:20:33 +08:00
if _, er := t.localFileDb.Update(localFileInDb); er != nil {
logger.Verboseln("local db update error ", er)
}
2022-05-22 16:42:57 +08:00
}
// for next term scan
if file.IsDir() {
2022-06-04 13:20:33 +08:00
folderQueue.Push(&folderItem{
2022-05-22 16:42:57 +08:00
fileInfo: file,
path: item.path + "/" + file.Name(),
})
}
}
if len(localFileAppendList) > 0 {
//fmt.Println(utils.ObjectToJsonStr(localFileAppendList))
if _, er := t.localFileDb.AddFileList(localFileAppendList); er != nil {
logger.Verboseln("add files to local file db error {}", er)
}
}
time.Sleep(500 * time.Millisecond)
}
}
}
2022-06-09 14:52:49 +08:00
// discardPanFileDb 清理云盘数据库中无效的数据项
2022-06-23 16:40:10 +08:00
func (t *SyncTask) discardPanFileDb(filePath string, startTimeUnix int64) bool {
2022-06-04 13:20:33 +08:00
files, e := t.panFileDb.GetFileList(filePath)
2022-06-23 16:40:10 +08:00
r := false
2022-06-04 13:20:33 +08:00
if e != nil {
2022-06-23 16:40:10 +08:00
return r
2022-06-04 13:20:33 +08:00
}
for _, file := range files {
if file.ScanTimeUnix() < startTimeUnix {
2022-06-23 16:40:10 +08:00
if t.Mode == UploadOnly {
// delete discard pan file info directly
t.panFileDb.Delete(file.Path)
logger.Verboseln("delete discard pan file from DB: ", utils.ObjectToJsonStr(file, false))
} else {
// label file discard
file.ScanStatus = ScanStatusDiscard
t.panFileDb.Update(file)
logger.Verboseln("label pan file discard: ", utils.ObjectToJsonStr(file, false))
}
r = true
2022-06-04 13:20:33 +08:00
} else {
if file.IsFolder() {
2022-06-23 16:40:10 +08:00
b := t.discardPanFileDb(file.Path, startTimeUnix)
if b {
r = b
}
2022-06-04 13:20:33 +08:00
}
}
}
2022-06-23 16:40:10 +08:00
return r
2022-06-04 13:20:33 +08:00
}
2022-06-14 21:05:40 +08:00
func (t *SyncTask) skipPanFile(file *PanFileItem) bool {
// 插件回调
pluginParam := &plugins.SyncScanPanFilePrepareParams{
DriveId: file.DriveId,
DriveFileName: file.FileName,
DriveFilePath: file.Path,
DriveFileSha1: file.Sha1Hash,
DriveFileSize: file.FileSize,
DriveFileType: file.FileType,
DriveFileUpdatedAt: file.UpdatedAt,
}
t.pluginMutex.Lock()
defer t.pluginMutex.Unlock()
2022-06-14 21:05:40 +08:00
if result, er := t.plugin.SyncScanPanFilePrepareCallback(plugins.GetContext(t.panUser), pluginParam); er == nil && result != nil {
if strings.Compare("no", result.SyncScanPanApproved) == 0 {
// skip this file
return true
}
}
return false
}
2022-05-22 16:42:57 +08:00
// scanPanFile 云盘文件循环扫描进程
func (t *SyncTask) scanPanFile(ctx context.Context) {
2022-05-22 17:47:48 +08:00
// init the root folders info
pathParts := strings.Split(strings.ReplaceAll(t.PanFolderPath, "\\", "/"), "/")
fullPath := ""
for _, p := range pathParts {
if p == "" {
continue
}
fullPath += "/" + p
}
2022-06-12 17:03:05 +08:00
fi, err := t.panClient.FileInfoByPath(t.DriveId, fullPath)
2022-05-22 17:47:48 +08:00
if err != nil {
return
}
2022-06-12 17:03:05 +08:00
pFile := NewPanFileItem(fi)
pFile.ScanTimeAt = utils.NowTimeStr()
t.panFileDb.Add(pFile)
time.Sleep(200 * time.Millisecond)
folderQueue := collection.NewFifoQueue()
rootPanFile := fi
2022-05-22 17:47:48 +08:00
folderQueue.Push(rootPanFile)
2022-06-04 13:20:33 +08:00
startTimeOfThisLoop := time.Now().Unix()
delayTimeCount := int64(0)
2022-06-23 16:40:10 +08:00
isPanFolderModify := false
2022-05-22 17:47:48 +08:00
2022-05-22 16:42:57 +08:00
t.wg.AddDelta()
defer t.wg.Done()
for {
select {
case <-ctx.Done():
// cancel routine & done
logger.Verboseln("pan file routine done")
return
default:
// 采用广度优先遍历(BFS)进行文件遍历
2022-06-04 13:20:33 +08:00
if delayTimeCount > 0 {
time.Sleep(1 * time.Second)
delayTimeCount -= 1
continue
} else if delayTimeCount == 0 {
delayTimeCount -= 1
startTimeOfThisLoop = time.Now().Unix()
logger.Verboseln("do scan pan file process at ", utils.NowTimeStr())
}
2022-05-22 17:47:48 +08:00
obj := folderQueue.Pop()
if obj == nil {
2022-06-09 14:52:49 +08:00
// label discard file from DB
2022-06-23 16:40:10 +08:00
if t.discardPanFileDb(t.PanFolderPath, startTimeOfThisLoop) {
logger.Verboseln("notify pan folder modify, need to do file action task")
t.fileActionTaskManager.AddPanFolderModifyCount()
t.fileActionTaskManager.AddLocalFolderModifyCount()
isPanFolderModify = false
}
2022-06-04 13:20:33 +08:00
// restart scan loop over again
folderQueue.Push(rootPanFile)
2022-06-18 08:39:18 +08:00
delayTimeCount = TimeSecondsOf2Minute
2022-06-23 16:40:10 +08:00
if isPanFolderModify {
logger.Verboseln("notify pan folder modify, need to do file action task")
t.fileActionTaskManager.AddPanFolderModifyCount()
isPanFolderModify = false
}
2022-06-04 13:20:33 +08:00
continue
2022-05-22 17:47:48 +08:00
}
item := obj.(*aliyunpan.FileEntity)
files, err1 := t.panClient.FileListGetAll(&aliyunpan.FileListParam{
2022-05-22 17:47:48 +08:00
DriveId: t.DriveId,
ParentFileId: item.FileId,
2022-07-02 16:24:11 +08:00
}, 1500) // 延迟时间避免触发风控
if err1 != nil {
2022-05-22 17:47:48 +08:00
// retry next term
folderQueue.Push(item)
time.Sleep(10 * time.Second)
continue
}
panFileList := PanFileList{}
for _, file := range files {
file.Path = path.Join(item.Path, file.FileName)
2022-06-14 21:05:40 +08:00
panFile := NewPanFileItem(file)
if t.skipPanFile(panFile) {
logger.Verboseln("插件禁止扫描云盘文件: ", panFile.Path)
continue
}
2022-05-22 17:47:48 +08:00
panFileInDb, _ := t.panFileDb.Get(file.Path)
if panFileInDb == nil {
// append
2022-06-14 21:05:40 +08:00
panFile.ScanTimeAt = utils.NowTimeStr()
panFileList = append(panFileList, panFile)
logger.Verboseln("add pan file to db: ", utils.ObjectToJsonStr(panFile, false))
2022-06-23 16:40:10 +08:00
isPanFolderModify = true
2022-05-22 17:47:48 +08:00
} else {
// update newest info into DB
2022-06-23 16:40:10 +08:00
if strings.ToLower(file.ContentHash) != strings.ToLower(panFileInDb.Sha1Hash) {
isPanFolderModify = true
panFileInDb.DomainId = file.DomainId
panFileInDb.FileId = file.FileId
panFileInDb.FileType = file.FileType
panFileInDb.Category = file.Category
panFileInDb.Crc64Hash = file.Crc64Hash
panFileInDb.Sha1Hash = file.ContentHash
panFileInDb.FileSize = file.FileSize
panFileInDb.UpdatedAt = file.UpdatedAt
panFileInDb.CreatedAt = file.CreatedAt
}
// update scan time
2022-06-04 13:20:33 +08:00
panFileInDb.ScanTimeAt = utils.NowTimeStr()
2022-06-09 14:52:49 +08:00
panFileInDb.ScanStatus = ScanStatusNormal
2022-06-12 17:44:16 +08:00
logger.Verboseln("update pan file to db: ", utils.ObjectToJsonStr(panFileInDb, false))
2022-05-22 17:47:48 +08:00
t.panFileDb.Update(panFileInDb)
}
if file.IsFolder() {
folderQueue.Push(file)
}
}
if len(panFileList) > 0 {
if _, er := t.panFileDb.AddFileList(panFileList); er != nil {
logger.Verboseln("add files to pan file db error {}", er)
}
}
2022-06-18 08:39:18 +08:00
time.Sleep(5 * time.Second) // 延迟避免触发风控
2022-05-22 16:42:57 +08:00
}
}
}