[packagekit] packagekit: Branch 'master' - 3 commits

Richard Hughes hughsient at kemper.freedesktop.org
Tue Nov 27 23:42:49 PST 2007


 backends/zypp/pk-backend-zypp.cpp |   72 ++++++--
 backends/zypp/zypp-events.h       |  310 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 366 insertions(+), 16 deletions(-)

New commits:
commit 223e8ac238da2f7a0c6c76b424f27354711912dd
Author: Boyd Timothy <btimothy at gmail.com>
Date:   Sun Nov 18 04:04:45 2007 -0700

    Removed accidental pk_backend_error_code () from zypp backend.

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 6bc1ee5..c72cca6 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -174,7 +174,6 @@ backend_get_description_thread (PkBackend *backend, gpointer data)
 		g_free (d);
 		return FALSE;
 	}
-		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 	pk_backend_change_status (backend, PK_STATUS_ENUM_QUERY);
 
 	// FIXME: Call libzypp here to get the "Selectable"
commit 4d19f08f40d52f4d0149f1926b308b02c21944e6
Author: Boyd Timothy <btimothy at gmail.com>
Date:   Sun Nov 18 04:00:35 2007 -0700

    Keep a separate event handle for each backend that is created in zypp's backend.  Also commented out a bunch of debug printf statements

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 33ddb47..6bc1ee5 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -44,6 +44,8 @@
 #include <zypp/Pathname.h>
 #include <sqlite3.h>
 
+#include <map>
+
 #include "zypp-events.h"
 
 enum PkgSearchType {
@@ -103,7 +105,11 @@ typedef zypp::Language::constPtr	ZyppLanguage;
 inline ZyppPackage tryCastToZyppPkg (ZyppObject obj)
 	{ return zypp::dynamic_pointer_cast <const zypp::Package> (obj); }
 
-static EventDirector *_eventDirector;
+/**
+ * A map to keep track of the EventDirector objects for
+ * each zypp backend that is created.
+ */
+static std::map<PkBackend *, EventDirector *> _eventDirectors;
 
 /**
  * Initialize Zypp (Factory method)
@@ -135,7 +141,8 @@ backend_initialize (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
 fprintf (stderr, "\n\n*** zypp_backend_initialize ***\n\n");
-	_eventDirector = new EventDirector (backend);
+	EventDirector *eventDirector = new EventDirector (backend);
+	_eventDirectors [backend] = eventDirector;
 }
 
 /**
@@ -146,7 +153,11 @@ backend_destroy (PkBackend *backend)
 {
 	g_return_if_fail (backend != NULL);
 fprintf (stderr, "\n\n*** zypp_backend_destroy ***\n\n");
-	delete (_eventDirector);
+	EventDirector *eventDirector = _eventDirectors [backend];
+	if (eventDirector != NULL) {
+		delete (eventDirector);
+		_eventDirectors.erase (backend);
+	}
 }
 
 static gboolean
@@ -216,6 +227,7 @@ backend_install_package_thread (PkBackend *backend, gpointer data)
 	gchar *package_id = (gchar *)data;
 
 	pk_backend_change_status (backend, PK_STATUS_ENUM_QUERY);
+	pk_backend_change_percentage (backend, 0);
 
 	PkPackageId *pi = pk_package_id_new_from_string (package_id);
         if (pi == NULL) {
@@ -237,7 +249,6 @@ backend_install_package_thread (PkBackend *backend, gpointer data)
 	pk_backend_change_percentage (backend, 10);
 
 	// Load resolvables from all the enabled repositories
-	pk_backend_change_status (backend, PK_STATUS_ENUM_WAIT);
 	zypp::RepoManager manager;
 	std::list <zypp::RepoInfo> repos;
 	try
@@ -272,7 +283,7 @@ backend_install_package_thread (PkBackend *backend, gpointer data)
 				const char *edition_str = installable->edition().asString().c_str();
 
 				if (strcmp (edition_str, pi->version) == 0) {
-printf ("WOOT!  Marking the package to be installed!\n");
+//printf ("WOOT!  Marking the package to be installed!\n");
 					// this is the one, mark it to be installed
 					selectable->set_status (zypp::ui::S_Install);
 					break; // Found it, get out of the for loop
@@ -282,7 +293,7 @@ printf ("WOOT!  Marking the package to be installed!\n");
 
 		pk_backend_change_percentage (backend, 40);
 
-printf ("Resolving dependencies...\n");
+//printf ("Resolving dependencies...\n");
 		// Gather up any dependencies
 		pk_backend_change_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
 		if (zypp->resolver ()->resolvePool () == FALSE) {
@@ -297,7 +308,7 @@ printf ("Resolving dependencies...\n");
 
 		pk_backend_change_percentage (backend, 60);
 
-printf ("Performing installation...\n");
+//printf ("Performing installation...\n");
 		// Perform the installation
 		// TODO: If this were an update, you should use PK_INFO_ENUM_UPDATING instead
 		zypp::ZYppCommitPolicy policy;
@@ -308,9 +319,6 @@ printf ("Finished the installation.\n");
 		pk_backend_change_percentage (backend, 100);
 
 		// TODO: Check result for success
-		// TODO: Loop through the installed packages and let
-		// packagekit know we installed them and not just the top-level package
-		pk_backend_package (backend, PK_INFO_ENUM_INSTALLED, package_id, "TODO: Put the package summary here");
 	} catch (const zypp::repo::RepoNotFoundException &ex) {
 		// TODO: make sure this dumps out the right sring.
 		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() );
@@ -338,10 +346,11 @@ backend_install_package (PkBackend *backend, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
 
-	printf("package_id is %s\n", package_id);
+	//printf("package_id is %s\n", package_id);
 	gchar *package_to_install = g_strdup (package_id);
-	pk_backend_change_percentage (backend, 0);
 	pk_backend_thread_helper (backend, backend_install_package_thread, package_to_install);
+	//pk_backend_thread_create (backend, backend_install_package_thread, package_to_install);
+fprintf (stderr, "\n\n\n\n============== Returning from backend_install_package =============\n\n\n\n");
 }
 
 static int
@@ -405,7 +414,7 @@ backend_resolve_thread (PkBackend *backend, gpointer data)
 	}
 	full_version = g_strconcat (sql_data->version, "-", sql_data->release, NULL);
 	package_id = pk_package_id_build(sql_data->name, full_version, sql_data->arch, "opensuse");
-	printf("about to return package_id of:%s\n", package_id);
+	//printf("about to return package_id of:%s\n", package_id);
 	//FIXME - return real PK_INFO_ENUM_*
 	pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
 				package_id, "description generated by zypp backend");
@@ -426,7 +435,7 @@ static void
 backend_resolve (PkBackend *backend, const gchar *filter, const gchar *package_id)
 {
 	g_return_if_fail (backend != NULL);
-	printf("Enter backend_resolve - filter:%s, package_id:%s\n", filter, package_id);
+	//printf("Enter backend_resolve - filter:%s, package_id:%s\n", filter, package_id);
 	ResolveData *data = g_new0(ResolveData, 1);
 	if (data == NULL) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_OOM, "Failed to allocate memory in backend_resolve");
diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
index ff68373..e6c7a75 100644
--- a/backends/zypp/zypp-events.h
+++ b/backends/zypp/zypp-events.h
@@ -6,6 +6,21 @@
 #include <pk-backend.h>
 #include <zypp/ZYppCallbacks.h>
 
+/*
+typedef struct {
+	PkBackend *backend;
+	guint percentage;
+} PercentageData;
+
+static gboolean
+emit_sub_percentage (gpointer data)
+{
+	PercentageData *pd = (PercentageData *)data;
+	pk_backend_change_sub_percentage (pd->backend, pd->percentage);
+	free (pd);
+	return FALSE;
+}
+*/
 
 namespace ZyppBackend
 {
@@ -130,6 +145,10 @@ struct ZyppBackendReceiver
 			return;
 
 		_sub_percentage = percentage;
+		//PercentageData *pd = (PercentageData *)malloc (sizeof (PercentageData));
+		//pd->backend = _backend;
+		//pd->percentage = _sub_percentage;
+		//g_idle_add (emit_sub_percentage, pd);
 		pk_backend_change_sub_percentage (_backend, _sub_percentage);
 	}
 
@@ -149,7 +168,7 @@ struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zy
 	{
 		clear_package_id ();
 		_package_id = build_package_id_from_resolvable (resolvable);
-		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::start(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
+		//fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::start(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
 		if (_package_id != NULL) {
 			pk_backend_change_status (_backend, PK_STATUS_ENUM_INSTALL);
 			pk_backend_package (_backend, PK_INFO_ENUM_INSTALLING, _package_id, "TODO: Put the package summary here if possible");
@@ -159,7 +178,7 @@ struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zy
 
 	virtual bool progress (int value, zypp::Resolvable::constPtr resolvable)
 	{
-		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
+		//fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
 		if (_package_id != NULL)
 			update_sub_percentage (value);
 		return true;
@@ -167,13 +186,13 @@ struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zy
 
 	virtual Action problem (zypp::Resolvable::constPtr resolvable, Error error, const std::string &description, RpmLevel level)
 	{
-		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::problem()\n\n");
+		//fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::problem()\n\n");
 		return ABORT;
 	}
 
 	virtual void finish (zypp::Resolvable::constPtr resolvable, Error error, const std::string &reason, RpmLevel level)
 	{
-		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::finish(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
+		//fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::finish(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
 		if (_package_id != NULL) {
 			pk_backend_package (_backend, PK_INFO_ENUM_INSTALLED, _package_id, "TODO: Put the package summary here if possible");
 			clear_package_id ();
@@ -185,18 +204,18 @@ struct RepoProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::P
 {
 	virtual void start (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::start()\n\n");
+		//fprintf (stderr, "\n\n----> RepoProgressReportReceiver::start()\n\n");
 	}
 
 	virtual bool progress (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::progress(), %s:%d\n\n", data.name().c_str(), (int)data.val());
+		//fprintf (stderr, "\n\n----> RepoProgressReportReceiver::progress(), %s:%d\n\n", data.name().c_str(), (int)data.val());
 		return true;
 	}
 
 	virtual void finish (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::finish()\n\n");
+		//fprintf (stderr, "\n\n----> RepoProgressReportReceiver::finish()\n\n");
 	}
 };
 
@@ -204,18 +223,18 @@ struct RepoReportReceiver : public zypp::callback::ReceiveReport<zypp::repo::Rep
 {
 	virtual void start (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoReportReceiver::start()\n");
+		//fprintf (stderr, "\n\n----> RepoReportReceiver::start()\n");
 	}
 
 	virtual bool progress (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoReportReceiver::progress(), %s:%d\n", data.name().c_str(), (int)data.val());
+		//fprintf (stderr, "\n\n----> RepoReportReceiver::progress(), %s:%d\n", data.name().c_str(), (int)data.val());
 		return true;
 	}
 
 	virtual void finish (const zypp::ProgressData &data)
 	{
-		fprintf (stderr, "\n\n----> RepoReportReceiver::finish()\n");
+		//fprintf (stderr, "\n\n----> RepoReportReceiver::finish()\n");
 	}
 };
 
@@ -226,7 +245,7 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp
 		clear_package_id ();
 		_package_id = build_package_id_from_url (&file);
 
-		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::start(): %s\n", _package_id == NULL ? "unknown" : _package_id);
+		//fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::start(): %s\n", _package_id == NULL ? "unknown" : _package_id);
 		if (_package_id != NULL) {
 			pk_backend_change_status (_backend, PK_STATUS_ENUM_DOWNLOAD);
 			pk_backend_package (_backend, PK_INFO_ENUM_DOWNLOADING, _package_id, "TODO: Put the package summary here if possible");
@@ -236,7 +255,7 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp
 
 	virtual bool progress (int value, const zypp::Url &file)
 	{
-		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
+		//fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
 		if (_package_id != NULL)
 			update_sub_percentage (value);
 		return true;
@@ -244,7 +263,7 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp
 
 	virtual void finish (const zypp::Url & file, Error error, const std::string &konreason)
 	{
-		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::finish(): %s\n", _package_id == NULL ? "unknown" : _package_id);
+		//fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::finish(): %s\n", _package_id == NULL ? "unknown" : _package_id);
 		clear_package_id ();
 	}
 };
commit f9c4b3f10b1f1a733dbd68f5359be97cfc794e16
Author: Boyd Timothy <btimothy at gmail.com>
Date:   Sun Nov 18 02:15:27 2007 -0700

    Starting some work on the events from libzypp to the zypp backend for progress updates.

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 2fc410d..33ddb47 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -44,6 +44,8 @@
 #include <zypp/Pathname.h>
 #include <sqlite3.h>
 
+#include "zypp-events.h"
+
 enum PkgSearchType {
 	SEARCH_TYPE_NAME = 0,
 	SEARCH_TYPE_DETAILS = 1,
@@ -101,6 +103,8 @@ typedef zypp::Language::constPtr	ZyppLanguage;
 inline ZyppPackage tryCastToZyppPkg (ZyppObject obj)
 	{ return zypp::dynamic_pointer_cast <const zypp::Package> (obj); }
 
+static EventDirector *_eventDirector;
+
 /**
  * Initialize Zypp (Factory method)
  */
@@ -123,6 +127,28 @@ get_zypp ()
 	return zypp;
 }
 
+/**
+ * backend_initialize:
+ */
+static void
+backend_initialize (PkBackend *backend)
+{
+	g_return_if_fail (backend != NULL);
+fprintf (stderr, "\n\n*** zypp_backend_initialize ***\n\n");
+	_eventDirector = new EventDirector (backend);
+}
+
+/**
+ * backend_destroy
+ */
+static void
+backend_destroy (PkBackend *backend)
+{
+	g_return_if_fail (backend != NULL);
+fprintf (stderr, "\n\n*** zypp_backend_destroy ***\n\n");
+	delete (_eventDirector);
+}
+
 static gboolean
 backend_get_description_thread (PkBackend *backend, gpointer data)
 {
@@ -137,7 +163,7 @@ backend_get_description_thread (PkBackend *backend, gpointer data)
 		g_free (d);
 		return FALSE;
 	}
-
+		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 	pk_backend_change_status (backend, PK_STATUS_ENUM_QUERY);
 
 	// FIXME: Call libzypp here to get the "Selectable"
@@ -208,6 +234,7 @@ backend_install_package_thread (PkBackend *backend, gpointer data)
 
 	// Load all the local system "resolvables" (packages)
 	zypp->addResolvables (target->resolvables(), TRUE);
+	pk_backend_change_percentage (backend, 10);
 
 	// Load resolvables from all the enabled repositories
 	pk_backend_change_status (backend, PK_STATUS_ENUM_WAIT);
@@ -253,6 +280,8 @@ printf ("WOOT!  Marking the package to be installed!\n");
 			}
 		}
 
+		pk_backend_change_percentage (backend, 40);
+
 printf ("Resolving dependencies...\n");
 		// Gather up any dependencies
 		pk_backend_change_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
@@ -266,16 +295,18 @@ printf ("Resolving dependencies...\n");
 			return FALSE;
 		}
 
+		pk_backend_change_percentage (backend, 60);
+
 printf ("Performing installation...\n");
 		// Perform the installation
-		pk_backend_change_status (backend, PK_STATUS_ENUM_COMMIT);
 		// TODO: If this were an update, you should use PK_INFO_ENUM_UPDATING instead
-		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING, package_id, "TODO: Put the package summary here");
 		zypp::ZYppCommitPolicy policy;
 		policy.restrictToMedia (0);	// 0 - install all packages regardless to media
 		zypp::ZYppCommitResult result = zypp->commit (policy);
 printf ("Finished the installation.\n");
 
+		pk_backend_change_percentage (backend, 100);
+
 		// TODO: Check result for success
 		// TODO: Loop through the installed packages and let
 		// packagekit know we installed them and not just the top-level package
@@ -309,6 +340,7 @@ backend_install_package (PkBackend *backend, const gchar *package_id)
 
 	printf("package_id is %s\n", package_id);
 	gchar *package_to_install = g_strdup (package_id);
+	pk_backend_change_percentage (backend, 0);
 	pk_backend_thread_helper (backend, backend_install_package_thread, package_to_install);
 }
 
@@ -372,7 +404,7 @@ backend_resolve_thread (PkBackend *backend, gpointer data)
 		return FALSE;
 	}
 	full_version = g_strconcat (sql_data->version, "-", sql_data->release, NULL);
-	package_id = pk_package_id_build(sql_data->name, full_version, sql_data->arch, sql_data->repo);
+	package_id = pk_package_id_build(sql_data->name, full_version, sql_data->arch, "opensuse");
 	printf("about to return package_id of:%s\n", package_id);
 	//FIXME - return real PK_INFO_ENUM_*
 	pk_backend_package (backend, PK_INFO_ENUM_AVAILABLE,
@@ -681,8 +713,8 @@ backend_repo_enable (PkBackend *backend, const gchar *rid, gboolean enabled)
 extern "C" PK_BACKEND_OPTIONS (
 	"Zypp",					/* description */
 	"Boyd Timothy <btimothy at gmail.com>, Scott Reeves <sreeves at novell.com>",	/* author */
-	NULL,					/* initalize */
-	NULL,					/* destroy */
+	backend_initialize,			/* initalize */
+	backend_destroy,			/* destroy */
 	NULL,					/* get_groups */
 	NULL,					/* get_filters */
 	NULL,					/* cancel */
diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
new file mode 100644
index 0000000..ff68373
--- /dev/null
+++ b/backends/zypp/zypp-events.h
@@ -0,0 +1,291 @@
+#ifndef _ZYPP_EVENTS_H_
+#define _ZYPP_EVENTS_H_
+
+#include <stdio.h>
+#include <glib.h>
+#include <pk-backend.h>
+#include <zypp/ZYppCallbacks.h>
+
+
+namespace ZyppBackend
+{
+
+struct ZyppBackendReceiver
+{
+	PkBackend *_backend;
+	gchar *_package_id;
+	guint _sub_percentage;
+
+	virtual void initWithBackend (PkBackend *backend)
+	{
+		_backend = backend;
+		_package_id = NULL;
+		_sub_percentage = 0;
+	}
+
+	virtual void clear_package_id ()
+	{
+		if (_package_id != NULL) {
+			g_free (_package_id);
+			_package_id = NULL;
+		}
+	}
+
+	/**
+	 * Build a package_id from the specified resolvable.  The returned
+	 * gchar * should be freed with g_free ().
+	 */
+	gchar *
+	build_package_id_from_resolvable (zypp::Resolvable::constPtr resolvable)
+	{
+		gchar *package_id;
+		
+		package_id = pk_package_id_build (resolvable->name ().c_str (),
+						  resolvable->edition ().asString ().c_str (),
+						  resolvable->arch ().asString ().c_str (),
+						  "opensuse");
+
+		return package_id;
+	}
+
+	/**
+	 * Build a package_id from the specified zypp::Url.  The returned
+	 * gchar * should be freed with g_free ().  Returns NULL if the
+	 * URL does not contain information about an RPM.
+	 *
+	 * Example:
+	 *    basename: lynx-2.8.6-63.i586.rpm
+	 *    result:   lynx;2.8.6-63;i586;opensuse
+	 */
+	gchar *
+	build_package_id_from_url (const zypp::Url *url)
+	{
+		gchar *package_id;
+		gchar *basename;
+		gchar *tmp;
+	
+		gchar *arch;
+		gchar *edition;
+		gchar *name;
+		gboolean first_dash_found;
+	
+		basename = g_strdup (zypp::Pathname (url->getPathName ()).basename ().c_str());
+	
+		tmp = g_strrstr (basename, ".rpm");
+	
+		if (tmp == NULL) {
+			g_free (basename);
+			return NULL;
+		}
+	
+		// Parse the architecture
+		tmp [0] = '\0'; // null-terminate the arch section
+		for (tmp--; tmp != basename && tmp [0] != '.'; tmp--) {}
+		arch = tmp + 1;
+	
+		// Parse the edition
+		tmp [0] = '\0'; // null-terminate the edition (version)
+		first_dash_found = FALSE;
+		for (tmp--; tmp != basename; tmp--) {
+			if (tmp [0] == '-') {
+				if (first_dash_found == FALSE) {
+					first_dash_found = TRUE;
+					continue;
+				} else {
+					break;
+				}
+			}
+		}
+		edition = tmp + 1;
+	
+		// Parse the name
+		tmp [0] = '\0'; // null-terminate the name
+		name = basename;
+	
+		package_id = pk_package_id_build (name, edition, arch, "opensuse");
+		g_free (basename);
+	
+		return package_id;
+	}
+
+	inline void
+	update_sub_percentage (guint percentage)
+	{
+		// TODO: Figure out this weird bug that libzypp emits a 100
+		// at the beginning of installing a package.
+		if (_sub_percentage == 0 && percentage == 100)
+			return; // can't jump from 0 -> 100 instantly!
+
+		// Only emit a percentage if it's different from the last
+		// percentage we emitted and it's divisible by ten.  We
+		// don't want to overload dbus/GUI.  Also account for the
+		// fact that libzypp may skip over a "divisible by ten"
+		// value (i.e., 28, 29, 31, 32).
+
+		// Drop off the least significant digit
+		// TODO: Figure out a faster way to drop the least significant digit
+		percentage = (percentage / 10) * 10;
+
+		if (percentage <= _sub_percentage)
+			return;
+
+		_sub_percentage = percentage;
+		pk_backend_change_sub_percentage (_backend, _sub_percentage);
+	}
+
+	void
+	reset_sub_percentage ()
+	{
+		_sub_percentage = 0;
+		pk_backend_change_sub_percentage (_backend, _sub_percentage);
+	}
+};
+
+struct InstallResolvableReportReceiver : public zypp::callback::ReceiveReport<zypp::target::rpm::InstallResolvableReport>, ZyppBackendReceiver
+{
+	zypp::Resolvable::constPtr _resolvable;
+
+	virtual void start (zypp::Resolvable::constPtr resolvable)
+	{
+		clear_package_id ();
+		_package_id = build_package_id_from_resolvable (resolvable);
+		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::start(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
+		if (_package_id != NULL) {
+			pk_backend_change_status (_backend, PK_STATUS_ENUM_INSTALL);
+			pk_backend_package (_backend, PK_INFO_ENUM_INSTALLING, _package_id, "TODO: Put the package summary here if possible");
+			reset_sub_percentage ();
+		}
+	}
+
+	virtual bool progress (int value, zypp::Resolvable::constPtr resolvable)
+	{
+		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
+		if (_package_id != NULL)
+			update_sub_percentage (value);
+		return true;
+	}
+
+	virtual Action problem (zypp::Resolvable::constPtr resolvable, Error error, const std::string &description, RpmLevel level)
+	{
+		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::problem()\n\n");
+		return ABORT;
+	}
+
+	virtual void finish (zypp::Resolvable::constPtr resolvable, Error error, const std::string &reason, RpmLevel level)
+	{
+		fprintf (stderr, "\n\n----> InstallResolvableReportReceiver::finish(): %s\n\n", _package_id == NULL ? "unknown" : _package_id);
+		if (_package_id != NULL) {
+			pk_backend_package (_backend, PK_INFO_ENUM_INSTALLED, _package_id, "TODO: Put the package summary here if possible");
+			clear_package_id ();
+		}
+	}
+};
+
+struct RepoProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::ProgressReport>, ZyppBackendReceiver
+{
+	virtual void start (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::start()\n\n");
+	}
+
+	virtual bool progress (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::progress(), %s:%d\n\n", data.name().c_str(), (int)data.val());
+		return true;
+	}
+
+	virtual void finish (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoProgressReportReceiver::finish()\n\n");
+	}
+};
+
+struct RepoReportReceiver : public zypp::callback::ReceiveReport<zypp::repo::RepoReport>, ZyppBackendReceiver
+{
+	virtual void start (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoReportReceiver::start()\n");
+	}
+
+	virtual bool progress (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoReportReceiver::progress(), %s:%d\n", data.name().c_str(), (int)data.val());
+		return true;
+	}
+
+	virtual void finish (const zypp::ProgressData &data)
+	{
+		fprintf (stderr, "\n\n----> RepoReportReceiver::finish()\n");
+	}
+};
+
+struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::media::DownloadProgressReport>, ZyppBackendReceiver
+{
+	virtual void start (const zypp::Url &file, zypp::Pathname localfile)
+	{
+		clear_package_id ();
+		_package_id = build_package_id_from_url (&file);
+
+		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::start(): %s\n", _package_id == NULL ? "unknown" : _package_id);
+		if (_package_id != NULL) {
+			pk_backend_change_status (_backend, PK_STATUS_ENUM_DOWNLOAD);
+			pk_backend_package (_backend, PK_INFO_ENUM_DOWNLOADING, _package_id, "TODO: Put the package summary here if possible");
+			reset_sub_percentage ();
+		}
+	}
+
+	virtual bool progress (int value, const zypp::Url &file)
+	{
+		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
+		if (_package_id != NULL)
+			update_sub_percentage (value);
+		return true;
+	}
+
+	virtual void finish (const zypp::Url & file, Error error, const std::string &konreason)
+	{
+		fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::finish(): %s\n", _package_id == NULL ? "unknown" : _package_id);
+		clear_package_id ();
+	}
+};
+
+}; // namespace ZyppBackend
+
+class EventDirector
+{
+	private:
+		EventDirector () {}
+	
+		ZyppBackend::RepoReportReceiver _repoReport;
+		ZyppBackend::RepoProgressReportReceiver _repoProgressReport;
+		ZyppBackend::InstallResolvableReportReceiver _installResolvableReport;
+		ZyppBackend::DownloadProgressReportReceiver _downloadProgressReport;
+
+	public:
+		EventDirector (PkBackend *backend)
+		{
+			_repoReport.initWithBackend (backend);
+			_repoReport.connect ();
+
+			_repoProgressReport.initWithBackend (backend);
+			_repoProgressReport.connect ();
+
+			_installResolvableReport.initWithBackend (backend);
+			_installResolvableReport.connect ();
+
+			_downloadProgressReport.initWithBackend (backend);
+			_downloadProgressReport.connect ();
+		}
+
+		~EventDirector ()
+		{
+			_repoReport.disconnect ();
+			_repoProgressReport.disconnect ();
+			_installResolvableReport.disconnect ();
+			_downloadProgressReport.disconnect ();
+		}
+};
+
+
+#endif // _ZYPP_EVENTS_H_
+



More information about the PackageKit mailing list