selfprivacy.org.app/lib/logic/cubit/backups/backups_cubit.dart

198 lines
6.5 KiB
Dart
Raw Normal View History

2021-12-06 18:31:19 +00:00
import 'dart:async';
import 'package:easy_localization/easy_localization.dart';
2021-12-06 18:31:19 +00:00
import 'package:selfprivacy/config/get_it_config.dart';
2022-07-12 12:54:16 +00:00
import 'package:selfprivacy/logic/api_maps/rest_maps/backblaze.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
2021-12-06 18:31:19 +00:00
import 'package:selfprivacy/logic/cubit/app_config_dependent/authentication_dependend_cubit.dart';
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/json/backup.dart';
2021-12-06 18:31:19 +00:00
part 'backups_state.dart';
class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
2022-06-05 19:36:32 +00:00
BackupsCubit(final ServerInstallationCubit serverInstallationCubit)
2022-05-24 18:55:39 +00:00
: super(
serverInstallationCubit,
const BackupsState(preventActions: true),
);
2021-12-06 18:31:19 +00:00
2022-06-05 19:36:32 +00:00
final ServerApi api = ServerApi();
final BackblazeApi backblaze = BackblazeApi();
2021-12-06 18:31:19 +00:00
2022-05-24 18:55:39 +00:00
@override
2021-12-06 18:31:19 +00:00
Future<void> load() async {
if (serverInstallationCubit.state is ServerInstallationFinished) {
2022-06-05 19:36:32 +00:00
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
2021-12-06 18:31:19 +00:00
if (bucket == null) {
emit(
const BackupsState(
isInitialized: false,
preventActions: false,
refreshing: false,
),
);
2021-12-06 18:31:19 +00:00
} else {
2022-06-05 19:36:32 +00:00
final BackupStatus status = await api.getBackupStatus();
2021-12-06 18:31:19 +00:00
switch (status.status) {
case BackupStatusEnum.noKey:
case BackupStatusEnum.notInitialized:
emit(
BackupsState(
backups: const [],
isInitialized: true,
preventActions: false,
progress: 0,
status: status.status,
refreshing: false,
),
);
2021-12-06 18:31:19 +00:00
break;
case BackupStatusEnum.initializing:
emit(
BackupsState(
backups: const [],
isInitialized: true,
preventActions: false,
progress: 0,
status: status.status,
refreshTimer: const Duration(seconds: 10),
refreshing: false,
),
);
2021-12-06 18:31:19 +00:00
break;
case BackupStatusEnum.initialized:
case BackupStatusEnum.error:
2022-06-05 19:36:32 +00:00
final List<Backup> backups = await api.getBackups();
emit(
BackupsState(
backups: backups,
isInitialized: true,
preventActions: false,
progress: status.progress,
status: status.status,
error: status.errorMessage ?? '',
refreshing: false,
),
);
2021-12-06 18:31:19 +00:00
break;
case BackupStatusEnum.backingUp:
case BackupStatusEnum.restoring:
2022-06-05 19:36:32 +00:00
final List<Backup> backups = await api.getBackups();
emit(
BackupsState(
backups: backups,
isInitialized: true,
preventActions: true,
progress: status.progress,
status: status.status,
error: status.errorMessage ?? '',
refreshTimer: const Duration(seconds: 5),
refreshing: false,
),
);
2021-12-06 18:31:19 +00:00
break;
default:
2022-05-24 18:55:39 +00:00
emit(const BackupsState());
2021-12-06 18:31:19 +00:00
}
Timer(state.refreshTimer, () => updateBackups(useTimer: true));
}
}
}
Future<void> createBucket() async {
emit(state.copyWith(preventActions: true));
2022-06-05 19:36:32 +00:00
final String domain = serverInstallationCubit.state.serverDomain!.domainName
2022-02-01 01:56:05 +00:00
.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '-');
2022-06-05 19:36:32 +00:00
final int serverId = serverInstallationCubit.state.serverDetails!.id;
String bucketName = 'selfprivacy-$domain-$serverId';
2021-12-06 18:31:19 +00:00
// If bucket name is too long, shorten it
if (bucketName.length > 49) {
bucketName = bucketName.substring(0, 49);
}
2022-06-05 19:36:32 +00:00
final String bucketId = await backblaze.createBucket(bucketName);
2021-12-06 18:31:19 +00:00
2022-06-05 19:36:32 +00:00
final BackblazeApplicationKey key = await backblaze.createKey(bucketId);
final BackblazeBucket bucket = BackblazeBucket(
bucketId: bucketId,
bucketName: bucketName,
applicationKey: key.applicationKey,
applicationKeyId: key.applicationKeyId,
);
2021-12-06 18:31:19 +00:00
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
await api.uploadBackblazeConfig(bucket);
await updateBackups();
emit(state.copyWith(isInitialized: true, preventActions: false));
}
Future<void> reuploadKey() async {
emit(state.copyWith(preventActions: true));
2022-06-05 19:36:32 +00:00
final BackblazeBucket? bucket = getIt<ApiConfigModel>().backblazeBucket;
2021-12-06 18:31:19 +00:00
if (bucket == null) {
emit(state.copyWith(isInitialized: false));
} else {
await api.uploadBackblazeConfig(bucket);
emit(state.copyWith(isInitialized: true, preventActions: false));
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
2021-12-06 18:31:19 +00:00
}
}
2022-06-05 19:36:32 +00:00
Duration refreshTimeFromState(final BackupStatusEnum status) {
2021-12-06 18:31:19 +00:00
switch (status) {
case BackupStatusEnum.backingUp:
case BackupStatusEnum.restoring:
2022-05-24 18:55:39 +00:00
return const Duration(seconds: 5);
2021-12-06 18:31:19 +00:00
case BackupStatusEnum.initializing:
2022-05-24 18:55:39 +00:00
return const Duration(seconds: 10);
2021-12-06 18:31:19 +00:00
default:
2022-05-24 18:55:39 +00:00
return const Duration(seconds: 60);
2021-12-06 18:31:19 +00:00
}
}
2022-06-05 19:36:32 +00:00
Future<void> updateBackups({final bool useTimer = false}) async {
2021-12-06 18:31:19 +00:00
emit(state.copyWith(refreshing: true));
2022-06-05 19:36:32 +00:00
final List<Backup> backups = await api.getBackups();
final BackupStatus status = await api.getBackupStatus();
emit(
state.copyWith(
backups: backups,
progress: status.progress,
status: status.status,
error: status.errorMessage,
refreshTimer: refreshTimeFromState(status.status),
refreshing: false,
),
);
2022-05-24 18:55:39 +00:00
if (useTimer) {
2021-12-06 18:31:19 +00:00
Timer(state.refreshTimer, () => updateBackups(useTimer: true));
2022-05-24 18:55:39 +00:00
}
2021-12-06 18:31:19 +00:00
}
Future<void> forceUpdateBackups() async {
emit(state.copyWith(preventActions: true));
await api.forceBackupListReload();
getIt<NavigationService>().showSnackBar('backup.refetching_list'.tr());
emit(state.copyWith(preventActions: false));
}
2021-12-06 18:31:19 +00:00
Future<void> createBackup() async {
emit(state.copyWith(preventActions: true));
await api.startBackup();
await updateBackups();
emit(state.copyWith(preventActions: false));
}
2022-06-05 19:36:32 +00:00
Future<void> restoreBackup(final String backupId) async {
2021-12-06 18:31:19 +00:00
emit(state.copyWith(preventActions: true));
await api.restoreBackup(backupId);
emit(state.copyWith(preventActions: false));
}
@override
void clear() async {
2022-05-24 18:55:39 +00:00
emit(const BackupsState());
2021-12-06 18:31:19 +00:00
}
}