mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-09 09:31:13 +00:00
chore: Implement new backups api
This commit is contained in:
parent
e70cbab618
commit
f05bedf460
|
@ -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
|
@ -2,6 +2,7 @@ import 'package:graphql/client.dart';
|
||||||
import 'package:selfprivacy/config/get_it_config.dart';
|
import 'package:selfprivacy/config/get_it_config.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/generic_result.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/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/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/schema.graphql.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_api.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/services.graphql.dart';
|
||||||
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/users.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/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_details.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
import 'package:selfprivacy/logic/models/hive/server_domain.dart';
|
||||||
import 'package:selfprivacy/logic/models/hive/user.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/api_token.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/backup.dart';
|
import 'package:selfprivacy/logic/models/json/backup.dart';
|
||||||
import 'package:selfprivacy/logic/models/json/device_token.dart';
|
import 'package:selfprivacy/logic/models/json/device_token.dart';
|
||||||
|
@ -510,7 +511,133 @@ class ServerApi extends GraphQLApiMap
|
||||||
return token;
|
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(
|
Future<BackupStatus> getBackupStatus() async => BackupStatus(
|
||||||
progress: 0.0,
|
progress: 0.0,
|
||||||
|
@ -518,13 +645,67 @@ class ServerApi extends GraphQLApiMap
|
||||||
errorMessage: null,
|
errorMessage: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<List<Backup>> getBackups() async => [];
|
Future<GenericResult> removeRepository() async {
|
||||||
|
try {
|
||||||
Future<void> uploadBackblazeConfig(final BackblazeBucket bucket) async {}
|
final GraphQLClient client = await getClient();
|
||||||
|
await client.mutate$RemoveRepository();
|
||||||
Future<void> forceBackupListReload() async {}
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
Future<void> startBackup() async {}
|
return GenericResult(
|
||||||
|
success: false,
|
||||||
Future<void> restoreBackup(final String backupId) async {}
|
data: null,
|
||||||
|
message: e.toString(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GenericResult(
|
||||||
|
success: true,
|
||||||
|
data: null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<GenericResult> initializeRepository(
|
||||||
|
final InitializeRepositoryInput input,
|
||||||
|
) async {
|
||||||
|
QueryResult<Mutation$InitializeRepository> response;
|
||||||
|
GenericResult? result;
|
||||||
|
|
||||||
|
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(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,10 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
break;
|
break;
|
||||||
case BackupStatusEnum.initialized:
|
case BackupStatusEnum.initialized:
|
||||||
case BackupStatusEnum.error:
|
case BackupStatusEnum.error:
|
||||||
final List<Backup> backups = await api.getBackups();
|
final result = await api.getBackups();
|
||||||
emit(
|
emit(
|
||||||
BackupsState(
|
BackupsState(
|
||||||
backups: backups,
|
backups: result.data,
|
||||||
isInitialized: true,
|
isInitialized: true,
|
||||||
preventActions: false,
|
preventActions: false,
|
||||||
progress: status.progress,
|
progress: status.progress,
|
||||||
|
@ -78,10 +78,10 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
break;
|
break;
|
||||||
case BackupStatusEnum.backingUp:
|
case BackupStatusEnum.backingUp:
|
||||||
case BackupStatusEnum.restoring:
|
case BackupStatusEnum.restoring:
|
||||||
final List<Backup> backups = await api.getBackups();
|
final result = await api.getBackups();
|
||||||
emit(
|
emit(
|
||||||
BackupsState(
|
BackupsState(
|
||||||
backups: backups,
|
backups: result.data,
|
||||||
isInitialized: true,
|
isInitialized: true,
|
||||||
preventActions: true,
|
preventActions: true,
|
||||||
progress: status.progress,
|
progress: status.progress,
|
||||||
|
@ -121,7 +121,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
);
|
);
|
||||||
|
|
||||||
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
|
await getIt<ApiConfigModel>().storeBackblazeBucket(bucket);
|
||||||
await api.uploadBackblazeConfig(bucket);
|
//await api.uploadBackblazeConfig(bucket);
|
||||||
await updateBackups();
|
await updateBackups();
|
||||||
|
|
||||||
emit(state.copyWith(isInitialized: true, preventActions: false));
|
emit(state.copyWith(isInitialized: true, preventActions: false));
|
||||||
|
@ -133,7 +133,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
if (bucket == null) {
|
if (bucket == null) {
|
||||||
emit(state.copyWith(isInitialized: false));
|
emit(state.copyWith(isInitialized: false));
|
||||||
} else {
|
} else {
|
||||||
await api.uploadBackblazeConfig(bucket);
|
//await api.uploadBackblazeConfig(bucket);
|
||||||
emit(state.copyWith(isInitialized: true, preventActions: false));
|
emit(state.copyWith(isInitialized: true, preventActions: false));
|
||||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
|
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,12 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
|
|
||||||
Future<void> updateBackups({final bool useTimer = false}) async {
|
Future<void> updateBackups({final bool useTimer = false}) async {
|
||||||
emit(state.copyWith(refreshing: true));
|
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();
|
final BackupStatus status = await api.getBackupStatus();
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
@ -186,7 +191,9 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
||||||
|
|
||||||
Future<void> restoreBackup(final String backupId) async {
|
Future<void> restoreBackup(final String backupId) async {
|
||||||
emit(state.copyWith(preventActions: true));
|
emit(state.copyWith(preventActions: true));
|
||||||
await api.restoreBackup(backupId);
|
|
||||||
|
/// TOOD: ???
|
||||||
|
//await api.restoreBackup(backupId);
|
||||||
emit(state.copyWith(preventActions: false));
|
emit(state.copyWith(preventActions: false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,11 @@ part 'backups_credential.g.dart';
|
||||||
|
|
||||||
@HiveType(typeId: 4)
|
@HiveType(typeId: 4)
|
||||||
class BackupsCredential {
|
class BackupsCredential {
|
||||||
BackupsCredential({required this.keyId, required this.applicationKey, required this.provider});
|
BackupsCredential({
|
||||||
|
required this.keyId,
|
||||||
|
required this.applicationKey,
|
||||||
|
required this.provider,
|
||||||
|
});
|
||||||
|
|
||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
final String keyId;
|
final String keyId;
|
||||||
|
@ -41,11 +45,19 @@ enum BackupsProvider {
|
||||||
@HiveField(3)
|
@HiveField(3)
|
||||||
backblaze;
|
backblaze;
|
||||||
|
|
||||||
factory BackupsProvider.fromGraphQL(final Enum$BackupProvider provider) => switch (provider) {
|
factory BackupsProvider.fromGraphQL(final Enum$BackupProvider provider) =>
|
||||||
|
switch (provider) {
|
||||||
Enum$BackupProvider.NONE => none,
|
Enum$BackupProvider.NONE => none,
|
||||||
Enum$BackupProvider.MEMORY => memory,
|
Enum$BackupProvider.MEMORY => memory,
|
||||||
Enum$BackupProvider.FILE => file,
|
Enum$BackupProvider.FILE => file,
|
||||||
Enum$BackupProvider.BACKBLAZE => backblaze,
|
Enum$BackupProvider.BACKBLAZE => backblaze,
|
||||||
Enum$BackupProvider.$unknown => none
|
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,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
16
lib/logic/models/initialize_repository_input.dart
Normal file
16
lib/logic/models/initialize_repository_input.dart
Normal 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;
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/backups.graphql.dart';
|
||||||
|
|
||||||
part 'backup.g.dart';
|
part 'backup.g.dart';
|
||||||
|
|
||||||
|
@ -6,12 +7,28 @@ part 'backup.g.dart';
|
||||||
class Backup {
|
class Backup {
|
||||||
factory Backup.fromJson(final Map<String, dynamic> json) =>
|
factory Backup.fromJson(final Map<String, dynamic> json) =>
|
||||||
_$BackupFromJson(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
|
// Time of the backup
|
||||||
final DateTime time;
|
final DateTime time;
|
||||||
@JsonKey(name: 'short_id')
|
@JsonKey(name: 'short_id')
|
||||||
final String id;
|
final String id;
|
||||||
|
final String serviceId;
|
||||||
|
final String fallbackServiceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BackupStatusEnum {
|
enum BackupStatusEnum {
|
||||||
|
|
|
@ -9,11 +9,15 @@ part of 'backup.dart';
|
||||||
Backup _$BackupFromJson(Map<String, dynamic> json) => Backup(
|
Backup _$BackupFromJson(Map<String, dynamic> json) => Backup(
|
||||||
time: DateTime.parse(json['time'] as String),
|
time: DateTime.parse(json['time'] as String),
|
||||||
id: json['short_id'] 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>{
|
Map<String, dynamic> _$BackupToJson(Backup instance) => <String, dynamic>{
|
||||||
'time': instance.time.toIso8601String(),
|
'time': instance.time.toIso8601String(),
|
||||||
'short_id': instance.id,
|
'short_id': instance.id,
|
||||||
|
'serviceId': instance.serviceId,
|
||||||
|
'fallbackServiceName': instance.fallbackServiceName,
|
||||||
};
|
};
|
||||||
|
|
||||||
BackupStatus _$BackupStatusFromJson(Map<String, dynamic> json) => BackupStatus(
|
BackupStatus _$BackupStatusFromJson(Map<String, dynamic> json) => BackupStatus(
|
||||||
|
|
Loading…
Reference in a new issue