Use new abstraction to fetch public files
This commit is contained in:
@@ -55,6 +55,40 @@ class CollectionFilesService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<DiffResult> getPublicCollectionDiff(
|
||||
int collectionID,
|
||||
int sinceTime,
|
||||
Uint8List collectionKey,
|
||||
Map<String, String> headers,
|
||||
) async {
|
||||
final response = await _enteDio.get(
|
||||
"/public-collection/diff",
|
||||
options: Options(headers: headers),
|
||||
queryParameters: {"sinceTime": sinceTime},
|
||||
);
|
||||
final List diff = response.data["diff"] as List;
|
||||
if (diff.isEmpty) {
|
||||
return DiffResult([], [], response.data["hasMore"] as bool, 0);
|
||||
}
|
||||
final String encodedKey = base64Encode(Uint8List.fromList(collectionKey));
|
||||
final startTime = DateTime.now();
|
||||
final DiffResult result =
|
||||
await Computer.shared().compute<Map<String, dynamic>, DiffResult>(
|
||||
_parseDiff,
|
||||
param: {
|
||||
"collectionKey": encodedKey,
|
||||
"diff": diff,
|
||||
"hasMore": response.data["hasMore"] as bool,
|
||||
},
|
||||
taskName: "parseDiff",
|
||||
);
|
||||
devLog(
|
||||
'[Collection-$collectionID] $result in ${DateTime.now().difference(startTime).inMilliseconds} ms',
|
||||
name: "CollectionFilesService.getCollectionItemsDiff",
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
DiffResult _parseDiff(Map<String, dynamic> args) {
|
||||
final Uint8List collectionKey = base64Decode(args['collectionKey']);
|
||||
final List diff = args['diff'] as List;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:ente_crypto/ente_crypto.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:photos/core/network/network.dart';
|
||||
import 'package:photos/generated/l10n.dart';
|
||||
import 'package:photos/models/file/file.dart';
|
||||
import "package:photos/models/metadata/file_magic.dart";
|
||||
import "package:photos/services/collections_service.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
import "package:photos/utils/file_key.dart";
|
||||
|
||||
class DiffFetcher {
|
||||
final _logger = Logger("DiffFetcher");
|
||||
final _enteDio = NetworkClient.instance.enteDio;
|
||||
|
||||
Future<List<EnteFile>> getPublicFiles(
|
||||
BuildContext context,
|
||||
int collectionID,
|
||||
bool sortAsc,
|
||||
) async {
|
||||
try {
|
||||
bool hasMore = false;
|
||||
final sharedFiles = <EnteFile>[];
|
||||
final headers =
|
||||
CollectionsService.instance.publicCollectionHeaders(collectionID);
|
||||
int sinceTime = 0;
|
||||
|
||||
do {
|
||||
final response = await _enteDio.get(
|
||||
"/public-collection/diff",
|
||||
options: Options(headers: headers),
|
||||
queryParameters: {"sinceTime": sinceTime},
|
||||
);
|
||||
|
||||
final diff = response.data["diff"] as List;
|
||||
hasMore = response.data["hasMore"] as bool;
|
||||
|
||||
for (final item in diff) {
|
||||
final file = EnteFile();
|
||||
if (item["isDeleted"]) {
|
||||
continue;
|
||||
}
|
||||
file.uploadedFileID = item["id"];
|
||||
file.collectionID = item["collectionID"];
|
||||
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"];
|
||||
if (item["info"] != null) {
|
||||
file.fileSize = item["info"]["fileSize"];
|
||||
}
|
||||
final fileKey = getFileKey(file);
|
||||
final encodedMetadata = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item["metadata"]["encryptedData"]),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(file.metadataDecryptionHeader!),
|
||||
);
|
||||
final Map<String, dynamic> metadata =
|
||||
jsonDecode(utf8.decode(encodedMetadata));
|
||||
file.applyMetadata(metadata);
|
||||
if (item['pubMagicMetadata'] != null) {
|
||||
final utfEncodedMmd = await CryptoUtil.decryptChaCha(
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['data']),
|
||||
fileKey,
|
||||
CryptoUtil.base642bin(item['pubMagicMetadata']['header']),
|
||||
);
|
||||
file.pubMmdEncodedJson = utf8.decode(utfEncodedMmd);
|
||||
file.pubMmdVersion = item['pubMagicMetadata']['version'];
|
||||
file.pubMagicMetadata =
|
||||
PubMagicMetadata.fromEncodedJson(file.pubMmdEncodedJson!);
|
||||
}
|
||||
|
||||
// To avoid local file to be used as thumbnail or full file.
|
||||
file.localID = null;
|
||||
|
||||
sharedFiles.add(file);
|
||||
}
|
||||
|
||||
if (diff.isNotEmpty) {
|
||||
sinceTime = diff.last["updationTime"];
|
||||
}
|
||||
} while (hasMore);
|
||||
if (sortAsc) {
|
||||
sharedFiles.sort((a, b) => a.creationTime!.compareTo(b.creationTime!));
|
||||
}
|
||||
return sharedFiles;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Failed to decrypt collection ", e, s);
|
||||
await showErrorDialog(
|
||||
context,
|
||||
S.of(context).somethingWentWrong,
|
||||
e.toString(),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
71
mobile/lib/services/sync/sync_public_collection.dart
Normal file
71
mobile/lib/services/sync/sync_public_collection.dart
Normal file
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:photos/core/network/network.dart';
|
||||
import 'package:photos/generated/l10n.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/services/remote/fetch/collection_files.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
|
||||
Future<List<EnteFile>> getPublicFiles(
|
||||
BuildContext context,
|
||||
int collectionID,
|
||||
bool sortAsc,
|
||||
) async {
|
||||
try {
|
||||
final collectionFilService =
|
||||
CollectionFilesService(NetworkClient.instance.enteDio);
|
||||
bool hasMore = false;
|
||||
final sharedFiles = <EnteFile>[];
|
||||
final headers =
|
||||
CollectionsService.instance.publicCollectionHeaders(collectionID);
|
||||
int sinceTime = 0;
|
||||
final collectionKey =
|
||||
CollectionsService.instance.getCollectionKey(collectionID);
|
||||
do {
|
||||
final diffResult = await collectionFilService.getPublicCollectionDiff(
|
||||
collectionID,
|
||||
sinceTime,
|
||||
collectionKey,
|
||||
headers,
|
||||
);
|
||||
for (final item in diffResult.updatedItems) {
|
||||
final cf = CollectionFileEntry(
|
||||
collectionID: item.collectionID,
|
||||
fileID: item.fileID,
|
||||
encFileKey: item.encFileKey!,
|
||||
encFileKeyNonce: item.encFileKeyNonce!,
|
||||
updatedAt: item.updatedAt,
|
||||
createdAt: item.createdAt ?? 0,
|
||||
);
|
||||
final rAsset = RemoteAsset(
|
||||
id: item.fileItem.fileID,
|
||||
ownerID: item.fileItem.ownerID,
|
||||
fileHeader: item.fileItem.fileDecryotionHeader!,
|
||||
thumbHeader: item.fileItem.thumnailDecryptionHeader!,
|
||||
metadata: item.fileItem.metadata!,
|
||||
publicMetadata: item.fileItem.pubMagicMetadata,
|
||||
privateMetadata: item.fileItem.magicMetadata,
|
||||
info: item.fileItem.info,
|
||||
);
|
||||
sharedFiles.add(EnteFile.fromRemoteAsset(rAsset, cf));
|
||||
}
|
||||
sinceTime = diffResult.maxUpdatedAtTime;
|
||||
hasMore = diffResult.hasMore;
|
||||
} while (hasMore);
|
||||
if (sortAsc) {
|
||||
sharedFiles.sort((a, b) => a.creationTime!.compareTo(b.creationTime!));
|
||||
}
|
||||
return sharedFiles;
|
||||
} catch (e, s) {
|
||||
Logger("getPublicFiles").severe("Failed to decrypt collection ", e, s);
|
||||
await showErrorDialog(
|
||||
context,
|
||||
S.of(context).somethingWentWrong,
|
||||
e.toString(),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@@ -44,8 +44,8 @@ import "package:photos/services/machine_learning/face_ml/person/person_service.d
|
||||
import "package:photos/services/memory_home_widget_service.dart";
|
||||
import "package:photos/services/notification_service.dart";
|
||||
import "package:photos/services/people_home_widget_service.dart";
|
||||
import "package:photos/services/sync/diff_fetcher.dart";
|
||||
import "package:photos/services/sync/remote_sync_service.dart";
|
||||
import "package:photos/services/sync/sync_public_collection.dart";
|
||||
import 'package:photos/states/user_details_state.dart';
|
||||
import 'package:photos/theme/colors.dart';
|
||||
import "package:photos/theme/effects.dart";
|
||||
@@ -120,8 +120,6 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||
late StreamSubscription<CollectionUpdatedEvent> _collectionUpdatedEvent;
|
||||
late StreamSubscription _publicAlbumLinkSubscription;
|
||||
|
||||
final DiffFetcher _diffFetcher = DiffFetcher();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_logger.info("Building initstate");
|
||||
@@ -337,8 +335,7 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||
if (result) {
|
||||
await dialog.show();
|
||||
|
||||
final List<EnteFile> sharedFiles =
|
||||
await _diffFetcher.getPublicFiles(
|
||||
final sharedFiles = await getPublicFiles(
|
||||
context,
|
||||
collection.id,
|
||||
collection.pubMagicMetadata.asc ?? false,
|
||||
@@ -369,7 +366,7 @@ class _HomeWidgetState extends State<HomeWidget> {
|
||||
} else {
|
||||
await dialog.show();
|
||||
|
||||
final List<EnteFile> sharedFiles = await _diffFetcher.getPublicFiles(
|
||||
final List<EnteFile> sharedFiles = await getPublicFiles(
|
||||
context,
|
||||
collection.id,
|
||||
collection.pubMagicMetadata.asc ?? false,
|
||||
|
||||
Reference in New Issue
Block a user