Improve WebDAV data sync version handling and force sync (#207)

* Fix WebDAV auto sync default setting initialization

* Improve WebDAV data sync version handling and  force sync
This commit is contained in:
buste
2025-02-19 22:43:23 +08:00
committed by GitHub
parent ee0da9a26a
commit a630771f0b
4 changed files with 57 additions and 30 deletions

View File

@@ -189,6 +189,7 @@
"Operation": "操作", "Operation": "操作",
"Upload": "上传", "Upload": "上传",
"Saved": "已保存", "Saved": "已保存",
"Saved Failed": "保存失败",
"Sync Data": "同步数据", "Sync Data": "同步数据",
"Syncing Data": "正在同步数据", "Syncing Data": "正在同步数据",
"Data Sync": "数据同步", "Data Sync": "数据同步",
@@ -549,6 +550,7 @@
"Operation": "操作", "Operation": "操作",
"Upload": "上傳", "Upload": "上傳",
"Saved": "已保存", "Saved": "已保存",
"Saved Failed": "保存失敗",
"Sync Data": "同步數據", "Sync Data": "同步數據",
"Syncing Data": "正在同步數據", "Syncing Data": "正在同步數據",
"Data Sync": "數據同步", "Data Sync": "數據同步",

View File

@@ -56,6 +56,18 @@ void _checkOldConfigs() {
.map((e) => e.key) .map((e) => e.key)
.toList(); .toList();
} }
if (appdata.settings['webdavAutoSync'] == null) {
var webdavConfig = appdata.settings['webdav'];
if (webdavConfig is List &&
webdavConfig.length == 3 &&
webdavConfig.whereType<String>().length == 3) {
appdata.settings['webdavAutoSync'] = true;
} else {
appdata.settings['webdavAutoSync'] = false;
}
appdata.saveData();
}
} }
Future<void> _checkAppUpdates() async { Future<void> _checkAppUpdates() async {

View File

@@ -473,8 +473,8 @@ class _WebdavSettingState extends State<_WebdavSetting> {
isTesting = true; isTesting = true;
}); });
var testResult = upload var testResult = upload
? await DataSync().uploadData() ? await DataSync().uploadData(forceSync: true)
: await DataSync().downloadData(); : await DataSync().downloadData(forceSync: true);
if (testResult.error) { if (testResult.error) {
setState(() { setState(() {
isTesting = false; isTesting = false;
@@ -482,11 +482,12 @@ class _WebdavSettingState extends State<_WebdavSetting> {
appdata.settings['webdav'] = oldConfig; appdata.settings['webdav'] = oldConfig;
appdata.settings['webdavAutoSync'] = oldAutoSync; appdata.settings['webdavAutoSync'] = oldAutoSync;
context.showMessage(message: testResult.errorMessage!); context.showMessage(message: testResult.errorMessage!);
return; context.showMessage(message: "Saved Failed".tl);
} else {
appdata.saveData();
context.showMessage(message: "Saved".tl);
App.rootPop();
} }
appdata.saveData();
context.showMessage(message: "Saved".tl);
App.rootPop();
}, },
child: Text("Continue".tl), child: Text("Continue".tl),
), ),

View File

@@ -58,7 +58,7 @@ class DataSync with ChangeNotifier {
return List.from(config); return List.from(config);
} }
Future<Res<bool>> uploadData() async { Future<Res<bool>> uploadData({bool forceSync = false}) async {
if (isDownloading) return const Res(true); if (isDownloading) return const Res(true);
if (haveWaitingTask) return const Res(true); if (haveWaitingTask) return const Res(true);
while (isUploading) { while (isUploading) {
@@ -102,20 +102,32 @@ class DataSync with ChangeNotifier {
} }
try { try {
appdata.settings['dataVersion']++;
await appdata.saveData(false);
var data = await exportAppData();
var time =
(DateTime.now().millisecondsSinceEpoch ~/ 86400000).toString();
var filename = time;
filename += '-';
filename += appdata.settings['dataVersion'].toString();
filename += '.venera';
var files = await client.readDir('/'); var files = await client.readDir('/');
files = files.where((e) => e.name!.endsWith('.venera')).toList(); files = files.where((e) => e.name!.endsWith('.venera')).toList();
var old = files.firstWhereOrNull((e) => e.name!.startsWith("$time-")); files.sort((a, b) => b.name!.compareTo(a.name!));
if (old != null) { var remoteFile = files.firstWhereOrNull((e) => e.name!.endsWith('.venera'));
await client.remove(old.name!); var remoteVersion = 0;
if (remoteFile != null) {
remoteVersion = int.tryParse(remoteFile.name!.split('-').elementAtOrNull(1)?.split('.').first ?? '0') ?? 0;
}
var localVersion = appdata.settings['dataVersion'] ?? 0;
if (!forceSync && remoteVersion >= localVersion) {
Log.info("Data Sync", 'Local: $localVersion Remote: $remoteVersion Skip upload ForceSync: $forceSync');
return const Res(true);
}
appdata.settings['dataVersion'] = forceSync ? remoteVersion + 1 : localVersion + 1;
await appdata.saveData(false);
var data = await exportAppData();
var time = (DateTime.now().millisecondsSinceEpoch ~/ 86400000).toString();
var filename = '$time-${appdata.settings['dataVersion']}.venera';
if (!forceSync) {
var old = files.firstWhereOrNull((e) => e.name!.startsWith("$time-"));
if (old != null) {
await client.remove(old.name!);
}
} }
if (files.length >= 10) { if (files.length >= 10) {
files.sort((a, b) => a.name!.compareTo(b.name!)); files.sort((a, b) => a.name!.compareTo(b.name!));
@@ -123,7 +135,7 @@ class DataSync with ChangeNotifier {
} }
await client.write(filename, await data.readAsBytes()); await client.write(filename, await data.readAsBytes());
data.deleteIgnoreError(); data.deleteIgnoreError();
Log.info("Upload Data", "Data uploaded successfully"); Log.info("Data Sync", "Local: ${appdata.settings['dataVersion']} Remote: $remoteVersion Data uploaded successfully ForceSync: $forceSync");
return const Res(true); return const Res(true);
} catch (e, s) { } catch (e, s) {
Log.error("Upload Data", e, s); Log.error("Upload Data", e, s);
@@ -135,7 +147,7 @@ class DataSync with ChangeNotifier {
} }
} }
Future<Res<bool>> downloadData() async { Future<Res<bool>> downloadData({bool forceSync = false}) async {
if (haveWaitingTask) return const Res(true); if (haveWaitingTask) return const Res(true);
while (isDownloading || isUploading) { while (isDownloading || isUploading) {
haveWaitingTask = true; haveWaitingTask = true;
@@ -184,16 +196,16 @@ class DataSync with ChangeNotifier {
if (file == null) { if (file == null) {
throw 'No data file found'; throw 'No data file found';
} }
var version = var version = file.name!.split('-').elementAtOrNull(1)?.split('.').first;
file.name!.split('-').elementAtOrNull(1)?.split('.').first; var remoteVersion = int.tryParse(version ?? '') ?? 0;
if (version != null && int.tryParse(version) != null) { var localVersion = appdata.settings['dataVersion'] ?? 0;
var currentVersion = appdata.settings['dataVersion'];
if (currentVersion != null && int.parse(version) <= currentVersion) { if (!forceSync && remoteVersion <= localVersion) {
Log.info("Data Sync", 'No new data to download'); Log.info("Data Sync", 'Local: $localVersion Remote: $remoteVersion Skip download ForceSync: $forceSync');
return const Res(true); return const Res(true);
}
} }
Log.info("Data Sync", "Downloading data from WebDAV server");
Log.info("Data Sync", "Local: $localVersion Remote: $remoteVersion Downloading data ForceSync: $forceSync");
var localFile = File(FilePath.join(App.cachePath, file.name!)); var localFile = File(FilePath.join(App.cachePath, file.name!));
await client.read2File(file.name!, localFile.path); await client.read2File(file.name!, localFile.path);
await importAppData(localFile, true); await importAppData(localFile, true);