chore: Implement new backups api

pull/228/head
NaiJi ✨ 2023-06-22 11:14:00 -03:00
parent e70cbab618
commit f05bedf460
8 changed files with 2925 additions and 24 deletions

View File

@ -22,3 +22,47 @@ query AllBackupSnapshots {
}
}
}
fragment genericBackupConfigReturn on GenericBackupConfigReturn {
code
message
success
configuration {
provider
encryptionKey
isInitialized
autobackupPeriod
locationName
locationId
}
}
mutation ForceSnapshotsReload {
forceSnapshotsReload {
...basicMutationReturnFields
}
}
mutation StartBackup($serviceId: String = null) {
startBackup(serviceId: $serviceId) {
...basicMutationReturnFields
}
}
mutation SetAutobackupPeriod($period: Int = null) {
setAutobackupPeriod(period: $period) {
...genericBackupConfigReturn
}
}
mutation RemoveRepository {
removeRepository {
...genericBackupConfigReturn
}
}
mutation InitializeRepository($repository: InitializeRepositoryInput!) {
initializeRepository(repository: $repository) {
...genericBackupConfigReturn
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ import 'package:graphql/client.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/logic/api_maps/generic_result.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/graphql_api_map.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/disk_volumes.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.graphql.dart';
@ -9,10 +10,10 @@ import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.g
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.graphql.dart';
import 'package:selfprivacy/logic/models/auto_upgrade_settings.dart';
import 'package:selfprivacy/logic/models/hive/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/hive/server_details.dart';
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
import 'package:selfprivacy/logic/models/hive/user.dart';
import 'package:selfprivacy/logic/models/initialize_repository_input.dart';
import 'package:selfprivacy/logic/models/json/api_token.dart';
import 'package:selfprivacy/logic/models/json/backup.dart';
import 'package:selfprivacy/logic/models/json/device_token.dart';
@ -510,7 +511,133 @@ class ServerApi extends GraphQLApiMap
return token;
}
/// TODO: backups're not implemented on server side
Future<GenericResult<List<Backup>>> getBackups() async {
GenericResult<List<Backup>> backups;
QueryResult<Query$AllBackupSnapshots> response;
try {
final GraphQLClient client = await getClient();
response = await client.query$AllBackupSnapshots();
if (response.hasException) {
final message = response.exception.toString();
print(message);
backups = GenericResult<List<Backup>>(
success: false,
data: [],
message: message,
);
}
final List<Backup> parsed = response.parsedData!.backup.allSnapshots
.map(
(
final Query$AllBackupSnapshots$backup$allSnapshots snapshot,
) =>
Backup.fromGraphQL(snapshot),
)
.toList();
backups = GenericResult<List<Backup>>(
success: true,
data: parsed,
);
} catch (e) {
print(e);
backups = GenericResult<List<Backup>>(
success: false,
data: [],
message: e.toString(),
);
}
return backups;
}
Future<GenericResult> forceBackupListReload() async {
try {
final GraphQLClient client = await getClient();
await client.mutate$ForceSnapshotsReload();
} catch (e) {
print(e);
return GenericResult(
success: false,
data: null,
message: e.toString(),
);
}
return GenericResult(
success: true,
data: null,
);
}
Future<GenericResult> startBackup({final String? serviceId}) async {
QueryResult<Mutation$StartBackup> response;
GenericResult? result;
try {
final GraphQLClient client = await getClient();
final variables = Variables$Mutation$StartBackup(serviceId: serviceId);
final options = Options$Mutation$StartBackup(variables: variables);
response = await client.mutate$StartBackup(options);
if (response.hasException) {
final message = response.exception.toString();
print(message);
result = GenericResult(
success: false,
data: null,
message: message,
);
}
result = GenericResult(
success: true,
data: null,
);
} catch (e) {
print(e);
result = GenericResult(
success: false,
data: null,
message: e.toString(),
);
}
return result;
}
Future<GenericResult> setAutobackupPeriod({final int? period}) async {
QueryResult<Mutation$SetAutobackupPeriod> response;
GenericResult? result;
try {
final GraphQLClient client = await getClient();
final variables = Variables$Mutation$SetAutobackupPeriod(period: period);
final options =
Options$Mutation$SetAutobackupPeriod(variables: variables);
response = await client.mutate$SetAutobackupPeriod(options);
if (response.hasException) {
final message = response.exception.toString();
print(message);
result = GenericResult(
success: false,
data: null,
message: message,
);
}
result = GenericResult(
success: true,
data: null,
);
} catch (e) {
print(e);
result = GenericResult(
success: false,
data: null,
message: e.toString(),
);
}
return result;
}
Future<BackupStatus> getBackupStatus() async => BackupStatus(
progress: 0.0,
@ -518,13 +645,67 @@ class ServerApi extends GraphQLApiMap
errorMessage: null,
);
Future<List<Backup>> getBackups() async => [];
Future<GenericResult> removeRepository() async {
try {
final GraphQLClient client = await getClient();
await client.mutate$RemoveRepository();
} catch (e) {
print(e);
return GenericResult(
success: false,
data: null,
message: e.toString(),
);
}
Future<void> uploadBackblazeConfig(final BackblazeBucket bucket) async {}
return GenericResult(
success: true,
data: null,
);
}
Future<void> forceBackupListReload() async {}
Future<GenericResult> initializeRepository(
final InitializeRepositoryInput input,
) async {
QueryResult<Mutation$InitializeRepository> response;
GenericResult? result;
Future<void> startBackup() async {}
try {
final GraphQLClient client = await getClient();
final variables = Variables$Mutation$InitializeRepository(
repository: Input$InitializeRepositoryInput(
locationId: input.locationId,
locationName: input.locationName,
login: input.login,
password: input.password,
provider: input.provider.toGraphQL(),
),
);
final options =
Options$Mutation$InitializeRepository(variables: variables);
response = await client.mutate$InitializeRepository(options);
if (response.hasException) {
final message = response.exception.toString();
print(message);
result = GenericResult(
success: false,
data: null,
message: message,
);
}
result = GenericResult(
success: true,
data: null,
);
} catch (e) {
print(e);
result = GenericResult(
success: false,
data: null,
message: e.toString(),
);
}
Future<void> restoreBackup(final String backupId) async {}
return result;
}
}

View File

@ -63,10 +63,10 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
break;
case BackupStatusEnum.initialized:
case BackupStatusEnum.error:
final List<Backup> backups = await api.getBackups();
final result = await api.getBackups();
emit(
BackupsState(
backups: backups,
backups: result.data,
isInitialized: true,
preventActions: false,
progress: status.progress,
@ -78,10 +78,10 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
break;
case BackupStatusEnum.backingUp:
case BackupStatusEnum.restoring:
final List<Backup> backups = await api.getBackups();
final result = await api.getBackups();
emit(
BackupsState(
backups: backups,
backups: result.data,
isInitialized: true,
preventActions: true,
progress: status.progress,
@ -121,7 +121,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
);
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
await api.uploadBackblazeConfig(bucket);
//await api.uploadBackblazeConfig(bucket);
await updateBackups();
emit(state.copyWith(isInitialized: true, preventActions: false));
@ -133,7 +133,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
if (bucket == null) {
emit(state.copyWith(isInitialized: false));
} else {
await api.uploadBackblazeConfig(bucket);
//await api.uploadBackblazeConfig(bucket);
emit(state.copyWith(isInitialized: true, preventActions: false));
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
}
@ -153,7 +153,12 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
Future<void> updateBackups({final bool useTimer = false}) async {
emit(state.copyWith(refreshing: true));
final List<Backup> backups = await api.getBackups();
final result = await api.getBackups();
if (!result.success || result.data.isEmpty) {
return;
}
final List<Backup> backups = result.data;
final BackupStatus status = await api.getBackupStatus();
emit(
state.copyWith(
@ -186,7 +191,9 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
Future<void> restoreBackup(final String backupId) async {
emit(state.copyWith(preventActions: true));
await api.restoreBackup(backupId);
/// TOOD: ???
//await api.restoreBackup(backupId);
emit(state.copyWith(preventActions: false));
}

View File

@ -7,7 +7,11 @@ part 'backups_credential.g.dart';
@HiveType(typeId: 4)
class BackupsCredential {
BackupsCredential({required this.keyId, required this.applicationKey, required this.provider});
BackupsCredential({
required this.keyId,
required this.applicationKey,
required this.provider,
});
@HiveField(0)
final String keyId;
@ -41,11 +45,19 @@ enum BackupsProvider {
@HiveField(3)
backblaze;
factory BackupsProvider.fromGraphQL(final Enum$BackupProvider provider) => switch (provider) {
Enum$BackupProvider.NONE => none,
Enum$BackupProvider.MEMORY => memory,
Enum$BackupProvider.FILE => file,
Enum$BackupProvider.BACKBLAZE => backblaze,
Enum$BackupProvider.$unknown => none
};
factory BackupsProvider.fromGraphQL(final Enum$BackupProvider provider) =>
switch (provider) {
Enum$BackupProvider.NONE => none,
Enum$BackupProvider.MEMORY => memory,
Enum$BackupProvider.FILE => file,
Enum$BackupProvider.BACKBLAZE => backblaze,
Enum$BackupProvider.$unknown => none
};
Enum$BackupProvider toGraphQL() => switch (this) {
none => Enum$BackupProvider.NONE,
memory => Enum$BackupProvider.MEMORY,
file => Enum$BackupProvider.FILE,
backblaze => Enum$BackupProvider.BACKBLAZE,
};
}

View File

@ -0,0 +1,16 @@
import 'package:selfprivacy/logic/models/hive/backups_credential.dart';
class InitializeRepositoryInput {
InitializeRepositoryInput({
required this.provider,
required this.locationId,
required this.locationName,
required this.login,
required this.password,
});
final BackupsProvider provider;
final String locationId;
final String locationName;
final String login;
final String password;
}

View File

@ -1,4 +1,5 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart';
part 'backup.g.dart';
@ -6,12 +7,28 @@ part 'backup.g.dart';
class Backup {
factory Backup.fromJson(final Map<String, dynamic> json) =>
_$BackupFromJson(json);
Backup({required this.time, required this.id});
Backup.fromGraphQL(
final Query$AllBackupSnapshots$backup$allSnapshots snapshot,
) : this(
id: snapshot.id,
time: snapshot.createdAt,
serviceId: snapshot.service.id,
fallbackServiceName: snapshot.service.displayName,
);
Backup({
required this.time,
required this.id,
required this.serviceId,
required this.fallbackServiceName,
});
// Time of the backup
final DateTime time;
@JsonKey(name: 'short_id')
final String id;
final String serviceId;
final String fallbackServiceName;
}
enum BackupStatusEnum {

View File

@ -9,11 +9,15 @@ part of 'backup.dart';
Backup _$BackupFromJson(Map<String, dynamic> json) => Backup(
time: DateTime.parse(json['time'] as String),
id: json['short_id'] as String,
serviceId: json['serviceId'] as String,
fallbackServiceName: json['fallbackServiceName'] as String,
);
Map<String, dynamic> _$BackupToJson(Backup instance) => <String, dynamic>{
'time': instance.time.toIso8601String(),
'short_id': instance.id,
'serviceId': instance.serviceId,
'fallbackServiceName': instance.fallbackServiceName,
};
BackupStatus _$BackupStatusFromJson(Map<String, dynamic> json) => BackupStatus(