Browse Source

[mob] Option for indexing without fetching

laurenspriem 1 year ago
parent
commit
01914ed3ce

+ 39 - 35
mobile/lib/services/machine_learning/face_ml/face_ml_service.dart

@@ -514,7 +514,7 @@ class FaceMlService {
   /// Analyzes all the images in the database with the latest ml version and stores the results in the database.
   ///
   /// This function first checks if the image has already been analyzed with the lastest faceMlVersion and stored in the database. If so, it skips the image.
-  Future<void> indexAllImages() async {
+  Future<void> indexAllImages({withFetching = true}) async {
     if (isImageIndexRunning) {
       _logger.warning("indexAllImages is already running, skipping");
       return;
@@ -566,44 +566,48 @@ class FaceMlService {
         for (final f in chunk) {
           fileIds.add(f.uploadedFileID!);
         }
-        try {
-          final EnteWatch? w = kDebugMode ? EnteWatch("face_em_fetch") : null;
-          w?.start();
-          w?.log('starting remote fetch for ${fileIds.length} files');
-          final res =
-              await RemoteFileMLService.instance.getFilessEmbedding(fileIds);
-          w?.logAndReset('fetched ${res.mlData.length} embeddings');
-          final List<Face> faces = [];
-          final remoteFileIdToVersion = <int, int>{};
-          for (FileMl fileMl in res.mlData.values) {
-            if (shouldDiscardRemoteEmbedding(fileMl)) continue;
-            if (fileMl.faceEmbedding.faces.isEmpty) {
-              faces.add(
-                Face.empty(
-                  fileMl.fileID,
-                  error: (fileMl.faceEmbedding.error ?? false),
-                ),
-              );
-            } else {
-              for (final f in fileMl.faceEmbedding.faces) {
-                f.fileInfo = FileInfo(
-                  imageHeight: fileMl.height,
-                  imageWidth: fileMl.width,
+        if (withFetching) {
+          try {
+            final EnteWatch? w = kDebugMode ? EnteWatch("face_em_fetch") : null;
+            w?.start();
+            w?.log('starting remote fetch for ${fileIds.length} files');
+            final res =
+                await RemoteFileMLService.instance.getFilessEmbedding(fileIds);
+            w?.logAndReset('fetched ${res.mlData.length} embeddings');
+            final List<Face> faces = [];
+            final remoteFileIdToVersion = <int, int>{};
+            for (FileMl fileMl in res.mlData.values) {
+              if (shouldDiscardRemoteEmbedding(fileMl)) continue;
+              if (fileMl.faceEmbedding.faces.isEmpty) {
+                faces.add(
+                  Face.empty(
+                    fileMl.fileID,
+                    error: (fileMl.faceEmbedding.error ?? false),
+                  ),
                 );
-                faces.add(f);
+              } else {
+                for (final f in fileMl.faceEmbedding.faces) {
+                  f.fileInfo = FileInfo(
+                    imageHeight: fileMl.height,
+                    imageWidth: fileMl.width,
+                  );
+                  faces.add(f);
+                }
               }
+              remoteFileIdToVersion[fileMl.fileID] =
+                  fileMl.faceEmbedding.version;
             }
-            remoteFileIdToVersion[fileMl.fileID] = fileMl.faceEmbedding.version;
-          }
-          await FaceMLDataDB.instance.bulkInsertFaces(faces);
-          w?.logAndReset('stored embeddings');
-          for (final entry in remoteFileIdToVersion.entries) {
-            alreadyIndexedFiles[entry.key] = entry.value;
+            await FaceMLDataDB.instance.bulkInsertFaces(faces);
+            w?.logAndReset('stored embeddings');
+            for (final entry in remoteFileIdToVersion.entries) {
+              alreadyIndexedFiles[entry.key] = entry.value;
+            }
+            _logger
+                .info('already indexed files ${remoteFileIdToVersion.length}');
+          } catch (e, s) {
+            _logger.severe("err while getting files embeddings", e, s);
+            rethrow;
           }
-          _logger.info('already indexed files ${remoteFileIdToVersion.length}');
-        } catch (e, s) {
-          _logger.severe("err while getting files embeddings", e, s);
-          rethrow;
         }
 
         for (final enteFile in chunk) {

+ 38 - 1
mobile/lib/ui/settings/debug/face_debug_section_widget.dart

@@ -65,7 +65,7 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
               if (snapshot.hasData) {
                 return CaptionedTextWidget(
                   title: LocalSettings.instance.isFaceIndexingEnabled
-                      ? "Disable Indexing (${snapshot.data!.length})"
+                      ? "Disable indexing (${snapshot.data!.length})"
                       : "Enable indexing (${snapshot.data!.length})",
                 );
               }
@@ -93,6 +93,43 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
             }
           },
         ),
+        MenuItemWidget(
+          captionedTextWidget: FutureBuilder<Map<int, int>>(
+            future: FaceMLDataDB.instance.getIndexedFileIds(),
+            builder: (context, snapshot) {
+              if (snapshot.hasData) {
+                return CaptionedTextWidget(
+                  title: LocalSettings.instance.isFaceIndexingEnabled
+                      ? "Disable indexing (no fetch) (${snapshot.data!.length})"
+                      : "Enable indexing (${snapshot.data!.length})",
+                );
+              }
+              return const SizedBox.shrink();
+            },
+          ),
+          pressedColor: getEnteColorScheme(context).fillFaint,
+          trailingIcon: Icons.chevron_right_outlined,
+          trailingIconIsMuted: true,
+          onTap: () async {
+            try {
+              final isEnabled =
+                  await LocalSettings.instance.toggleFaceIndexing();
+              if (isEnabled) {
+                FaceMlService.instance
+                    .indexAllImages(withFetching: false)
+                    .ignore();
+              } else {
+                FaceMlService.instance.pauseIndexing();
+              }
+              if (mounted) {
+                setState(() {});
+              }
+            } catch (e, s) {
+              _logger.warning('indexing failed ', e, s);
+              await showGenericErrorDialog(context: context, error: e);
+            }
+          },
+        ),
         MenuItemWidget(
           captionedTextWidget: FutureBuilder<int>(
             future: FaceMLDataDB.instance.getTotalFaceCount(),