Skip to content

Commit

Permalink
new: webdav sync
Browse files Browse the repository at this point in the history
  • Loading branch information
lollipopkit committed Dec 4, 2023
1 parent 3524d92 commit 2dc86a9
Show file tree
Hide file tree
Showing 9 changed files with 385 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/sync.dart';
import 'package:toolbox/data/res/logger.dart';

import '../../data/model/app/error.dart';
import '../../data/res/path.dart';
import '../../../data/model/app/error.dart';
import '../../../data/res/path.dart';

abstract final class ICloud {
static const _containerId = 'iCloud.tech.lolli.serverbox';
Expand Down
96 changes: 96 additions & 0 deletions lib/core/utils/sync/webdav.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/error.dart';
import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/res/store.dart';
// ignore: implementation_imports
import 'package:webdav_client/src/client.dart';

abstract final class Webdav {
static var _client = WebdavClient(
url: Stores.setting.webdavUrl.fetch(),
user: Stores.setting.webdavUser.fetch(),
pwd: Stores.setting.webdavPwd.fetch(),
);

static Future<WebdavErr?> upload({
required String relativePath,
String? localPath,
}) async {
try {
await _client.writeFile(
localPath ?? '${await Paths.doc}/$relativePath',
relativePath,
);
} catch (e, s) {
Loggers.app.warning('Webdav upload failed', e, s);
return WebdavErr(type: WebdavErrType.generic, message: '$e');
}
return null;
}

static Future<WebdavErr?> delete(String relativePath) async {
try {
await _client.remove(relativePath);
} catch (e, s) {
Loggers.app.warning('Webdav delete failed', e, s);
return WebdavErr(type: WebdavErrType.generic, message: '$e');
}
return null;
}

static Future<WebdavErr?> download({
required String relativePath,
String? localPath,
}) async {
try {
await _client.readFile(
relativePath,
localPath ?? '${await Paths.doc}/$relativePath',
);
} catch (e, s) {
Loggers.app.warning('Webdav download failed', e, s);
return WebdavErr(type: WebdavErrType.generic, message: '$e');
}
return null;
}

static void changeClient(String url, String user, String pwd) {
_client = WebdavClient(url: url, user: user, pwd: pwd);
}

static Future<void> sync() async {
try {
final result = await download(relativePath: Paths.bakName);
if (result != null) {
Loggers.app.warning('Download backup failed: $result');
return;
}
} catch (e, s) {
Loggers.app.warning('Download backup failed', e, s);
}
final dlFile = await File(await Paths.bak).readAsString();
final dlBak = await compute(Backup.fromJsonString, dlFile);
final restore = await dlBak.restore();
switch (restore) {
case true:
Loggers.app.info('Restore from iCloud (${dlBak.lastModTime}) success');
break;
case false:
await Backup.backup();
final uploadResult = await upload(relativePath: Paths.bakName);
if (uploadResult != null) {
Loggers.app.warning('Upload iCloud backup failed: $uploadResult');
} else {
Loggers.app.info('Upload iCloud backup success');
}
break;
case null:
Loggers.app.info('Skip iCloud sync');
break;
}
}
}
21 changes: 19 additions & 2 deletions lib/data/model/app/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ enum ErrFrom {
docker,
sftp,
ssh,
status;
status,
icloud,
webdav,;
}

abstract class Err<T> {
Expand Down Expand Up @@ -61,10 +63,25 @@ enum ICloudErrType {

class ICloudErr extends Err<ICloudErrType> {
ICloudErr({required ICloudErrType type, String? message})
: super(from: ErrFrom.docker, type: type, message: message);
: super(from: ErrFrom.icloud, type: type, message: message);

@override
String toString() {
return 'ICloudErr<$type>: $message';
}
}

enum WebdavErrType {
generic,
notFound,;
}

class WebdavErr extends Err<WebdavErrType> {
WebdavErr({required WebdavErrType type, String? message})
: super(from: ErrFrom.webdav, type: type, message: message);

@override
String toString() {
return 'WebdavErr<$type>: $message';
}
}
13 changes: 13 additions & 0 deletions lib/data/model/app/remote_storage.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
abstract class RemoteStorage {
Future<Error> upload({
required String relativePath,
String? localPath
});

Future<Error> download({
required String relativePath,
String? localPath
});

Future<Error> delete(String relativePath);
}
6 changes: 6 additions & 0 deletions lib/data/store/setting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@ class SettingStore extends PersistentStore {
late final serverFuncBtnsDisplayName =
property('serverFuncBtnsDisplayName', false);

/// Webdav sync
late final webdavSync = property('webdavSync', false);
late final webdavUrl = property('webdavUrl', '');
late final webdavUser = property('webdavUser', '');
late final webdavPwd = property('webdavPwd', '');

// Never show these settings for users
//
// ------BEGIN------
Expand Down
2 changes: 1 addition & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:macos_window_utils/window_manipulator.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:toolbox/core/channel/bg_run.dart';
import 'package:toolbox/core/utils/icloud.dart';
import 'package:toolbox/core/utils/sync/icloud.dart';
import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/provider.dart';
Expand Down
Loading

0 comments on commit 2dc86a9

Please sign in to comment.