[tracker/miner-fs-remaining-time: 2/2] tracker-control: Report miner's processing remaining time in --follow



commit 099e33a35f81b86097940a20a924cb4b56d69b27
Author: Aleksander Morgado <aleksander lanedo com>
Date:   Thu Mar 24 15:40:12 2011 +0100

    tracker-control: Report miner's processing remaining time in --follow
    
    Note that this commit breaks TrackerMinerManager API w.r.t 0.10
    
    Fixes GB#611471

 data/dbus/tracker-miner.xml                   |    4 +
 src/libtracker-common/tracker-utils.c         |   46 +++++----
 src/libtracker-common/tracker-utils.h         |    5 +-
 src/libtracker-miner/tracker-marshal.list     |    4 +-
 src/libtracker-miner/tracker-miner-fs.c       |   21 ++++-
 src/libtracker-miner/tracker-miner-manager.c  |  132 +++++++++++++++---------
 src/libtracker-miner/tracker-miner-manager.h  |    3 +-
 src/libtracker-miner/tracker-miner-object.c   |   77 ++++++++++++--
 src/tracker-control/tracker-control-general.c |    7 +-
 src/tracker-control/tracker-control-status.c  |   75 ++++++++++-----
 10 files changed, 263 insertions(+), 111 deletions(-)
---
diff --git a/data/dbus/tracker-miner.xml b/data/dbus/tracker-miner.xml
index a6b521a..901943f 100644
--- a/data/dbus/tracker-miner.xml
+++ b/data/dbus/tracker-miner.xml
@@ -11,6 +11,10 @@
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="d" name="progress" direction="out" />
     </method>
+    <method name="GetRemainingTime">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="i" name="remaining_time" direction="out" />
+    </method>
     <method name="GetPauseDetails">
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="as" name="pause_applications" direction="out" />
diff --git a/src/libtracker-common/tracker-utils.c b/src/libtracker-common/tracker-utils.c
index 8051662..a9b3612 100644
--- a/src/libtracker-common/tracker-utils.c
+++ b/src/libtracker-common/tracker-utils.c
@@ -57,29 +57,39 @@ tracker_is_blank_string (const char *str)
 	return TRUE;
 }
 
+guint
+tracker_seconds_estimate (gdouble seconds_elapsed,
+                          guint   items_done,
+                          guint   items_remaining)
+{
+	/* Return 0 if unknown */
+	if (seconds_elapsed <= 0 ||
+	    items_done < 1 ||
+	    items_remaining < 1) {
+		return 0;
+	}
+
+	/* A estimate is an estimate, and full seconds is probably
+	 * more correct than a floating point value... */
+	return (guint)((seconds_elapsed / items_done) * items_remaining);
+}
+
 gchar *
-tracker_seconds_estimate_to_string (gdouble  seconds_elapsed,
-                                    gboolean short_string,
-                                    guint    items_done,
-                                    guint    items_remaining)
+tracker_seconds_estimate_to_string (gdouble   seconds_elapsed,
+                                    gboolean  short_string,
+                                    guint     items_done,
+                                    guint     items_remaining)
 {
-	gdouble per_item;
-	gdouble total;
+	guint estimate;
 
-	g_return_val_if_fail (seconds_elapsed >= 0.0, g_strdup (_("unknown time")));
+	estimate = tracker_seconds_estimate (seconds_elapsed,
+	                                     items_done,
+	                                     items_remaining);
 
-	/* We don't want division by 0 or if total is 0 because items
-	 * remaining is 0 then, equally pointless.
-	 */
-	if (items_done < 1 ||
-	    items_remaining < 1) {
+	if (estimate == 0)
 		return g_strdup (_("unknown time"));
-	}
-
-	per_item = seconds_elapsed / items_done;
-	total = per_item * items_remaining;
 
-	return tracker_seconds_to_string (total, short_string);
+	return tracker_seconds_to_string (estimate, short_string);
 }
 
 gchar *
@@ -93,7 +103,7 @@ tracker_seconds_to_string (gdouble  seconds_elapsed,
 
 	g_return_val_if_fail (seconds_elapsed >= 0.0, g_strdup (_("less than one second")));
 
-	total    = seconds_elapsed;
+	total = seconds_elapsed;
 
 	seconds  = (gint) total % 60;
 	total   /= 60;
diff --git a/src/libtracker-common/tracker-utils.h b/src/libtracker-common/tracker-utils.h
index 2112100..035be96 100644
--- a/src/libtracker-common/tracker-utils.h
+++ b/src/libtracker-common/tracker-utils.h
@@ -31,11 +31,14 @@ G_BEGIN_DECLS
 
 gboolean tracker_is_empty_string            (const char   *str);
 gboolean tracker_is_blank_string            (const char   *str);
+guint    tracker_seconds_estimate           (gdouble       seconds_elapsed,
+                                             guint         items_done,
+                                             guint         items_remaining);
 gchar *  tracker_seconds_estimate_to_string (gdouble       seconds_elapsed,
                                              gboolean      short_string,
                                              guint         items_done,
                                              guint         items_remaining);
-gchar *  tracker_seconds_to_string          (gdouble       seconds_elapsed,
+gchar *  tracker_seconds_to_string          (gdouble       seconds,
                                              gboolean      short_string);
 gchar *  tracker_strhex                     (const guint8 *data,
                                              gsize         size,
diff --git a/src/libtracker-miner/tracker-marshal.list b/src/libtracker-miner/tracker-marshal.list
index 28f8e4a..eb7e526 100644
--- a/src/libtracker-miner/tracker-marshal.list
+++ b/src/libtracker-miner/tracker-marshal.list
@@ -2,9 +2,9 @@ VOID:OBJECT,BOOLEAN
 VOID:OBJECT,OBJECT,BOOLEAN,BOOLEAN
 VOID:OBJECT,POINTER,UINT,UINT,UINT,UINT
 VOID:DOUBLE,UINT,UINT,UINT,UINT
-VOID:STRING,DOUBLE
+VOID:STRING,DOUBLE,INT
 VOID:STRING,STRING
-VOID:STRING,STRING,DOUBLE
+VOID:STRING,STRING,DOUBLE,INT
 VOID:STRING,STRING,BOOLEAN,BOOLEAN
 VOID:STRING,STRING,STRING,BOOLEAN,BOOLEAN
 BOOL:OBJECT,OBJECT,OBJECT
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index 33453df..5d9ec79 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -900,6 +900,7 @@ miner_started (TrackerMiner *miner)
 	g_object_set (miner,
 	              "progress", 0.0,
 	              "status", "Initializing",
+	              "remaining-time", 0,
 	              NULL);
 
 	crawl_directories_start (fs);
@@ -913,6 +914,7 @@ miner_stopped (TrackerMiner *miner)
 	g_object_set (miner,
 	              "progress", 1.0,
 	              "status", "Idle",
+	              "remaining-time", -1,
 	              NULL);
 }
 
@@ -1049,6 +1051,7 @@ process_stop (TrackerMinerFS *fs)
 	g_object_set (fs,
 	              "progress", 1.0,
 	              "status", "Idle",
+	              "remaining-time", 0,
 	              NULL);
 
 	g_signal_emit (fs, signals[FINISHED], 0,
@@ -2670,6 +2673,7 @@ item_queue_handlers_cb (gpointer user_data)
 		gdouble progress_now;
 		static gdouble progress_last = 0.0;
 		static gint info_last = 0;
+		gdouble seconds_elapsed;
 
 		time_last = time_now;
 
@@ -2677,22 +2681,31 @@ item_queue_handlers_cb (gpointer user_data)
 		progress_now = item_queue_get_progress (fs,
 		                                        &items_processed,
 		                                        &items_remaining);
+		seconds_elapsed = g_timer_elapsed (fs->private->timer, NULL);
 
 		if (!fs->private->is_crawling) {
 			gchar *status;
+			gint remaining_time;
 
 			g_object_get (fs, "status", &status, NULL);
 
+			/* Compute remaining time */
+			remaining_time = (gint)tracker_seconds_estimate (seconds_elapsed,
+			                                                 items_processed,
+			                                                 items_remaining);
+
 			if (g_strcmp0 (status, "Processingâ?¦") != 0) {
 				/* Don't spam this */
 				tracker_info ("Processingâ?¦");
 				g_object_set (fs,
 				              "status", "Processingâ?¦",
 				              "progress", progress_now,
+				              "remaining-time", remaining_time,
 				              NULL);
 			} else {
 				g_object_set (fs,
 				              "progress", progress_now,
+				              "remaining-time", remaining_time,
 				              NULL);
 			}
 
@@ -2702,13 +2715,12 @@ item_queue_handlers_cb (gpointer user_data)
 		if (++info_last >= 5 &&
 		    (gint) (progress_last * 100) != (gint) (progress_now * 100)) {
 			gchar *str1, *str2;
-			gdouble seconds_elapsed;
+
 
 			info_last = 0;
 			progress_last = progress_now;
 
 			/* Log estimated remaining time */
-			seconds_elapsed = g_timer_elapsed (fs->private->timer, NULL);
 			str1 = tracker_seconds_estimate_to_string (seconds_elapsed,
 			                                           TRUE,
 			                                           items_processed,
@@ -3764,10 +3776,13 @@ crawl_directories_cb (gpointer user_data)
 
 	tracker_info ("%s", str);
 
-	/* Always set the progress here to at least 1% */
+	/* Always set the progress here to at least 1%, and the remaining time
+	 * to -1 as we cannot guess during crawling (we don't know how many directories
+	 * we will find) */
 	g_object_set (fs,
 	              "progress", 0.01,
 	              "status", str,
+	              "remaining-time", -1,
 	              NULL);
 	g_free (str);
 
diff --git a/src/libtracker-miner/tracker-miner-manager.c b/src/libtracker-miner/tracker-miner-manager.c
index b6b89f2..8b3fbf2 100644
--- a/src/libtracker-miner/tracker-miner-manager.c
+++ b/src/libtracker-miner/tracker-miner-manager.c
@@ -129,11 +129,12 @@ tracker_miner_manager_class_init (TrackerMinerManagerClass *klass)
 	 * @miner: miner reference
 	 * @status: miner status
 	 * @progress: miner progress, from 0 to 1
+	 * @remaining_time: remaining processing time
 	 *
 	 * The ::miner-progress signal is meant to report status/progress changes
 	 * in any tracked miner.
 	 *
-	 * Since: 0.8
+	 * Since: 0.11
 	 **/
 	signals [MINER_PROGRESS] =
 		g_signal_new ("miner-progress",
@@ -141,11 +142,12 @@ tracker_miner_manager_class_init (TrackerMinerManagerClass *klass)
 		              G_SIGNAL_RUN_LAST,
 		              G_STRUCT_OFFSET (TrackerMinerManagerClass, miner_progress),
 		              NULL, NULL,
-		              tracker_marshal_VOID__STRING_STRING_DOUBLE,
-		              G_TYPE_NONE, 3,
+		              tracker_marshal_VOID__STRING_STRING_DOUBLE_INT,
+		              G_TYPE_NONE, 4,
 		              G_TYPE_STRING,
 		              G_TYPE_STRING,
-		              G_TYPE_DOUBLE);
+		              G_TYPE_DOUBLE,
+		              G_TYPE_INT);
 	/**
 	 * TrackerMinerManager::miner-paused
 	 * @manager: the #TrackerMinerManager
@@ -334,10 +336,11 @@ miner_progress_changed (GDBusConnection *connection,
 	MinerData *data = user_data;
 	const gchar *status = NULL;
 	gdouble progress = 0;
+	gint remaining_time = -1;
 
-	g_variant_get (parameters, "(&sd)", &status, &progress);
+	g_variant_get (parameters, "(&sdi)", &status, &progress, &remaining_time);
 	if (data->manager) {
-		g_signal_emit (data->manager, signals[MINER_PROGRESS], 0, data->dbus_name, status, progress);
+		g_signal_emit (data->manager, signals[MINER_PROGRESS], 0, data->dbus_name, status, progress, remaining_time);
 	}
 }
 
@@ -998,27 +1001,32 @@ tracker_miner_manager_is_active (TrackerMinerManager *manager,
  * @miner: miner reference
  * @status: return location for status
  * @progress: return location for progress
+ * @remaining_time: return location for remaining time
  *
- * Returns the current status and progress for @miner.
+ * Returns the current status, progress and remaining time for @miner.
+ * @remaining_time will be 0 if not possible to compute it yet,
+ * and less than zero if it is not applicable.
  *
  * Returns: %TRUE if the status could be retrieved successfully,
  * otherwise %FALSE
  *
- * Since: 0.8
+ * Since: 0.11
  **/
 gboolean
 tracker_miner_manager_get_status (TrackerMinerManager  *manager,
                                   const gchar          *miner,
                                   gchar               **status,
-                                  gdouble              *progress)
+                                  gdouble              *progress,
+                                  gint                 *remaining_time)
 {
 	GDBusProxy *proxy;
-	GError *error = NULL;
-	gdouble p;
-	GVariant *v;
 
 	g_return_val_if_fail (TRACKER_IS_MINER_MANAGER (manager), FALSE);
 	g_return_val_if_fail (miner != NULL, FALSE);
+	/* At least one of them should be asked */
+	g_return_val_if_fail (status != NULL ||
+	                      progress != NULL ||
+	                      remaining_time != NULL, FALSE);
 
 	proxy = find_miner_proxy (manager, miner, TRUE);
 
@@ -1027,54 +1035,78 @@ tracker_miner_manager_get_status (TrackerMinerManager  *manager,
 		return FALSE;
 	}
 
-	v = g_dbus_proxy_call_sync (proxy,
-	                            "GetProgress",
-	                            NULL,
-	                            G_DBUS_CALL_FLAGS_NONE,
-	                            -1,
-	                            NULL,
-	                            &error);
-
-	if (error) {
-		/* We handle this error as a special case, some
-		 * plugins don't have .service files.
-		 */
-		if (error->code != G_DBUS_ERROR_SERVICE_UNKNOWN) {
-			g_critical ("Could not get miner progress for '%s': %s", miner,
-			            error->message);
-		}
-
-		g_error_free (error);
-
-		return FALSE;
-	}
+	if (progress) {
+		GError *error = NULL;
+		GVariant *v;
+
+		v = g_dbus_proxy_call_sync (proxy,
+		                            "GetProgress",
+		                            NULL,
+		                            G_DBUS_CALL_FLAGS_NONE,
+		                            -1,
+		                            NULL,
+		                            &error);
+		if (error) {
+			/* We handle this error as a special case, some
+			 * plugins don't have .service files.
+			 */
+			if (error->code != G_DBUS_ERROR_SERVICE_UNKNOWN) {
+				g_critical ("Could not get miner progress for '%s': %s", miner,
+				            error->message);
+			}
 
-	g_variant_get (v, "(d)", &p);
-	g_variant_unref (v);
+			g_error_free (error);
 
-	v = g_dbus_proxy_call_sync (proxy,
-	                            "GetStatus",
-	                            NULL,
-	                            G_DBUS_CALL_FLAGS_NONE,
-	                            -1,
-	                            NULL,
-	                            &error);
+			return FALSE;
+		}
 
-	if (error) {
-		g_critical ("Could not get miner status for '%s': %s", miner,
-		            error->message);
-		g_error_free (error);
-		return FALSE;
+		g_variant_get (v, "(d)", progress);
+		g_variant_unref (v);
 	}
 
 	if (status) {
+		GError *error = NULL;
+		GVariant *v;
+
+		v = g_dbus_proxy_call_sync (proxy,
+		                            "GetStatus",
+		                            NULL,
+		                            G_DBUS_CALL_FLAGS_NONE,
+		                            -1,
+		                            NULL,
+		                            &error);
+		if (error) {
+			g_critical ("Could not get miner status for '%s': %s", miner,
+			            error->message);
+			g_error_free (error);
+			return FALSE;
+		}
+
 		g_variant_get (v, "(s)", status);
+		g_variant_unref (v);
 	}
 
-	g_variant_unref (v);
+	if (remaining_time) {
+		GError *error = NULL;
+		GVariant *v;
+
+		v = g_dbus_proxy_call_sync (proxy,
+		                            "GetRemainingTime",
+		                            NULL,
+		                            G_DBUS_CALL_FLAGS_NONE,
+		                            -1,
+		                            NULL,
+		                            &error);
+		if (error) {
+			g_critical ("Could not get miner remaining processing "
+			            "time for '%s': %s", miner,
+			            error->message);
+			g_error_free (error);
+			return FALSE;
+		}
 
-	if (progress) {
-		*progress = p;
+		g_variant_get (v, "(i)", remaining_time);
+		g_variant_unref (v);
 	}
 
 	return TRUE;
diff --git a/src/libtracker-miner/tracker-miner-manager.h b/src/libtracker-miner/tracker-miner-manager.h
index e6c13e8..ea3e3e6 100644
--- a/src/libtracker-miner/tracker-miner-manager.h
+++ b/src/libtracker-miner/tracker-miner-manager.h
@@ -118,7 +118,8 @@ gboolean             tracker_miner_manager_is_paused          (TrackerMinerManag
 gboolean             tracker_miner_manager_get_status         (TrackerMinerManager  *manager,
                                                                const gchar          *miner,
                                                                gchar               **status,
-                                                               gdouble              *progress);
+                                                               gdouble              *progress,
+                                                               gint                 *remaining_time);
 gboolean             tracker_miner_manager_ignore_next_update (TrackerMinerManager  *manager,
                                                                const gchar          *miner,
                                                                const gchar         **urls);
diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c
index 9331fc2..0648230 100644
--- a/src/libtracker-miner/tracker-miner-object.c
+++ b/src/libtracker-miner/tracker-miner-object.c
@@ -71,6 +71,9 @@ static const gchar introspection_xml[] =
   "    <method name='GetProgress'>"
   "      <arg type='d' name='progress' direction='out' />"
   "    </method>"
+  "    <method name='GetRemainingTime'>"
+  "      <arg type='i' name='remaining_time' direction='out' />"
+  "    </method>"
   "    <method name='GetPauseDetails'>"
   "      <arg type='as' name='pause_applications' direction='out' />"
   "      <arg type='as' name='pause_reasons' direction='out' />"
@@ -104,6 +107,7 @@ struct _TrackerMinerPrivate {
 	gchar *name;
 	gchar *status;
 	gdouble progress;
+	gint remaining_time;
 	gint availability_cookie;
 	GDBusConnection *d_connection;
 	GDBusNodeInfo *introspection_data;
@@ -123,7 +127,8 @@ enum {
 	PROP_0,
 	PROP_NAME,
 	PROP_STATUS,
-	PROP_PROGRESS
+	PROP_PROGRESS,
+	PROP_REMAINING_TIME
 };
 
 enum {
@@ -276,13 +281,17 @@ tracker_miner_class_init (TrackerMinerClass *klass)
 	 * @miner: the #TrackerMiner
 	 * @status: miner status
 	 * @progress: a #gdouble indicating miner progress, from 0 to 1.
+	 * @remaining_time: a #gint indicating the reamaining processing time, in
+	 * seconds.
 	 *
 	 * the ::progress signal will be emitted by TrackerMiner implementations
 	 * to indicate progress about the data mining process. @status will
 	 * contain a translated string with the current miner status and @progress
-	 * will indicate how much has been processed so far.
+	 * will indicate how much has been processed so far. @remaining_time will
+	 * give the number expected of seconds to finish processing, 0 if the
+	 * value cannot be estimated, and -1 if its not applicable.
 	 *
-	 * Since: 0.8
+	 * Since: 0.11
 	 **/
 	signals[PROGRESS] =
 		g_signal_new ("progress",
@@ -290,10 +299,11 @@ tracker_miner_class_init (TrackerMinerClass *klass)
 		              G_SIGNAL_RUN_LAST,
 		              G_STRUCT_OFFSET (TrackerMinerClass, progress),
 		              NULL, NULL,
-		              tracker_marshal_VOID__STRING_DOUBLE,
-		              G_TYPE_NONE, 2,
+		              tracker_marshal_VOID__STRING_DOUBLE_INT,
+		              G_TYPE_NONE, 3,
 		              G_TYPE_STRING,
-		              G_TYPE_DOUBLE);
+		              G_TYPE_DOUBLE,
+		              G_TYPE_INT);
 
 	/**
 	 * TrackerMiner::ignore-next-update:
@@ -340,6 +350,16 @@ tracker_miner_class_init (TrackerMinerClass *klass)
 	                                                      0.0,
 	                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
+	g_object_class_install_property (object_class,
+	                                 PROP_REMAINING_TIME,
+	                                 g_param_spec_int ("remaining-time",
+	                                                   "Remaining time",
+	                                                   "Estimated remaining time to finish processing",
+	                                                   -1,
+	                                                   G_MAXINT,
+	                                                   -1,
+	                                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
 	g_type_class_add_private (object_class, sizeof (TrackerMinerPrivate));
 
 	miner_error_quark = g_quark_from_static_string ("TrackerMiner");
@@ -487,7 +507,8 @@ miner_update_progress (TrackerMiner *miner)
 {
 	g_signal_emit (miner, signals[PROGRESS], 0,
 	               miner->private->status,
-	               miner->private->progress);
+	               miner->private->progress,
+	               miner->private->remaining_time);
 
 	if (miner->private->d_connection) {
 		g_dbus_connection_emit_signal (miner->private->d_connection,
@@ -495,9 +516,10 @@ miner_update_progress (TrackerMiner *miner)
 		                               miner->private->full_path,
 		                               TRACKER_MINER_DBUS_INTERFACE,
 		                               "Progress",
-		                               g_variant_new ("(sd)",
+		                               g_variant_new ("(sdi)",
 		                                              miner->private->status,
-		                                              miner->private->progress),
+		                                              miner->private->progress,
+		                                              miner->private->remaining_time),
 		                               NULL);
 	}
 }
@@ -550,6 +572,16 @@ miner_set_property (GObject      *object,
 		miner_update_progress (miner);
 		break;
 	}
+	case PROP_REMAINING_TIME: {
+		gint new_remaining_time;
+
+		new_remaining_time = g_value_get_int (value);
+		if (new_remaining_time != miner->private->remaining_time) {
+			/* Just set the new remaining time, don't notify it */
+			miner->private->remaining_time = new_remaining_time;
+		}
+		break;
+	}
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -574,6 +606,9 @@ miner_get_property (GObject    *object,
 	case PROP_PROGRESS:
 		g_value_set_double (value, miner->private->progress);
 		break;
+	case PROP_REMAINING_TIME:
+		g_value_set_int (value, miner->private->remaining_time);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -1092,6 +1127,21 @@ handle_method_call_get_pause_details (TrackerMiner          *miner,
 }
 
 static void
+handle_method_call_get_remaining_time (TrackerMiner          *miner,
+                                       GDBusMethodInvocation *invocation,
+                                       GVariant              *parameters)
+{
+	TrackerDBusRequest *request;
+
+	request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__);
+
+	tracker_dbus_request_end (request, NULL);
+	g_dbus_method_invocation_return_value (invocation,
+	                                       g_variant_new ("(i)",
+	                                                      miner->private->remaining_time));
+}
+
+static void
 handle_method_call_get_progress (TrackerMiner          *miner,
                                  GDBusMethodInvocation *invocation,
                                  GVariant              *parameters)
@@ -1102,7 +1152,8 @@ handle_method_call_get_progress (TrackerMiner          *miner,
 
 	tracker_dbus_request_end (request, NULL);
 	g_dbus_method_invocation_return_value (invocation,
-	                                       g_variant_new ("(d)", miner->private->progress));
+	                                       g_variant_new ("(d)",
+	                                                      miner->private->progress));
 }
 
 static void
@@ -1116,7 +1167,8 @@ handle_method_call_get_status (TrackerMiner          *miner,
 
 	tracker_dbus_request_end (request, NULL);
 	g_dbus_method_invocation_return_value (invocation,
-	                                       g_variant_new ("(s)", miner->private->status ? miner->private->status : ""));
+	                                       g_variant_new ("(s)",
+	                                                      miner->private->status ? miner->private->status : ""));
 
 }
 
@@ -1146,6 +1198,9 @@ handle_method_call (GDBusConnection       *connection,
 	if (g_strcmp0 (method_name, "GetPauseDetails") == 0) {
 		handle_method_call_get_pause_details (miner, invocation, parameters);
 	} else
+	if (g_strcmp0 (method_name, "GetRemainingTime") == 0) {
+		handle_method_call_get_remaining_time (miner, invocation, parameters);
+	} else
 	if (g_strcmp0 (method_name, "GetProgress") == 0) {
 		handle_method_call_get_progress (miner, invocation, parameters);
 	} else
diff --git a/src/tracker-control/tracker-control-general.c b/src/tracker-control/tracker-control-general.c
index fe2b0e2..247e291 100644
--- a/src/tracker-control/tracker-control-general.c
+++ b/src/tracker-control/tracker-control-general.c
@@ -513,14 +513,17 @@ tracker_control_general_run (void)
 		/* Get the status of all miners, this will start all
 		 * miners not already running.
 		 */
-
 		for (l = miners; l; l = l->next) {
 			const gchar *display_name;
 			gdouble progress = 0.0;
 
 			display_name = tracker_miner_manager_get_display_name (manager, l->data);
 
-			if (!tracker_miner_manager_get_status (manager, l->data, NULL, &progress)) {
+			if (!tracker_miner_manager_get_status (manager,
+			                                       l->data,
+			                                       NULL,
+			                                       &progress,
+			                                       NULL)) {
 				g_printerr ("  â?? %s (%s)\n",
 				            display_name,
 				            _("perhaps a disabled plugin?"));
diff --git a/src/tracker-control/tracker-control-status.c b/src/tracker-control/tracker-control-status.c
index 0d114ac..4b5bf4d 100644
--- a/src/tracker-control/tracker-control-status.c
+++ b/src/tracker-control/tracker-control-status.c
@@ -128,12 +128,16 @@ miner_get_details (TrackerMinerManager  *manager,
                    const gchar          *miner,
                    gchar               **status,
                    gdouble              *progress,
+                   gint                 *remaining_time,
                    GStrv                *pause_applications,
                    GStrv                *pause_reasons)
 {
-	if ((status || progress) &&
-	    !tracker_miner_manager_get_status (manager, miner,
-	                                       status, progress)) {
+	if ((status || progress || remaining_time) &&
+	    !tracker_miner_manager_get_status (manager,
+	                                       miner,
+	                                       status,
+	                                       progress,
+	                                       remaining_time)) {
 		g_printerr (_("Could not get status from miner: %s"), miner);
 		return FALSE;
 	}
@@ -150,6 +154,7 @@ miner_print_state (TrackerMinerManager *manager,
                    const gchar         *miner_name,
                    const gchar         *status,
                    gdouble              progress,
+                   gint                 remaining_time,
                    gboolean             is_running,
                    gboolean             is_paused)
 {
@@ -158,7 +163,6 @@ miner_print_state (TrackerMinerManager *manager,
 	gchar time_str[64];
 	size_t len;
 	struct tm *local_time;
-	gchar *progress_str;
 
 	now = time ((time_t *) NULL);
 	local_time = localtime (&now);
@@ -170,18 +174,31 @@ miner_print_state (TrackerMinerManager *manager,
 
 	name = tracker_miner_manager_get_display_name (manager, miner_name);
 
-	if (!is_running) {
-		progress_str = g_strdup_printf ("â??   ");
-	} else if (progress > 0.0 && progress < 1.0) {
-		progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
-	} else {
-		progress_str = g_strdup_printf ("â??   ");
-	}
-
 	if (is_running) {
-		g_print ("%s  %s  %-*.*s %s%-*.*s%s %s %s\n",
+		gchar *progress_str = NULL;
+		gchar *remaining_time_str = NULL;
+
+		if (progress > 0.0 && progress < 1.0) {
+			progress_str = g_strdup_printf ("%3u%%", (guint)(progress * 100));
+		}
+
+		/* Progress > 0.01 here because we want to avoid any message
+		 * during crawling, as we don't have the remaining time in that
+		 * case and it would just print "unknown time left" */
+		if (progress > 0.01 &&
+		    progress < 1.0 &&
+		    remaining_time >= 0) {
+			/* 0 means that we couldn't properly compute the remaining
+			 * time. */
+			remaining_time_str = (remaining_time > 0 ?
+			                      g_strdup_printf (_("estimated %ds left"),
+			                                       remaining_time) :
+			                      g_strdup (_("unknown time left")));
+		}
+
+		g_print ("%s  %s  %-*.*s %s%-*.*s%s %s %s %s\n",
 		         time_str,
-		         progress_str,
+		         progress_str ? progress_str : "â??   ",
 		         longest_miner_name_length,
 		         longest_miner_name_length,
 		         name,
@@ -191,11 +208,14 @@ miner_print_state (TrackerMinerManager *manager,
 		         is_paused ? _("PAUSED") : " ",
 		         is_paused ? ")" : " ",
 		         status ? "-" : "",
-		         status ? _(status) : "");
+		         status ? _(status) : "",
+		         remaining_time_str ? remaining_time_str : "");
+
+		g_free (progress_str);
+		g_free (remaining_time_str);
 	} else {
-		g_print ("%s  %s  %-*.*s  %-*.*s  - %s\n",
+		g_print ("%s  â??     %-*.*s  %-*.*s  - %s\n",
 		         time_str,
-		         progress_str,
 		         longest_miner_name_length,
 		         longest_miner_name_length,
 		         name,
@@ -204,8 +224,6 @@ miner_print_state (TrackerMinerManager *manager,
 		         " ",
 		         _("Not running or is a disabled plugin"));
 	}
-
-	g_free (progress_str);
 }
 
 static void
@@ -334,7 +352,8 @@ static void
 manager_miner_progress_cb (TrackerMinerManager *manager,
                            const gchar         *miner_name,
                            const gchar         *status,
-                           gdouble              progress)
+                           gdouble              progress,
+                           gint                 remaining_time)
 {
 	GValue *gvalue;
 
@@ -343,7 +362,7 @@ manager_miner_progress_cb (TrackerMinerManager *manager,
 	g_value_init (gvalue, G_TYPE_DOUBLE);
 	g_value_set_double (gvalue, progress);
 
-	miner_print_state (manager, miner_name, status, progress, TRUE, FALSE);
+	miner_print_state (manager, miner_name, status, progress, remaining_time, TRUE, FALSE);
 
 	g_hash_table_replace (miners_status,
 	                      g_strdup (miner_name),
@@ -364,6 +383,7 @@ manager_miner_paused_cb (TrackerMinerManager *manager,
 	miner_print_state (manager, miner_name,
 	                   g_hash_table_lookup (miners_status, miner_name),
 	                   gvalue ? g_value_get_double (gvalue) : 0.0,
+	                   -1,
 	                   TRUE,
 	                   TRUE);
 }
@@ -379,6 +399,7 @@ manager_miner_resumed_cb (TrackerMinerManager *manager,
 	miner_print_state (manager, miner_name,
 	                   g_hash_table_lookup (miners_status, miner_name),
 	                   gvalue ? g_value_get_double (gvalue) : 0.0,
+	                   0,
 	                   TRUE,
 	                   FALSE);
 }
@@ -539,12 +560,14 @@ tracker_control_status_run (void)
 				GStrv pause_applications, pause_reasons;
 				gchar *status = NULL;
 				gdouble progress;
+				gint remaining_time;
 				gboolean is_paused;
 
 				if (!miner_get_details (manager,
 				                        l->data,
 				                        &status,
 				                        &progress,
+				                        &remaining_time,
 				                        &pause_applications,
 				                        &pause_reasons)) {
 					continue;
@@ -552,13 +575,19 @@ tracker_control_status_run (void)
 
 				is_paused = *pause_applications || *pause_reasons;
 
-				miner_print_state (manager, l->data, status, progress, TRUE, is_paused);
+				miner_print_state (manager,
+				                   l->data,
+				                   status,
+				                   progress,
+				                   remaining_time,
+				                   TRUE,
+				                   is_paused);
 
 				g_strfreev (pause_applications);
 				g_strfreev (pause_reasons);
 				g_free (status);
 			} else {
-				miner_print_state (manager, l->data, NULL, 0.0, FALSE, FALSE);
+				miner_print_state (manager, l->data, NULL, 0.0, -1, FALSE, FALSE);
 			}
 		}
 



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