From 2512fc5b5781be44b7584ca1898796992009a417 Mon Sep 17 00:00:00 2001 From: ElonH Date: Mon, 1 Jun 2020 18:35:00 +0800 Subject: [PATCH] feat(sync-copy-flow): enable copy directory now sync/copy: Copy files from source to dest, skipping already copied --- src/app/@dataflow/rclone/index.ts | 1 + src/app/@dataflow/rclone/sync-copy-flow.ts | 31 ++++++++++++++++++ src/app/pages/manager/tasks/tasks.service.ts | 34 ++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/app/@dataflow/rclone/sync-copy-flow.ts diff --git a/src/app/@dataflow/rclone/index.ts b/src/app/@dataflow/rclone/index.ts index 943fa37..b58bcbc 100644 --- a/src/app/@dataflow/rclone/index.ts +++ b/src/app/@dataflow/rclone/index.ts @@ -11,3 +11,4 @@ export * from './async-post-flow'; export * from './operations-copyfile-flow'; export * from './operations-movefile-flow'; export * from './operations-deletefile-flow'; +export * from './sync-copy-flow'; diff --git a/src/app/@dataflow/rclone/sync-copy-flow.ts b/src/app/@dataflow/rclone/sync-copy-flow.ts new file mode 100644 index 0000000..3386c57 --- /dev/null +++ b/src/app/@dataflow/rclone/sync-copy-flow.ts @@ -0,0 +1,31 @@ +import { IRcloneServer } from '../extra'; +import { CombErr } from '../core'; +import { AsyncPostFlow, AsyncPostFlowParamsNode } from './async-post-flow'; + +export interface SyncCopyFlowParamsNode extends AsyncPostFlowParamsNode { + /** a remote name string eg "drive:src" for the source */ + srcFs: string; + /** a remote name string eg "drive:dst" for the destination */ + dstFs: string; +} +export interface SyncCopyFlowInNode + extends SyncCopyFlowParamsNode, + IRcloneServer {} + +export abstract class SyncCopyFlow extends AsyncPostFlow< + SyncCopyFlowInNode, + SyncCopyFlowParamsNode +> { + // public prerequest$: Observable>; + protected cmd: string = 'sync/copy'; + protected params = ( + pre: CombErr + ): SyncCopyFlowParamsNode => { + if (pre[1].length !== 0) return {} as any; + return { + srcFs: pre[0].srcFs, + dstFs: pre[0].dstFs, + }; + }; + protected cacheSupport: boolean = false; +} diff --git a/src/app/pages/manager/tasks/tasks.service.ts b/src/app/pages/manager/tasks/tasks.service.ts index 3dac3d8..27b954b 100644 --- a/src/app/pages/manager/tasks/tasks.service.ts +++ b/src/app/pages/manager/tasks/tasks.service.ts @@ -7,6 +7,8 @@ import { OperationsMovefileFlowInNode, OperationsDeletefileFlowInNode, OperationsDeletefileFlow, + SyncCopyFlow, + SyncCopyFlowInNode, } from 'src/app/@dataflow/rclone'; import { ClipboardService, @@ -185,6 +187,37 @@ export class TaskService { }); } + private syncCopy$: SyncCopyFlow; + private deploySyncCopy() { + const outer = this; + const taskReal$ = outer.post$.pipe(filter((x) => x.oper === 'copy' && x.srcItem.IsDir)); + this.syncCopy$ = new (class extends SyncCopyFlow { + public prerequest$ = taskReal$.pipe( + withLatestFrom(outer.connectService.listCmd$.verify(this.cmd)), + map( + ([item, cmdNode]): CombErr => { + if (cmdNode[1].length !== 0) return [{}, cmdNode[1]] as any; + return [ + { + ...cmdNode[0], + srcFs: `${item.srcRemote}:${item.srcItem.Path}`, + dstFs: `${item.dst.remote}:${[item.dst.path, item.srcItem.Name].join('/')}`, + }, + [], + ]; + } + ) + ); + })(); + this.syncCopy$.deploy(); + this.syncCopy$ + .getOutput() + .pipe(zip(taskReal$)) + .subscribe((x) => { + this.postAfter(...x); + }); + } + private detailTrigger = new Subject(); public detail$: TasksPoolFlow; private deployDetail() { @@ -223,6 +256,7 @@ export class TaskService { this.deployCopyFile(); this.deployMoveFile(); this.deployDeleteFile(); + this.deploySyncCopy(); this.deployDetail(); } }