Procházet zdrojové kódy

By default, only add to collection if file not already uploaded

Neeraj Gupta před 2 roky
rodič
revize
29a0ebad8e

+ 19 - 0
lib/db/files_db.dart

@@ -819,6 +819,25 @@ class FilesDB {
     return result;
     return result;
   }
   }
 
 
+  Future<Set<String>> getLocalIDsMarkedForOrAlreadyUploaded(int ownerID) async {
+    final db = await instance.database;
+    final rows = await db.query(
+      filesTable,
+      columns: [columnLocalID],
+      distinct: true,
+      where: '$columnLocalID IS NOT NULL AND ($columnCollectionID IS NOT NULL '
+          'AND '
+          '$columnCollectionID != -1) AND ($columnOwnerID = ? OR '
+          '$columnOwnerID IS NULL)',
+      whereArgs: [ownerID],
+    );
+    final result = <String>{};
+    for (final row in rows) {
+      result.add(row[columnLocalID]);
+    }
+    return result;
+  }
+
   Future<Set<String>> getLocalFileIDsForCollection(int collectionID) async {
   Future<Set<String>> getLocalFileIDsForCollection(int collectionID) async {
     final db = await instance.database;
     final db = await instance.database;
     final rows = await db.query(
     final rows = await db.query(

+ 3 - 0
lib/models/device_collection.dart

@@ -1,4 +1,5 @@
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
+import 'package:photos/models/upload_strategy.dart';
 
 
 class DeviceCollection {
 class DeviceCollection {
   final String id;
   final String id;
@@ -6,6 +7,7 @@ class DeviceCollection {
   final String coverId;
   final String coverId;
   final int count;
   final int count;
   final bool shouldBackup;
   final bool shouldBackup;
+  final UploadStrategy uploadStrategy;
   int collectionID;
   int collectionID;
   File thumbnail;
   File thumbnail;
 
 
@@ -17,5 +19,6 @@ class DeviceCollection {
     this.collectionID,
     this.collectionID,
     this.thumbnail,
     this.thumbnail,
     this.shouldBackup = false,
     this.shouldBackup = false,
+    this.uploadStrategy = UploadStrategy.ifMissing,
   });
   });
 }
 }

+ 30 - 0
lib/models/upload_strategy.dart

@@ -0,0 +1,30 @@
+enum UploadStrategy {
+  // uploader will only try to upload the file in a collection if the file is
+  // not already uploaded
+  ifMissing,
+  // alwaysUpload will always try to upload or add the file to given collection
+  always,
+  other,
+}
+
+int getInt(UploadStrategy uploadType) {
+  switch (uploadType) {
+    case UploadStrategy.ifMissing:
+      return 0;
+    case UploadStrategy.always:
+      return 1;
+    default:
+      return -1;
+  }
+}
+
+UploadStrategy getUploadType(int uploadType) {
+  switch (uploadType) {
+    case 0:
+      return UploadStrategy.ifMissing;
+    case 1:
+      return UploadStrategy.always;
+    default:
+      return UploadStrategy.other;
+  }
+}

+ 19 - 12
lib/services/remote_sync_service.dart

@@ -18,6 +18,7 @@ import 'package:photos/events/sync_status_update_event.dart';
 import 'package:photos/models/device_collection.dart';
 import 'package:photos/models/device_collection.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file.dart';
 import 'package:photos/models/file_type.dart';
 import 'package:photos/models/file_type.dart';
+import 'package:photos/models/upload_strategy.dart';
 import 'package:photos/services/app_lifecycle_service.dart';
 import 'package:photos/services/app_lifecycle_service.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/collections_service.dart';
 import 'package:photos/services/ignored_files_service.dart';
 import 'package:photos/services/ignored_files_service.dart';
@@ -231,6 +232,7 @@ class RemoteSyncService {
   }
   }
 
 
   Future<void> _syncDeviceCollectionFilesForUpload() async {
   Future<void> _syncDeviceCollectionFilesForUpload() async {
+    final int ownerID = Configuration.instance.getUserID();
     final FilesDB filesDB = FilesDB.instance;
     final FilesDB filesDB = FilesDB.instance;
     final deviceCollections = await filesDB.getDeviceCollections();
     final deviceCollections = await filesDB.getDeviceCollections();
     deviceCollections.removeWhere((element) => !element.shouldBackup);
     deviceCollections.removeWhere((element) => !element.shouldBackup);
@@ -243,12 +245,17 @@ class RemoteSyncService {
         await filesDB.getDevicePathIDToLocalIDMap();
         await filesDB.getDevicePathIDToLocalIDMap();
     for (final deviceCollection in deviceCollections) {
     for (final deviceCollection in deviceCollections) {
       _logger.fine("processing ${deviceCollection.name}");
       _logger.fine("processing ${deviceCollection.name}");
-      final Set<String> unSyncedLocalIDs =
+      final Set<String> localIDsToSync =
           pathIdToLocalIDs[deviceCollection.id] ?? {};
           pathIdToLocalIDs[deviceCollection.id] ?? {};
-      if (unSyncedLocalIDs.isNotEmpty && deviceCollection.collectionID != -1) {
+      if (deviceCollection.uploadStrategy == UploadStrategy.ifMissing) {
+        final Set<String> alreadyClaimedLocalIDs =
+            await filesDB.getLocalIDsMarkedForOrAlreadyUploaded(ownerID);
+        localIDsToSync.removeAll(alreadyClaimedLocalIDs);
+      }
+      if (localIDsToSync.isNotEmpty && deviceCollection.collectionID != -1) {
         await filesDB.setCollectionIDForUnMappedLocalFiles(
         await filesDB.setCollectionIDForUnMappedLocalFiles(
           deviceCollection.collectionID,
           deviceCollection.collectionID,
-          unSyncedLocalIDs,
+          localIDsToSync,
         );
         );
 
 
         // mark IDs as already synced if corresponding entry is present in
         // mark IDs as already synced if corresponding entry is present in
@@ -257,25 +264,25 @@ class RemoteSyncService {
         final Set<String> existingMapping = await filesDB
         final Set<String> existingMapping = await filesDB
             .getLocalFileIDsForCollection(deviceCollection.collectionID);
             .getLocalFileIDsForCollection(deviceCollection.collectionID);
         final Set<String> commonElements =
         final Set<String> commonElements =
-            unSyncedLocalIDs.intersection(existingMapping);
+            localIDsToSync.intersection(existingMapping);
         if (commonElements.isNotEmpty) {
         if (commonElements.isNotEmpty) {
           debugPrint(
           debugPrint(
             "${commonElements.length} files already existing in "
             "${commonElements.length} files already existing in "
             "collection ${deviceCollection.collectionID} for ${deviceCollection.name}",
             "collection ${deviceCollection.collectionID} for ${deviceCollection.name}",
           );
           );
-          unSyncedLocalIDs.removeAll(commonElements);
+          localIDsToSync.removeAll(commonElements);
         }
         }
 
 
-        // At this point, the remaining unSyncedLocalIDs will need to create
+        // At this point, the remaining localIDsToSync will need to create
         // new file entries, where we can store mapping for localID and
         // new file entries, where we can store mapping for localID and
         // corresponding collection ID
         // corresponding collection ID
-        if (unSyncedLocalIDs.isNotEmpty) {
+        if (localIDsToSync.isNotEmpty) {
           debugPrint(
           debugPrint(
-            'Adding new entries for ${unSyncedLocalIDs.length} files'
+            'Adding new entries for ${localIDsToSync.length} files'
             ' for ${deviceCollection.name}',
             ' for ${deviceCollection.name}',
           );
           );
           final filesWithCollectionID =
           final filesWithCollectionID =
-              await filesDB.getLocalFiles(unSyncedLocalIDs.toList());
+              await filesDB.getLocalFiles(localIDsToSync.toList());
           final List<File> newFilesToInsert = [];
           final List<File> newFilesToInsert = [];
           final Set<String> fileFoundForLocalIDs = {};
           final Set<String> fileFoundForLocalIDs = {};
           for (var existingFile in filesWithCollectionID) {
           for (var existingFile in filesWithCollectionID) {
@@ -290,13 +297,13 @@ class RemoteSyncService {
             }
             }
           }
           }
           await filesDB.insertMultiple(newFilesToInsert);
           await filesDB.insertMultiple(newFilesToInsert);
-          unSyncedLocalIDs.removeAll(fileFoundForLocalIDs);
+          localIDsToSync.removeAll(fileFoundForLocalIDs);
         }
         }
 
 
-        if (unSyncedLocalIDs.isNotEmpty) {
+        if (localIDsToSync.isNotEmpty) {
           _logger.warning(
           _logger.warning(
             "All localIDs should be synced, missed for "
             "All localIDs should be synced, missed for "
-            "${unSyncedLocalIDs.length}",
+            "${localIDsToSync.length}",
           );
           );
         }
         }
       }
       }