[tracker-miners/sam/index-file-sync: 8/11] miners: Add FileProcessed signal



commit a2e721ba45834bc66c555624524622a81eaa89ac
Author: Sam Thursfield <sam afuera me uk>
Date:   Tue Feb 25 01:08:19 2020 +0100

    miners: Add FileProcessed signal
    
    This new signal provides more detailed status info from miners, so that
    CLI and apps can show the status and reuslts of processing specific files.
    
    The miner-fs ::finished-root signal is removed as it's apparently
    unused, and it overlaps with this one.

 src/libtracker-miner/tracker-decorator.c    | 23 +++++++++
 src/libtracker-miner/tracker-miner-fs.c     | 72 ++++++++++-------------------
 src/libtracker-miner/tracker-miner-fs.h     |  8 ----
 src/libtracker-miner/tracker-miner-object.c | 46 ++++++++++++++++++
 src/libtracker-miner/tracker-miner-object.h | 10 ++++
 src/libtracker-miner/tracker-miner-proxy.c  | 21 +++++++++
 6 files changed, 125 insertions(+), 55 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-decorator.c b/src/libtracker-miner/tracker-decorator.c
index eecfd2a17..7be149986 100644
--- a/src/libtracker-miner/tracker-decorator.c
+++ b/src/libtracker-miner/tracker-decorator.c
@@ -64,6 +64,7 @@ struct _ClassInfo {
 struct _SparqlUpdate {
        gchar *sparql;
        gint id;
+       GFile *file;
 };
 
 struct _TrackerDecoratorPrivate {
@@ -354,9 +355,20 @@ decorator_commit_cb (GObject      *object,
                        SparqlUpdate *update;
 
                        update = &g_array_index (priv->commit_buffer, SparqlUpdate, i);
+
+                       tracker_miner_file_processed (TRACKER_MINER (decorator), update->file, FALSE, 
error->message);
                        decorator_blacklist_add (decorator, update->id);
                        item_warn (conn, update->id, update->sparql, error);
                }
+       } else {
+               /* Notify success */
+               for (i = 0; i < priv->commit_buffer->len; i++) {
+                       SparqlUpdate *update;
+
+                       update = &g_array_index (priv->commit_buffer, SparqlUpdate, i);
+
+                       tracker_miner_file_processed (TRACKER_MINER (decorator), update->file, TRUE, "");
+               }
        }
 
        g_clear_pointer (&priv->commit_buffer, g_array_unref);
@@ -369,6 +381,7 @@ static void
 sparql_update_clear (SparqlUpdate *update)
 {
        g_free (update->sparql);
+       g_object_unref (update->file);
 }
 
 static GArray *
@@ -517,26 +530,36 @@ decorator_task_done (GObject      *object,
        TrackerDecoratorInfo *info = user_data;
        TrackerDecoratorPrivate *priv;
        GError *error = NULL;
+       GFile *file;
        gchar *sparql;
 
        priv = decorator->priv;
        sparql = g_task_propagate_pointer (G_TASK (result), &error);
 
        if (!sparql) {
+               file = g_file_new_for_uri (info->url);
+
                /* Blacklist item */
                decorator_blacklist_add (decorator, info->id);
 
                if (error) {
+                       tracker_miner_file_processed (TRACKER_MINER (object), file, FALSE, error->message);
+
                        g_warning ("Task for '%s' finished with error: %s\n",
                                   info->url, error->message);
                        g_error_free (error);
+               } else {
+                       tracker_miner_file_processed (TRACKER_MINER (object), file, FALSE, "no SPARQL was 
generated for this item");
                }
+
+               g_object_unref (file);
        } else {
                SparqlUpdate update;
 
                /* Add resulting sparql to buffer and check whether flushing */
                update.sparql = sparql;
                update.id = info->id;
+               update.file = g_file_new_for_uri (info->url);
 
                if (!priv->sparql_buffer)
                        priv->sparql_buffer = sparql_buffer_new ();
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index c0abde854..68ac0c036 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -202,7 +202,6 @@ enum {
        PROCESS_FILE,
        PROCESS_FILE_ATTRIBUTES,
        FINISHED,
-       FINISHED_ROOT,
        REMOVE_FILE,
        REMOVE_CHILDREN,
        MOVE_FILE,
@@ -453,31 +452,6 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
                              G_TYPE_UINT,
                              G_TYPE_UINT);
 
-       /**
-        * TrackerMinerFS::finished-root:
-        * @miner_fs: the #TrackerMinerFS
-        * @file: a #GFile
-        *
-        * The ::finished-crawl signal is emitted when @miner_fs has
-        * finished finding all resources that need to be indexed
-        * with the root location of @file. At this point, it's likely
-        * many are still in the queue to be added to the database,
-        * but this gives some indication that a location is
-        * processed.
-        *
-        * Since: 1.2
-        **/
-       signals[FINISHED_ROOT] =
-               g_signal_new ("finished-root",
-                             G_TYPE_FROM_CLASS (object_class),
-                             G_SIGNAL_RUN_LAST,
-                             G_STRUCT_OFFSET (TrackerMinerFSClass, finished_root),
-                             NULL, NULL,
-                             NULL,
-                             G_TYPE_NONE,
-                             1,
-                             G_TYPE_FILE);
-
        /**
         * TrackerMinerFS::remove-file:
         * @miner_fs: the #TrackerMinerFS
@@ -1042,12 +1016,10 @@ notify_roots_finished (TrackerMinerFS *fs,
        if (check_queues &&
            fs->priv->roots_to_notify &&
            g_hash_table_size (fs->priv->roots_to_notify) < 2) {
-               /* Technically, if there is only one root, it's
-                * pointless to do anything before the FINISHED (not
-                * FINISHED_ROOT) signal is emitted. In that
-                * situation we calls function first anyway with
-                * check_queues=FALSE so we still notify roots. This
-                * is really just for efficiency.
+               /* Technically, if there is only one root, it's pointless to do
+                * anything before the FINISHED signal is emitted. In that situation we
+                * calls function first anyway with check_queues=FALSE so we still
+                * notify roots. This is really just for efficiency.
                 */
                return;
        } else if (fs->priv->roots_to_notify == NULL ||
@@ -1070,8 +1042,8 @@ notify_roots_finished (TrackerMinerFS *fs,
                        continue;
                }
 
-               /* Signal root is finished */
-               g_signal_emit (fs, signals[FINISHED_ROOT], 0, root);
+               /* Notify completion of the index root */
+               tracker_miner_file_processed (TRACKER_MINER (fs), root, TRUE, NULL);
 
                /* Remove from hash table */
                g_hash_table_iter_remove (&iter);
@@ -1183,14 +1155,15 @@ sparql_buffer_task_finished_cb (GObject      *object,
        task = tracker_sparql_buffer_push_finish (TRACKER_SPARQL_BUFFER (object),
                                                  result, &error);
 
+       task_file = tracker_task_get_file (task);
+
        if (error) {
                g_critical ("Could not execute sparql: %s", error->message);
+               tracker_miner_file_processed (TRACKER_MINER (fs), task_file, FALSE, error->message);
                priv->total_files_notified_error++;
                g_error_free (error);
        }
 
-       task_file = tracker_task_get_file (task);
-
        recursive = GPOINTER_TO_INT (g_object_steal_qdata (G_OBJECT (task_file),
                                                             priv->quark_recursive_removal));
        tracker_file_notifier_invalidate_file_iri (priv->file_notifier, task_file, recursive);
@@ -1212,6 +1185,14 @@ sparql_buffer_task_finished_cb (GObject      *object,
                item_queue_handlers_set_up (fs);
        }
 
+       /* Notify completion unless this the root, in which case we wait til
+        * notify_roots_finished() so we know we already notified for all its
+        * children.
+        */
+       if (! tracker_indexing_tree_file_is_root (priv->indexing_tree, task_file)) {
+               tracker_miner_file_processed (TRACKER_MINER (fs), task_file, TRUE, NULL);
+       }
+
        tracker_task_unref (task);
 }
 
@@ -1269,7 +1250,7 @@ on_signal_gtask_complete (GObject      *source,
        uri = g_file_get_uri (file);
 
        if (error) {
-               g_message ("Could not process '%s': %s", uri, error->message);
+               tracker_miner_file_processed (TRACKER_MINER (fs), file, FALSE, error->message);
                g_error_free (error);
 
                fs->priv->total_files_notified_error++;
@@ -2244,7 +2225,7 @@ file_notifier_directory_finished (TrackerFileNotifier *notifier,
        if (directories_found == 0 &&
            files_found == 0) {
                /* Signal now because we have nothing to index */
-               g_signal_emit (fs, signals[FINISHED_ROOT], 0, directory);
+               tracker_miner_file_processed (TRACKER_MINER (fs), directory, TRUE, NULL);
        } else {
                /* Add root to list we want to be notified about when
                 * finished indexing! */
@@ -2383,7 +2364,6 @@ tracker_miner_fs_check_file (TrackerMinerFS *fs,
 {
        gboolean should_process = TRUE;
        QueueEvent *event;
-       gchar *uri;
 
        g_return_if_fail (TRACKER_IS_MINER_FS (fs));
        g_return_if_fail (G_IS_FILE (file));
@@ -2392,14 +2372,11 @@ tracker_miner_fs_check_file (TrackerMinerFS *fs,
                should_process = should_check_file (fs, file, FALSE);
        }
 
-       uri = g_file_get_uri (file);
-
-       g_debug ("%s:'%s' (FILE) (requested by application)",
-                should_process ? "Found " : "Ignored",
-                uri);
-
        if (should_process) {
                if (check_parents && !check_file_parents (fs, file)) {
+                       tracker_miner_file_processed (TRACKER_MINER (fs), file, FALSE,
+                                                     "parent directory not eligible for indexing");
+
                        return;
                }
 
@@ -2409,9 +2386,10 @@ tracker_miner_fs_check_file (TrackerMinerFS *fs,
                event = queue_event_new (TRACKER_MINER_FS_EVENT_UPDATED, file);
                trace_eq_event (event);
                miner_fs_queue_event (fs, event, priority);
+       } else {
+               tracker_miner_file_processed (TRACKER_MINER (file), file, FALSE,
+                                             "file is ignored by configuration");
        }
-
-       g_free (uri);
 }
 
 /**
diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h
index 871b20375..60a18310f 100644
--- a/src/libtracker-miner/tracker-miner-fs.h
+++ b/src/libtracker-miner/tracker-miner-fs.h
@@ -78,8 +78,6 @@ struct _TrackerMinerFS {
  * @finished: Called when all processing has been performed.
  * @process_file_attributes: Called when the metadata associated with
  * a file's attributes changes, for example, the mtime.
- * @finished_root: Called when all resources on a particular root URI
- * have been processed.
  * @remove_file: Called when a file is removed.
  * @remove_children: Called when children have been removed.
  * @move_file: Called when a file has moved.
@@ -104,12 +102,6 @@ typedef struct {
        gboolean (* process_file_attributes)  (TrackerMinerFS       *fs,
                                               GFile                *file,
                                               GTask                *task);
-       void     (* finished_root)            (TrackerMinerFS       *fs,
-                                              GFile                *root,
-                                              gint                  directories_found,
-                                              gint                  directories_ignored,
-                                              gint                  files_found,
-                                              gint                  files_ignored);
        gchar *  (* remove_file)              (TrackerMinerFS       *fs,
                                               GFile                *file);
        gchar *  (* remove_children)          (TrackerMinerFS       *fs,
diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c
index a4c79f8b4..5c6e0330c 100644
--- a/src/libtracker-miner/tracker-miner-object.c
+++ b/src/libtracker-miner/tracker-miner-object.c
@@ -84,6 +84,7 @@ enum {
        PAUSED,
        RESUMED,
        PROGRESS,
+       FILE_PROCESSED,
        LAST_SIGNAL
 };
 
@@ -231,6 +232,32 @@ tracker_miner_class_init (TrackerMinerClass *klass)
                              G_TYPE_DOUBLE,
                              G_TYPE_INT);
 
+       /**
+        * TrackerMiner::file-processed:
+        * @miner: the #TrackerMiner
+        * @uri: URI of the file that was processed
+        * @status: %FALSE if there was a problem processing this file, %TRUE otherwise
+        * @error: a #GError detailing the error, if any
+        *
+        * each time a file is processed, this signal is emitted and gives status
+        * information. It is useful for notifying the user of any error that
+        * occurred processing a given file. Use of #TrackerNotifier instead if you
+        * want the metadata from the file, not the status info.
+        *
+        * Since: 3.0
+        **/
+       signals[FILE_PROCESSED] =
+               g_signal_new ("file-processed",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (TrackerMinerClass, file_processed),
+                             NULL, NULL,
+                             NULL,
+                             G_TYPE_NONE, 3,
+                             G_TYPE_STRING,
+                             G_TYPE_BOOLEAN,
+                             G_TYPE_STRING);
+
        g_object_class_install_property (object_class,
                                         PROP_STATUS,
                                         g_param_spec_string ("status",
@@ -624,6 +651,25 @@ tracker_miner_get_connection (TrackerMiner *miner)
        return miner->priv->connection;
 }
 
+void
+tracker_miner_file_processed (TrackerMiner *miner,
+                              GFile        *file,
+                              gboolean      success,
+                              const gchar  *message)
+{
+       gchar *uri;
+
+       g_return_if_fail (G_IS_FILE (file));
+
+       uri = g_file_get_uri (file);
+
+       g_message ("File %s: success %i, message: %s", uri, success, message);
+
+       g_signal_emit (miner, signals[FILE_PROCESSED], 0, uri, success, message);
+
+       g_free (uri);
+}
+
 static void
 miner_finalize (GObject *object)
 {
diff --git a/src/libtracker-miner/tracker-miner-object.h b/src/libtracker-miner/tracker-miner-object.h
index 62513061b..6694d75ca 100644
--- a/src/libtracker-miner/tracker-miner-object.h
+++ b/src/libtracker-miner/tracker-miner-object.h
@@ -132,6 +132,11 @@ typedef struct {
                                     gdouble       progress,
                                     gint          remaining_time);
 
+       void (* file_processed)     (TrackerMiner *miner,
+                                    const gchar  *uri,
+                                    gboolean      status,
+                                    GError       *error);
+
        /* <Private> */
        gpointer padding[10];
 } TrackerMinerClass;
@@ -180,6 +185,11 @@ gboolean                 tracker_miner_resume              (TrackerMiner
 
 TrackerSparqlConnection *tracker_miner_get_connection      (TrackerMiner         *miner);
 
+void                     tracker_miner_file_processed      (TrackerMiner         *miner,
+                                                            GFile                *file,
+                                                            gboolean              success,
+                                                            const gchar          *message);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_MINER_OBJECT_H__ */
diff --git a/src/libtracker-miner/tracker-miner-proxy.c b/src/libtracker-miner/tracker-miner-proxy.c
index e599ef64c..7e57f1267 100644
--- a/src/libtracker-miner/tracker-miner-proxy.c
+++ b/src/libtracker-miner/tracker-miner-proxy.c
@@ -115,6 +115,11 @@ static const gchar introspection_xml[] =
   "      <arg type='d' name='progress' />"
   "      <arg type='i' name='remaining_time' />"
   "    </signal>"
+  "    <signal name='FileProcessed'>"
+  "      <arg type='s' name='uri' />"
+  "      <arg type='b' name='success' />"
+  "      <arg type='s' name='error' />"
+  "    </signal>"
   "  </interface>"
   "</node>";
 
@@ -729,6 +734,20 @@ miner_progress_cb (TrackerMiner      *miner,
        emit_dbus_signal (proxy, "Progress", variant);
 }
 
+static void
+miner_file_processed_cb (TrackerMiner      *miner,
+                         const gchar       *uri,
+                         gboolean           success,
+                         const gchar       *message,
+                         TrackerMinerProxy *proxy)
+{
+       GVariant *variant;
+
+       variant = g_variant_new ("(sbs)", uri, success, message ? message : "");
+       /* variant reference is sunk here */
+       emit_dbus_signal (proxy, "FileProcessed", variant);
+}
+
 static gboolean
 tracker_miner_proxy_initable_init (GInitable     *initable,
                                    GCancellable  *cancellable,
@@ -773,6 +792,8 @@ tracker_miner_proxy_initable_init (GInitable     *initable,
                          G_CALLBACK (miner_resumed_cb), proxy);
        g_signal_connect (priv->miner, "progress",
                          G_CALLBACK (miner_progress_cb), proxy);
+       g_signal_connect (priv->miner, "file-processed",
+                         G_CALLBACK (miner_file_processed_cb), proxy);
 
        return TRUE;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]