From 36d2d2fbf4d3dc4baced5c02017ffae1c93e39e1 Mon Sep 17 00:00:00 2001 From: ShukeBta <272197458+ShukeBta@users.noreply.github.com> Date: Sat, 27 Jun 2026 09:42:52 +0800 Subject: [PATCH] split organize pipeline helpers --- internal/service/organize_pipeline.go | 160 -------------------- internal/service/organize_pipeline_scan.go | 78 ++++++++++ internal/service/organize_pipeline_tasks.go | 94 ++++++++++++ 3 files changed, 172 insertions(+), 160 deletions(-) create mode 100644 internal/service/organize_pipeline_scan.go create mode 100644 internal/service/organize_pipeline_tasks.go diff --git a/internal/service/organize_pipeline.go b/internal/service/organize_pipeline.go index 42f4962..ef85884 100644 --- a/internal/service/organize_pipeline.go +++ b/internal/service/organize_pipeline.go @@ -205,169 +205,9 @@ func (p *OrganizePipelineService) shouldScan(req OrganizePipelineRequest, res *O return OrganizeResultNeedsVisibilitySync(res) } -func organizeScanRoot(res *OrganizeResult, path string) string { - if res == nil { - if strings.TrimSpace(path) == "" { - return "" - } - return filepath.Dir(path) - } - var root string - for _, item := range res.Items { - if !organizeItemNeedsVisibilitySync(item) { - continue - } - target := strings.TrimSpace(item.Target) - if target == "" { - continue - } - dir := filepath.Dir(target) - if root == "" { - root = dir - continue - } - root = commonPathRoot(root, dir) - } - if root != "" { - return root - } - if strings.TrimSpace(path) != "" { - return filepath.Dir(path) - } - return strings.TrimSpace(res.DestPath) -} - -func organizeItemNeedsVisibilitySync(item OrganizePreviewItem) bool { - switch item.Action { - case "organize", "replace", "reclassify", "cleanup": - return true - case "skip": - switch item.Reason { - case organizeSkipAlreadyOrganized, organizeSkipTargetExists, "duplicate exists", "target exists": - return true - } - } - return false -} - -func commonPathRoot(a, b string) string { - a = filepath.Clean(strings.TrimSpace(a)) - b = filepath.Clean(strings.TrimSpace(b)) - if a == "" || a == "." { - return b - } - if b == "" || b == "." { - return a - } - if pathWithin(a, b) { - return b - } - if pathWithin(b, a) { - return a - } - for { - parent := filepath.Dir(a) - if parent == a || parent == "." { - return parent - } - if pathWithin(b, parent) { - return parent - } - a = parent - } -} - func (p *OrganizePipelineService) scrapeAfter(ctx context.Context, req OrganizePipelineRequest) bool { if req.ScrapeAfter != nil { return *req.ScrapeAfter } return OrganizeScrapeAfterEnabled(ctx, p.repo) } - -func (p *OrganizePipelineService) startTask(ctx context.Context, req OrganizePipelineRequest, opts OrganizeOptions) *TaskHandle { - if p == nil || p.tasks == nil { - return nil - } - name := strings.TrimSpace(req.TaskName) - if name == "" { - name = p.defaultTaskName(req) - } - message := "正在整理/重命名/入库" - if req.DryRun { - message = "正在预览整理/重命名" - } - return p.tasks.Start(TaskKindOrganize, name, TaskUpdate{ - Stage: "organize", - SourcePath: firstNonEmpty(opts.SourcePath, p.defaultSourcePath(ctx, req)), - DestPath: firstNonEmpty(opts.DestPath, p.defaultDestPath(ctx, req)), - Message: message, - }) -} - -func (p *OrganizePipelineService) finishTask(task *TaskHandle, err error, stage, message string, res *OrganizeResult) { - if task == nil { - return - } - task.Finish(err, TaskUpdate{ - Stage: stage, - Message: message, - Metrics: OrganizeTaskMetrics(res), - Details: OrganizeTaskDetails(res, 8), - }) -} - -func (p *OrganizePipelineService) defaultTaskName(req OrganizePipelineRequest) string { - switch req.Trigger { - case OrganizeTriggerScheduled: - return "自动整理重命名刮削入库" - case OrganizeTriggerDownload: - return "下载完成自动整理重命名刮削入库" - default: - if req.DryRun { - return "预览整理重命名入库" - } - return "手动整理重命名刮削入库" - } -} - -func (p *OrganizePipelineService) failureMessage(req OrganizePipelineRequest) string { - switch req.Trigger { - case OrganizeTriggerScheduled: - return "自动整理重命名入库失败" - case OrganizeTriggerDownload: - return "下载完成自动整理失败" - default: - return "手动整理重命名入库失败" - } -} - -func (p *OrganizePipelineService) completedMessage(req OrganizePipelineRequest) string { - switch req.Trigger { - case OrganizeTriggerScheduled: - return "自动整理重命名刮削入库结束" - case OrganizeTriggerDownload: - return "下载完成自动整理入库结束" - default: - return "手动整理重命名刮削入库结束" - } -} - -func (p *OrganizePipelineService) defaultSourcePath(ctx context.Context, req OrganizePipelineRequest) string { - if p == nil || p.organizer == nil { - return "" - } - if req.Scope == OrganizeScopeDirectory { - return p.organizer.defaultSourceRoot(ctx, "") - } - return "" -} - -func (p *OrganizePipelineService) defaultDestPath(ctx context.Context, req OrganizePipelineRequest) string { - if p == nil || p.organizer == nil { - return "" - } - if req.Scope == OrganizeScopeDirectory { - return p.organizer.defaultDestRoot(ctx, "") - } - return "" -} diff --git a/internal/service/organize_pipeline_scan.go b/internal/service/organize_pipeline_scan.go new file mode 100644 index 0000000..7d73c83 --- /dev/null +++ b/internal/service/organize_pipeline_scan.go @@ -0,0 +1,78 @@ +package service + +import ( + "path/filepath" + "strings" +) + +func organizeScanRoot(res *OrganizeResult, path string) string { + if res == nil { + if strings.TrimSpace(path) == "" { + return "" + } + return filepath.Dir(path) + } + var root string + for _, item := range res.Items { + if !organizeItemNeedsVisibilitySync(item) { + continue + } + target := strings.TrimSpace(item.Target) + if target == "" { + continue + } + dir := filepath.Dir(target) + if root == "" { + root = dir + continue + } + root = commonPathRoot(root, dir) + } + if root != "" { + return root + } + if strings.TrimSpace(path) != "" { + return filepath.Dir(path) + } + return strings.TrimSpace(res.DestPath) +} + +func organizeItemNeedsVisibilitySync(item OrganizePreviewItem) bool { + switch item.Action { + case "organize", "replace", "reclassify", "cleanup": + return true + case "skip": + switch item.Reason { + case organizeSkipAlreadyOrganized, organizeSkipTargetExists, "duplicate exists", "target exists": + return true + } + } + return false +} + +func commonPathRoot(a, b string) string { + a = filepath.Clean(strings.TrimSpace(a)) + b = filepath.Clean(strings.TrimSpace(b)) + if a == "" || a == "." { + return b + } + if b == "" || b == "." { + return a + } + if pathWithin(a, b) { + return b + } + if pathWithin(b, a) { + return a + } + for { + parent := filepath.Dir(a) + if parent == a || parent == "." { + return parent + } + if pathWithin(b, parent) { + return parent + } + a = parent + } +} diff --git a/internal/service/organize_pipeline_tasks.go b/internal/service/organize_pipeline_tasks.go new file mode 100644 index 0000000..4cf600b --- /dev/null +++ b/internal/service/organize_pipeline_tasks.go @@ -0,0 +1,94 @@ +package service + +import ( + "context" + "strings" +) + +func (p *OrganizePipelineService) startTask(ctx context.Context, req OrganizePipelineRequest, opts OrganizeOptions) *TaskHandle { + if p == nil || p.tasks == nil { + return nil + } + name := strings.TrimSpace(req.TaskName) + if name == "" { + name = p.defaultTaskName(req) + } + message := "正在整理/重命名/入库" + if req.DryRun { + message = "正在预览整理/重命名" + } + return p.tasks.Start(TaskKindOrganize, name, TaskUpdate{ + Stage: "organize", + SourcePath: firstNonEmpty(opts.SourcePath, p.defaultSourcePath(ctx, req)), + DestPath: firstNonEmpty(opts.DestPath, p.defaultDestPath(ctx, req)), + Message: message, + }) +} + +func (p *OrganizePipelineService) finishTask(task *TaskHandle, err error, stage, message string, res *OrganizeResult) { + if task == nil { + return + } + task.Finish(err, TaskUpdate{ + Stage: stage, + Message: message, + Metrics: OrganizeTaskMetrics(res), + Details: OrganizeTaskDetails(res, 8), + }) +} + +func (p *OrganizePipelineService) defaultTaskName(req OrganizePipelineRequest) string { + switch req.Trigger { + case OrganizeTriggerScheduled: + return "自动整理重命名刮削入库" + case OrganizeTriggerDownload: + return "下载完成自动整理重命名刮削入库" + default: + if req.DryRun { + return "预览整理重命名入库" + } + return "手动整理重命名刮削入库" + } +} + +func (p *OrganizePipelineService) failureMessage(req OrganizePipelineRequest) string { + switch req.Trigger { + case OrganizeTriggerScheduled: + return "自动整理重命名入库失败" + case OrganizeTriggerDownload: + return "下载完成自动整理失败" + default: + return "手动整理重命名入库失败" + } +} + +func (p *OrganizePipelineService) completedMessage(req OrganizePipelineRequest) string { + switch req.Trigger { + case OrganizeTriggerScheduled: + return "自动整理重命名刮削入库结束" + case OrganizeTriggerDownload: + return "下载完成自动整理入库结束" + default: + return "手动整理重命名刮削入库结束" + } +} + +func (p *OrganizePipelineService) defaultSourcePath(ctx context.Context, req OrganizePipelineRequest) string { + if p == nil || p.organizer == nil { + return "" + } + if req.Scope == OrganizeScopeDirectory { + return p.organizer.defaultSourceRoot(ctx, "") + } + return "" +} + +func (p *OrganizePipelineService) defaultDestPath(ctx context.Context, req OrganizePipelineRequest) string { + if p == nil || p.organizer == nil { + return "" + } + if req.Scope == OrganizeScopeDirectory { + return p.organizer.defaultDestRoot(ctx, "") + } + return "" +}