file_downloader.dart 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import 'dart:convert';
  2. import 'package:dio/dio.dart';
  3. import 'package:flutter_sodium/flutter_sodium.dart';
  4. import 'package:logging/logging.dart';
  5. import 'package:photos/core/configuration.dart';
  6. import 'package:photos/core/event_bus.dart';
  7. import 'package:photos/core/network.dart';
  8. import 'package:photos/db/files_db.dart';
  9. import 'package:photos/events/collection_updated_event.dart';
  10. import 'package:photos/events/remote_sync_event.dart';
  11. import 'package:photos/models/file.dart';
  12. import 'package:photos/utils/crypto_util.dart';
  13. import 'package:photos/utils/file_util.dart';
  14. class DiffFetcher {
  15. final _logger = Logger("FileDownloader");
  16. final _dio = Network.instance.getDio();
  17. Future<List<File>> getEncryptedFilesDiff(
  18. int collectionID, int sinceTime, int limit) async {
  19. return _dio
  20. .get(
  21. Configuration.instance.getHttpEndpoint() + "/collections/diff",
  22. options: Options(
  23. headers: {"X-Auth-Token": Configuration.instance.getToken()}),
  24. queryParameters: {
  25. "collectionID": collectionID,
  26. "sinceTime": sinceTime,
  27. "limit": limit,
  28. },
  29. )
  30. .catchError((e) => _logger.severe(e))
  31. .then((response) async {
  32. final files = List<File>();
  33. if (response != null) {
  34. Bus.instance.fire(RemoteSyncEvent(true));
  35. final diff = response.data["diff"] as List;
  36. for (final item in diff) {
  37. final file = File();
  38. file.uploadedFileID = item["id"];
  39. file.collectionID = item["collectionID"];
  40. if (item["isDeleted"]) {
  41. await FilesDB.instance.deleteFromCollection(
  42. file.uploadedFileID, file.collectionID);
  43. Bus.instance.fire(
  44. CollectionUpdatedEvent(collectionID: file.collectionID));
  45. continue;
  46. }
  47. file.updationTime = item["updationTime"];
  48. final existingFile = await FilesDB.instance
  49. .getUploadedFile(file.uploadedFileID, file.collectionID);
  50. if (existingFile.updationTime == file.updationTime) {
  51. continue;
  52. }
  53. file.ownerID = item["ownerID"];
  54. file.isEncrypted = true;
  55. file.encryptedKey = item["encryptedKey"];
  56. file.keyDecryptionNonce = item["keyDecryptionNonce"];
  57. file.fileDecryptionHeader = item["file"]["decryptionHeader"];
  58. file.thumbnailDecryptionHeader =
  59. item["thumbnail"]["decryptionHeader"];
  60. file.metadataDecryptionHeader =
  61. item["metadata"]["decryptionHeader"];
  62. final encodedMetadata = CryptoUtil.decryptChaCha(
  63. Sodium.base642bin(item["metadata"]["encryptedData"]),
  64. decryptFileKey(file),
  65. Sodium.base642bin(file.metadataDecryptionHeader),
  66. );
  67. Map<String, dynamic> metadata =
  68. jsonDecode(utf8.decode(encodedMetadata));
  69. file.applyMetadata(metadata);
  70. files.add(file);
  71. }
  72. } else {
  73. Bus.instance.fire(RemoteSyncEvent(false));
  74. }
  75. return files;
  76. });
  77. }
  78. }