|
@@ -7,8 +7,6 @@ import 'package:photos/core/configuration.dart';
|
|
import 'package:photos/core/event_bus.dart';
|
|
import 'package:photos/core/event_bus.dart';
|
|
import 'package:photos/core/network.dart';
|
|
import 'package:photos/core/network.dart';
|
|
import 'package:photos/db/files_db.dart';
|
|
import 'package:photos/db/files_db.dart';
|
|
-import 'package:photos/events/collection_updated_event.dart';
|
|
|
|
-import 'package:photos/events/local_photos_updated_event.dart';
|
|
|
|
import 'package:photos/events/remote_sync_event.dart';
|
|
import 'package:photos/events/remote_sync_event.dart';
|
|
import 'package:photos/models/file.dart';
|
|
import 'package:photos/models/file.dart';
|
|
import 'package:photos/models/magic_metadata.dart';
|
|
import 'package:photos/models/magic_metadata.dart';
|
|
@@ -21,100 +19,96 @@ class DiffFetcher {
|
|
|
|
|
|
Future<Diff> getEncryptedFilesDiff(
|
|
Future<Diff> getEncryptedFilesDiff(
|
|
int collectionID, int sinceTime, int limit) async {
|
|
int collectionID, int sinceTime, int limit) async {
|
|
- return _dio
|
|
|
|
- .get(
|
|
|
|
- Configuration.instance.getHttpEndpoint() + "/collections/diff",
|
|
|
|
- options: Options(
|
|
|
|
- headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
|
|
|
- queryParameters: {
|
|
|
|
- "collectionID": collectionID,
|
|
|
|
- "sinceTime": sinceTime,
|
|
|
|
- "limit": limit,
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .catchError((e) => _logger.severe(e))
|
|
|
|
- .then((response) async {
|
|
|
|
- final files = <File>[];
|
|
|
|
- if (response != null) {
|
|
|
|
- Bus.instance.fire(RemoteSyncEvent(true));
|
|
|
|
- final diff = response.data["diff"] as List;
|
|
|
|
- final startTime = DateTime.now();
|
|
|
|
- final existingFiles =
|
|
|
|
- await FilesDB.instance.getUploadedFileIDs(collectionID);
|
|
|
|
- for (final item in diff) {
|
|
|
|
- final file = File();
|
|
|
|
- file.uploadedFileID = item["id"];
|
|
|
|
- file.collectionID = item["collectionID"];
|
|
|
|
- if (item["isDeleted"]) {
|
|
|
|
- if (existingFiles.contains(file.uploadedFileID)) {
|
|
|
|
- await FilesDB.instance.deleteFromCollection(
|
|
|
|
- file.uploadedFileID, file.collectionID);
|
|
|
|
- Bus.instance
|
|
|
|
- .fire(CollectionUpdatedEvent(file.collectionID, [file]));
|
|
|
|
- Bus.instance.fire(LocalPhotosUpdatedEvent([file]));
|
|
|
|
- }
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- if (existingFiles.contains(file.uploadedFileID)) {
|
|
|
|
- final existingFile = await FilesDB.instance
|
|
|
|
- .getUploadedFile(file.uploadedFileID, file.collectionID);
|
|
|
|
- if (existingFile != null) {
|
|
|
|
- file.generatedID = existingFile.generatedID;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- file.updationTime = item["updationTime"];
|
|
|
|
- file.ownerID = item["ownerID"];
|
|
|
|
- file.encryptedKey = item["encryptedKey"];
|
|
|
|
- file.keyDecryptionNonce = item["keyDecryptionNonce"];
|
|
|
|
- file.fileDecryptionHeader = item["file"]["decryptionHeader"];
|
|
|
|
- file.thumbnailDecryptionHeader =
|
|
|
|
- item["thumbnail"]["decryptionHeader"];
|
|
|
|
- file.metadataDecryptionHeader =
|
|
|
|
- item["metadata"]["decryptionHeader"];
|
|
|
|
-
|
|
|
|
- final fileDecryptionKey = decryptFileKey(file);
|
|
|
|
- final encodedMetadata = await CryptoUtil.decryptChaCha(
|
|
|
|
- Sodium.base642bin(item["metadata"]["encryptedData"]),
|
|
|
|
- fileDecryptionKey,
|
|
|
|
- Sodium.base642bin(file.metadataDecryptionHeader),
|
|
|
|
- );
|
|
|
|
- Map<String, dynamic> metadata =
|
|
|
|
- jsonDecode(utf8.decode(encodedMetadata));
|
|
|
|
- file.applyMetadata(metadata);
|
|
|
|
- if (item['magicMetadata'] != null) {
|
|
|
|
- final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
|
|
|
- Sodium.base642bin(item['magicMetadata']['data']),
|
|
|
|
- fileDecryptionKey,
|
|
|
|
- Sodium.base642bin(item['magicMetadata']['header']));
|
|
|
|
- file.mMdEncodedJson = utf8.decode(utfEncodedMmd);
|
|
|
|
- file.mMdVersion = item['magicMetadata']['version'];
|
|
|
|
- file.magicMetadata =
|
|
|
|
- MagicMetadata.fromEncodedJson(file.mMdEncodedJson);
|
|
|
|
- }
|
|
|
|
- files.add(file);
|
|
|
|
|
|
+ return _dio.get(
|
|
|
|
+ Configuration.instance.getHttpEndpoint() + "/collections/diff",
|
|
|
|
+ options:
|
|
|
|
+ Options(headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
|
|
|
+ queryParameters: {
|
|
|
|
+ "collectionID": collectionID,
|
|
|
|
+ "sinceTime": sinceTime,
|
|
|
|
+ "limit": limit,
|
|
|
|
+ },
|
|
|
|
+ ).catchError((e) {
|
|
|
|
+ _logger.severe(e);
|
|
|
|
+ }).then((response) async {
|
|
|
|
+ final files = <File>[];
|
|
|
|
+ if (response != null) {
|
|
|
|
+ Bus.instance.fire(RemoteSyncEvent(true));
|
|
|
|
+ final diff = response.data["diff"] as List;
|
|
|
|
+ final startTime = DateTime.now();
|
|
|
|
+ final existingFiles =
|
|
|
|
+ await FilesDB.instance.getUploadedFileIDs(collectionID);
|
|
|
|
+ final deletedFiles = <File>[];
|
|
|
|
+ for (final item in diff) {
|
|
|
|
+ final file = File();
|
|
|
|
+ file.uploadedFileID = item["id"];
|
|
|
|
+ file.collectionID = item["collectionID"];
|
|
|
|
+ if (item["isDeleted"]) {
|
|
|
|
+ if (existingFiles.contains(file.uploadedFileID)) {
|
|
|
|
+ deletedFiles.add(file);
|
|
|
|
+ }
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (existingFiles.contains(file.uploadedFileID)) {
|
|
|
|
+ final existingFile = await FilesDB.instance
|
|
|
|
+ .getUploadedFile(file.uploadedFileID, file.collectionID);
|
|
|
|
+ if (existingFile != null) {
|
|
|
|
+ file.generatedID = existingFile.generatedID;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+ file.updationTime = item["updationTime"];
|
|
|
|
+ file.ownerID = item["ownerID"];
|
|
|
|
+ file.encryptedKey = item["encryptedKey"];
|
|
|
|
+ file.keyDecryptionNonce = item["keyDecryptionNonce"];
|
|
|
|
+ file.fileDecryptionHeader = item["file"]["decryptionHeader"];
|
|
|
|
+ file.thumbnailDecryptionHeader =
|
|
|
|
+ item["thumbnail"]["decryptionHeader"];
|
|
|
|
+ file.metadataDecryptionHeader = item["metadata"]["decryptionHeader"];
|
|
|
|
|
|
- final endTime = DateTime.now();
|
|
|
|
- _logger.info("time for parsing " +
|
|
|
|
- files.length.toString() +
|
|
|
|
- ": " +
|
|
|
|
- Duration(
|
|
|
|
- microseconds: (endTime.microsecondsSinceEpoch -
|
|
|
|
- startTime.microsecondsSinceEpoch))
|
|
|
|
- .inMilliseconds
|
|
|
|
- .toString());
|
|
|
|
- return Diff(files, diff.length);
|
|
|
|
- } else {
|
|
|
|
- Bus.instance.fire(RemoteSyncEvent(false));
|
|
|
|
- return Diff(<File>[], 0);
|
|
|
|
|
|
+ final fileDecryptionKey = decryptFileKey(file);
|
|
|
|
+ final encodedMetadata = await CryptoUtil.decryptChaCha(
|
|
|
|
+ Sodium.base642bin(item["metadata"]["encryptedData"]),
|
|
|
|
+ fileDecryptionKey,
|
|
|
|
+ Sodium.base642bin(file.metadataDecryptionHeader),
|
|
|
|
+ );
|
|
|
|
+ Map<String, dynamic> metadata =
|
|
|
|
+ jsonDecode(utf8.decode(encodedMetadata));
|
|
|
|
+ file.applyMetadata(metadata);
|
|
|
|
+ if (item['magicMetadata'] != null) {
|
|
|
|
+ final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
|
|
|
+ Sodium.base642bin(item['magicMetadata']['data']),
|
|
|
|
+ fileDecryptionKey,
|
|
|
|
+ Sodium.base642bin(item['magicMetadata']['header']));
|
|
|
|
+ file.mMdEncodedJson = utf8.decode(utfEncodedMmd);
|
|
|
|
+ file.mMdVersion = item['magicMetadata']['version'];
|
|
|
|
+ file.magicMetadata =
|
|
|
|
+ MagicMetadata.fromEncodedJson(file.mMdEncodedJson);
|
|
}
|
|
}
|
|
- });
|
|
|
|
|
|
+ files.add(file);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ final endTime = DateTime.now();
|
|
|
|
+ _logger.info("time for parsing " +
|
|
|
|
+ files.length.toString() +
|
|
|
|
+ ": " +
|
|
|
|
+ Duration(
|
|
|
|
+ microseconds: (endTime.microsecondsSinceEpoch -
|
|
|
|
+ startTime.microsecondsSinceEpoch))
|
|
|
|
+ .inMilliseconds
|
|
|
|
+ .toString());
|
|
|
|
+ return Diff(files, deletedFiles, diff.length);
|
|
|
|
+ } else {
|
|
|
|
+ Bus.instance.fire(RemoteSyncEvent(false));
|
|
|
|
+ return Diff(<File>[], <File>[], 0);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class Diff {
|
|
class Diff {
|
|
final List<File> updatedFiles;
|
|
final List<File> updatedFiles;
|
|
|
|
+ final List<File> deletedFiles;
|
|
final int fetchCount;
|
|
final int fetchCount;
|
|
|
|
|
|
- Diff(this.updatedFiles, this.fetchCount);
|
|
|
|
|
|
+ Diff(this.updatedFiles, this.deletedFiles, this.fetchCount);
|
|
}
|
|
}
|