Prechádzať zdrojové kódy

Add diff fetcher for trashed files

Neeraj Gupta 3 rokov pred
rodič
commit
a5265b09af
2 zmenil súbory, kde vykonal 132 pridanie a 0 odobranie
  1. 16 0
      lib/models/trash_file.dart
  2. 116 0
      lib/utils/trash_diff_fetcher.dart

+ 16 - 0
lib/models/trash_file.dart

@@ -0,0 +1,16 @@
+import 'package:photos/models/file.dart';
+
+class Trash {
+  File file;
+
+  // time when file was put in the trash for first time
+  int createdAt;
+
+  // for non-deleted trash items, updateAt is usually equal to the latest time
+  // when the file was moved to trash
+  int updateAt;
+
+  // time after which will will be deleted from trash & user's storage usage
+  // will go down
+  int deleteBy;
+}

+ 116 - 0
lib/utils/trash_diff_fetcher.dart

@@ -0,0 +1,116 @@
+import 'dart:convert';
+
+import 'package:dio/dio.dart';
+import 'package:flutter_sodium/flutter_sodium.dart';
+import 'package:logging/logging.dart';
+import 'package:photos/core/configuration.dart';
+import 'package:photos/core/event_bus.dart';
+import 'package:photos/core/network.dart';
+import 'package:photos/db/files_db.dart';
+import 'package:photos/events/remote_sync_event.dart';
+import 'package:photos/models/file.dart';
+import 'package:photos/models/magic_metadata.dart';
+import 'package:photos/models/trash_file.dart';
+import 'package:photos/utils/crypto_util.dart';
+import 'package:photos/utils/file_download_util.dart';
+
+class TrashDiffFetcher {
+  final _logger = Logger("TrashDiffFetcher");
+  final _dio = Network.instance.getDio();
+
+  Future<Diff> getTrashFilesDiff(int sinceTime, int limit) async {
+    try {
+      final response = await _dio.get(
+        Configuration.instance.getHttpEndpoint() + "/trash/diff",
+        options: Options(
+            headers: {"X-Auth-Token": Configuration.instance.getToken()}),
+        queryParameters: {
+          "sinceTime": sinceTime,
+          "limit": limit,
+        },
+      );
+      final trashedFiles = <Trash>[];
+      final deletedFiles = <Trash>[];
+      final restoredFiles = <Trash>[];
+      if (response != null) {
+        Bus.instance.fire(RemoteSyncEvent(true));
+        final diff = response.data["diff"] as List;
+        final startTime = DateTime.now();
+        for (final item in diff) {
+          final trash = Trash();
+          trash.createdAt = item['createdAt'];
+          trash.updateAt = item['updatedAt'];
+          trash.deleteBy = item['deleteBy'];
+          trash.file = File();
+          trash.file.uploadedFileID = item["file"]["id"];
+          trash.file.collectionID = item["file"]["collectionID"];
+          trash.file.updationTime = item["file"]["updationTime"];
+          trash.file.ownerID = item["file"]["ownerID"];
+          trash.file.encryptedKey = item["file"]["encryptedKey"];
+          trash.file.keyDecryptionNonce = item["file"]["keyDecryptionNonce"];
+          trash.file.fileDecryptionHeader =
+              item["file"]["file"]["decryptionHeader"];
+          trash.file.thumbnailDecryptionHeader =
+              item["file"]["thumbnail"]["decryptionHeader"];
+          trash.file.metadataDecryptionHeader =
+              item["file"]["metadata"]["decryptionHeader"];
+          final fileDecryptionKey = decryptFileKey(trash.file);
+          final encodedMetadata = await CryptoUtil.decryptChaCha(
+            Sodium.base642bin(item["file"]["metadata"]["encryptedData"]),
+            fileDecryptionKey,
+            Sodium.base642bin(trash.file.metadataDecryptionHeader),
+          );
+          Map<String, dynamic> metadata =
+              jsonDecode(utf8.decode(encodedMetadata));
+          trash.file.applyMetadata(metadata);
+          if (item["file"]['magicMetadata'] != null) {
+            final utfEncodedMmd = await CryptoUtil.decryptChaCha(
+                Sodium.base642bin(item["file"]['magicMetadata']['data']),
+                fileDecryptionKey,
+                Sodium.base642bin(item["file"]['magicMetadata']['header']));
+            trash.file.mMdEncodedJson = utf8.decode(utfEncodedMmd);
+            trash.file.mMdVersion = item["file"]['magicMetadata']['version'];
+            trash.file.magicMetadata =
+                MagicMetadata.fromEncodedJson(trash.file.mMdEncodedJson);
+          }
+          if (item["isDeleted"]) {
+            deletedFiles.add(trash);
+            continue;
+          }
+          if (item['isRestored']) {
+            restoredFiles.add(trash);
+            continue;
+          }
+          trashedFiles.add(trash);
+        }
+
+        final endTime = DateTime.now();
+        _logger.info("time for parsing " +
+            diff.length.toString() +
+            ": " +
+            Duration(
+                    microseconds: (endTime.microsecondsSinceEpoch -
+                        startTime.microsecondsSinceEpoch))
+                .inMilliseconds
+                .toString());
+        return Diff(trashedFiles, restoredFiles, deletedFiles, diff.length);
+      } else {
+        Bus.instance.fire(RemoteSyncEvent(false));
+        return Diff(<Trash>[], <Trash>[], <Trash>[], 0);
+      }
+    } catch (e, s) {
+      _logger.severe(e, s);
+      rethrow;
+    }
+  }
+}
+
+class Diff {
+  final List<Trash> trashedFiles;
+  final List<Trash> restoredFiles;
+  final List<Trash> deletedFiles;
+  final int fetchCount;
+
+  Diff(this.trashedFiles, this.restoredFiles, this.deletedFiles,
+      this.fetchCount);
+}