Implement move
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import "dart:typed_data";
|
||||
|
||||
import "package:ente_crypto/ente_crypto.dart";
|
||||
|
||||
class CollectionFileItem {
|
||||
final int id;
|
||||
@@ -11,16 +13,16 @@ class CollectionFileItem {
|
||||
this.keyDecryptionNonce,
|
||||
);
|
||||
|
||||
CollectionFileItem copyWith({
|
||||
int? id,
|
||||
String? encryptedKey,
|
||||
String? keyDecryptionNonce,
|
||||
static Map<String, dynamic> req(
|
||||
int fileID, {
|
||||
required Uint8List encryptedKey,
|
||||
required Uint8List keyDecryptionNonce,
|
||||
}) {
|
||||
return CollectionFileItem(
|
||||
id ?? this.id,
|
||||
encryptedKey ?? this.encryptedKey,
|
||||
keyDecryptionNonce ?? this.keyDecryptionNonce,
|
||||
);
|
||||
return {
|
||||
'fileID': fileID,
|
||||
'encryptedKey': CryptoUtil.bin2base64(encryptedKey),
|
||||
'keyDecryptionNonce': CryptoUtil.bin2base64(keyDecryptionNonce),
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
@@ -30,37 +32,4 @@ class CollectionFileItem {
|
||||
'keyDecryptionNonce': keyDecryptionNonce,
|
||||
};
|
||||
}
|
||||
|
||||
static fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) return null;
|
||||
|
||||
return CollectionFileItem(
|
||||
map['id'],
|
||||
map['encryptedKey'],
|
||||
map['keyDecryptionNonce'],
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory CollectionFileItem.fromJson(String source) =>
|
||||
CollectionFileItem.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'CollectionFileItem(id: $id, encryptedKey: $encryptedKey, keyDecryptionNonce: $keyDecryptionNonce)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object o) {
|
||||
if (identical(this, o)) return true;
|
||||
|
||||
return o is CollectionFileItem &&
|
||||
o.id == id &&
|
||||
o.encryptedKey == encryptedKey &&
|
||||
o.keyDecryptionNonce == keyDecryptionNonce;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
id.hashCode ^ encryptedKey.hashCode ^ keyDecryptionNonce.hashCode;
|
||||
}
|
||||
|
||||
@@ -1523,15 +1523,15 @@ class CollectionsService {
|
||||
final List<EnteFile> newFiles = [];
|
||||
for (final file in batch) {
|
||||
final newFile = moveOrAddEntry(file, destCollection);
|
||||
final item = mapDiffItem(newFile);
|
||||
collectionDiffItems.add(item);
|
||||
final localDiffItem = buildDiffItem(newFile);
|
||||
collectionDiffItems.add(localDiffItem);
|
||||
newFiles.add(newFile);
|
||||
params["files"].add(
|
||||
CollectionFileItem(
|
||||
item.fileID,
|
||||
CryptoUtil.bin2base64(item.encFileKey!),
|
||||
CryptoUtil.bin2base64(item.encFileKeyNonce!),
|
||||
).toMap(),
|
||||
CollectionFileItem.req(
|
||||
localDiffItem.fileID,
|
||||
encryptedKey: localDiffItem.encFileKey!,
|
||||
keyDecryptionNonce: localDiffItem.encFileKeyNonce!,
|
||||
),
|
||||
);
|
||||
}
|
||||
try {
|
||||
@@ -1618,9 +1618,6 @@ class CollectionsService {
|
||||
params["files"] = [];
|
||||
for (final batchFile in batch) {
|
||||
final fileKey = getFileKey(batchFile);
|
||||
_logger.info(
|
||||
"srcCollection : $srcCollectionID file: ${batchFile.uploadedFileID} key: ${CryptoUtil.bin2base64(fileKey)} ",
|
||||
);
|
||||
final encryptedKeyData =
|
||||
CryptoUtil.encryptSync(fileKey, getCollectionKey(dstCollectionID));
|
||||
batchFile.encryptedKey =
|
||||
@@ -1847,48 +1844,38 @@ class CollectionsService {
|
||||
}
|
||||
|
||||
final batchedFiles = files.chunks(batchSize);
|
||||
final List<EnteFile> movedFiles = [];
|
||||
for (final batch in batchedFiles) {
|
||||
final params = <String, dynamic>{};
|
||||
params["toCollectionID"] = toCollectionID;
|
||||
params["fromCollectionID"] = fromCollectionID;
|
||||
params["files"] = [];
|
||||
final List<EnteFile> batchMovedFiles = [];
|
||||
final List<DiffFileItem> collectionDiffItems = [];
|
||||
for (final file in batch) {
|
||||
final fileKey = getFileKey(file);
|
||||
file.generatedID =
|
||||
null; // So that a new entry is created in the FilesDB
|
||||
file.collectionID = toCollectionID;
|
||||
final encryptedKeyData =
|
||||
CryptoUtil.encryptSync(fileKey, getCollectionKey(toCollectionID));
|
||||
file.encryptedKey =
|
||||
CryptoUtil.bin2base64(encryptedKeyData.encryptedData!);
|
||||
file.keyDecryptionNonce =
|
||||
CryptoUtil.bin2base64(encryptedKeyData.nonce!);
|
||||
final newFile = moveOrAddEntry(file, toCollectionID);
|
||||
final DiffFileItem localDiffItem = buildDiffItem(newFile);
|
||||
batchMovedFiles.add(newFile);
|
||||
collectionDiffItems.add(localDiffItem);
|
||||
params["files"].add(
|
||||
CollectionFileItem(
|
||||
file.uploadedFileID!,
|
||||
file.encryptedKey!,
|
||||
file.keyDecryptionNonce!,
|
||||
).toMap(),
|
||||
CollectionFileItem.req(
|
||||
localDiffItem.fileID,
|
||||
encryptedKey: localDiffItem.encFileKey!,
|
||||
keyDecryptionNonce: localDiffItem.encFileKeyNonce!,
|
||||
),
|
||||
);
|
||||
}
|
||||
await _enteDio.post(
|
||||
"/collections/move-files",
|
||||
data: params,
|
||||
);
|
||||
await remoteDB.insertFilesDiff(collectionDiffItems);
|
||||
await remoteDB.deleteCFEnteries(
|
||||
fromCollectionID,
|
||||
files.map((e) => e.uploadedFileID!).toList(),
|
||||
);
|
||||
movedFiles.addAll(batchMovedFiles);
|
||||
}
|
||||
|
||||
// insert new files in the toCollection which are not part of the toCollection
|
||||
final existingUploadedIDs =
|
||||
await remoteDB.getUploadedFileIDs(toCollectionID);
|
||||
files.removeWhere(
|
||||
(element) => existingUploadedIDs.contains(element.uploadedFileID),
|
||||
);
|
||||
await _filesDB.insertMultiple(files);
|
||||
// remove files from old collection
|
||||
await remoteDB.deleteCFEnteries(
|
||||
fromCollectionID,
|
||||
files.map((e) => e.uploadedFileID!).toList(),
|
||||
);
|
||||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(
|
||||
fromCollectionID,
|
||||
@@ -1898,7 +1885,7 @@ class CollectionsService {
|
||||
),
|
||||
);
|
||||
Bus.instance.fire(
|
||||
CollectionUpdatedEvent(toCollectionID, files, "moveTo"),
|
||||
CollectionUpdatedEvent(toCollectionID, movedFiles, "moveTo"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import "package:ente_crypto/ente_crypto.dart";
|
||||
import "package:photos/models/api/diff/diff.dart";
|
||||
import "package:photos/models/file/file.dart";
|
||||
import "package:photos/models/file/remote/asset.dart";
|
||||
import "package:photos/models/file/remote/file_entry.dart";
|
||||
import "package:photos/services/collections_service.dart";
|
||||
import "package:photos/utils/file_key.dart";
|
||||
@@ -33,18 +32,14 @@ extension CollectionsServiceMapper on CollectionsService {
|
||||
);
|
||||
}
|
||||
|
||||
DiffFileItem mapDiffItem(EnteFile file) {
|
||||
DiffFileItem buildDiffItem(EnteFile file) {
|
||||
if (file.remoteAsset == null || file.fileEntry == null) {
|
||||
throw ArgumentError(
|
||||
"File must have remoteAsset and fileEntry to be mapped.",
|
||||
);
|
||||
throw ArgumentError("must have remoteAsset and fileEntry");
|
||||
}
|
||||
final remoteAsset = file.remoteAsset!;
|
||||
final cf = file.fileEntry!;
|
||||
if (remoteAsset.id != cf.fileID) {
|
||||
throw ArgumentError(
|
||||
"File ID in remote asset does not match file entry.",
|
||||
);
|
||||
throw ArgumentError("File ID in remote asset does not match file entry.");
|
||||
}
|
||||
|
||||
return DiffFileItem(
|
||||
|
||||
Reference in New Issue
Block a user