JJ_MKVMaker/lib/app/settings/copy_settings.dart

103 lines
5.0 KiB
Dart

import 'records.dart';
import 'settings_group.dart';
/// 약속 (설정 A): 환경 설정 > 복사 · 이동 (파일 탐색기) · rsync · 실시간 동기화 (Rsync 화면) - 자기 키 (이름 · 처음 값 · 읽기 · 쓰기) 를 스스로 갖는다.
/// 설정 하나를 더할 때는 이 파일만 고친다. 저장 파일의 키 이름은 예전 그대로 (평평한 키)
class CopySettings implements SettingsGroup {
/// 파일 탐색기의 복사 · 이동 방법: 'builtin' 현재 방식 (기본) · 'robocopy' (Windows). 파일만 고를 때 / 폴더가 들어 있을 때.
/// rsync 는 Rsync 화면에서 따로 (파일 탐색기에서는 쓰지 않음)
String methodFile = 'builtin';
/// 48: 복사 · 이동할 때 받는 폴더에 같은 이름이 있으면 'ask' (확인 창에서 고름, 처음 값) · 'rename' · 'overwrite' · 'skip'
String conflict = 'ask';
/// 229: 앱이 직접 하는 복사 · 이동 (현재 방식 · WebDAV 의 안의 것 맞추기) 에서 받는 쪽이 더 새것이면 건너뛴다 (rsync -u 와 같음).
/// 처음 값 켜짐 - 예전 원본으로 새 파일을 덮어쓰고 (이동이면 원본까지 지워) 새 내용을 잃었다 (관리자 판단)
bool skipNewer = true;
String methodFolder = 'builtin';
String rsyncOptions = '-avPog';
String robocopyOptions = '/E /COPY:DAT /DCOPY:T /R:2 /W:2';
/// 여러 개를 고르면: 'each' 항목마다 따로 실행 (기본) · 'once' 한 번에 (rsync)
String runMode = 'each';
/// 속도 제한 KB/s (0 = 제한 없음). 모든 방법에 (rsync --bwlimit, 현재 방식은 앱이 조절, robocopy 는 /IPG 로 비슷하게)
int bandwidthKBps = 0;
/// rsync 가져오기: 'download' 앱에 들어 있는 것 (기본, Windows 는 없으면 내려받기) · 'custom' 직접 지정한 실행 파일 ([rsyncPath])
String rsyncSource = 'download';
String rsyncPath = '';
/// 실시간 동기화 (lsyncd 처럼)
List<LiveSyncPair> liveSyncPairs = [];
/// 모니터링 (Rsync 화면 가운데 [모니터링]): 실행한 rsync 를 기억해 다시 실행 · 옵션 고치기 · lsync 로 옮기기
List<CopyTask> tasks = [];
/// Rsync 화면에서 마지막으로 연 폴더 (왼쪽 · 오른쪽)
List<String> rsyncPaths = [];
/// 92 (Windows): 실시간 동기화가 멈췄을 때 Windows 알림
bool syncStopToast = true;
/// 실시간 동기화 확인 간격 (초). Windows 는 바뀌면 바로, 그 밖은 이 간격으로 살핀다.
int liveSyncIntervalSec = 30;
/// 앱을 다시 켤 때 실시간 동기화: 'auto' 바로 시작 / 'ask' 골라서 시작 / 'off' 시작 안 함 (모니터링에서 시작)
String liveSyncOnStart = 'auto';
/// 파일 탐색기의 복사 방법 (rsync 는 Rsync 화면으로 옮겨 예전 값 rsync 도 현재 방식으로)
static String _method(Object? v) => v == 'robocopy' ? 'robocopy' : 'builtin';
@override
void write(Map<String, Object?> j, {required bool plainSecrets}) {
j['copyMethodFile'] = methodFile;
j['copyConflict'] = conflict;
j['copySkipNewer'] = skipNewer;
j['copyMethodFolder'] = methodFolder;
j['rsyncOptions'] = rsyncOptions;
j['robocopyOptions'] = robocopyOptions;
j['copyRunMode'] = runMode;
j['copyBandwidthKBps'] = bandwidthKBps;
j['rsyncSource'] = rsyncSource;
j['rsyncPath'] = rsyncPath;
j['liveSyncPairs'] = [for (final x in liveSyncPairs) x.toJson()];
j['liveSyncIntervalSec'] = liveSyncIntervalSec;
j['liveSyncOnStart'] = liveSyncOnStart;
j['copyTasks'] = [for (final x in tasks) x.toJson()];
j['rsyncPaths'] = rsyncPaths;
j['syncStopToast'] = syncStopToast;
}
@override
void read(Map<String, dynamic> j) {
methodFile = _method(j['copyMethodFile']);
conflict = const ['rename', 'overwrite', 'skip'].contains(j['copyConflict']) ? j['copyConflict'] as String : 'ask';
skipNewer = j['copySkipNewer'] != false;
methodFolder = _method(j['copyMethodFolder']);
rsyncPaths = [for (final x in (j['rsyncPaths'] as List?) ?? const []) '$x'];
syncStopToast = j['syncStopToast'] != false;
rsyncOptions = j['rsyncOptions'] as String? ?? '-avPog';
robocopyOptions = j['robocopyOptions'] as String? ?? '/E /COPY:DAT /DCOPY:T /R:2 /W:2';
runMode = j['copyRunMode'] == 'once' ? 'once' : 'each';
bandwidthKBps = ((j['copyBandwidthKBps'] as num?)?.toInt() ?? 0).clamp(0, 10000000);
rsyncSource = j['rsyncSource'] == 'custom' ? 'custom' : 'download';
rsyncPath = j['rsyncPath'] as String? ?? '';
liveSyncPairs = [
for (final x in (j['liveSyncPairs'] as List?) ?? const [])
if (x is Map && x['source'] is String && x['target'] is String) LiveSyncPair.fromJson(x),
];
liveSyncIntervalSec = ((j['liveSyncIntervalSec'] as num?)?.toInt() ?? 30).clamp(5, 3600);
liveSyncOnStart = const ['auto', 'ask', 'off'].contains(j['liveSyncOnStart']) ? j['liveSyncOnStart'] as String : 'auto';
tasks = [
for (final x in (j['copyTasks'] as List?) ?? const [])
if (x is Map && x['dest'] is String) CopyTask.fromJson(x),
];
}
}