[PackageKit-commit] packagekit: Branch 'master' - 14 commits

Richard Hughes hughsient at kemper.freedesktop.org
Mon Jun 9 01:19:06 PDT 2008


 backends/alpm/pk-backend-alpm.c     |  162 ++++++++++----
 backends/poldek/pk-backend-poldek.c |  346 +++++++++++-------------------
 client/pk-console.c                 |    2 
 contrib/PackageKit.catalog          |   14 +
 contrib/PackageKit.spec.in          |    8 
 contrib/gnome-packagekit.catalog    |   17 +
 contrib/gnome-packagekit.spec.in    |    7 
 data/.gitignore                     |    1 
 data/Makefile.am                    |    7 
 data/packagekit-catalog.xml.in      |    9 
 data/tests/Makefile.am              |    1 
 data/tests/test.catalog             |   16 +
 docs/example.catalog                |   16 +
 docs/html/pk-faq.html               |   71 ++++++
 docs/spec/pk-concepts.xml           |   26 ++
 libpackagekit/Makefile.am           |    3 
 libpackagekit/pk-catalog.c          |  414 ++++++++++++++++++++++++++++++++++++
 libpackagekit/pk-catalog.h          |   68 +++++
 libpackagekit/pk-self-test.c        |    2 
 po/ca.po                            |  320 +++++++++++++++++++++++++++
 20 files changed, 1244 insertions(+), 266 deletions(-)

New commits:
commit 1f55d9034e42071f50738b5c13a87be600b10e07
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Sun Jun 8 14:02:11 2008 +0200

    poldek: make UpdatePackages and UpdateSystem use update_packages_thread()

diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index 0ecf1f1..f6c6ca2 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -42,6 +42,10 @@ static gint do_get_files_to_download (const struct poldek_ts *ts, const gchar *m
 static void pb_load_packages (PkBackend *backend);
 static void poldek_backend_set_allow_cancel (PkBackend *backend, gboolean allow_cancel, gboolean reset);
 
+static void pb_error_show (PkBackend *backend, PkErrorCodeEnum errorcode);
+static void pb_error_clean (void);
+static void poldek_backend_percentage_data_destroy (PkBackend *backend);
+
 typedef enum {
 	TS_TYPE_ENUM_INSTALL,
 	TS_TYPE_ENUM_UPDATE,
@@ -101,7 +105,6 @@ typedef struct {
 	gint		filesdownload;
 
 	gint		percentage;
-	float		stepvalue;
 
 	gint		subpercentage;
 } PercentageData;
@@ -247,10 +250,9 @@ poldek_vf_progress (void *bar, long total, long amount)
 {
 	PkBackend	*backend = (PkBackend*) bar;
 	PercentageData	*pd = pk_backend_get_pointer (backend, "percentage_ptr");
-	guint		percentage = 0;
 	guint ts_type = pk_backend_get_uint (backend, "ts_type");
 
-	if (ts_type == TS_TYPE_ENUM_INSTALL) {
+	if (ts_type == TS_TYPE_ENUM_INSTALL || ts_type == TS_TYPE_ENUM_UPDATE) {
 		float	frac = (float)amount / (float)total;
 
 		/* file already downloaded */
@@ -264,20 +266,6 @@ poldek_vf_progress (void *bar, long total, long amount)
 			pd->percentage = (gint)(((float)(pd->bytesget + amount) / (float)pd->bytesdownload) * 100);
 			pd->subpercentage = (gint)(frac * 100);
 		}
-	} else if (ts_type == TS_TYPE_ENUM_UPDATE) {
-		float	stepfrac = pd->stepvalue / (float)pd->filesdownload;
-
-		/* file already downloaded */
-		if ((float)amount / (float)total < 0) {
-			pd->bytesget += total;
-			pd->filesget++;
-
-			pd->subpercentage = (gint)((float)pd->bytesget / (float)pd->bytesdownload * 100);
-			percentage = (guint)(stepfrac * (float)pd->filesget);
-		} else {
-			pd->subpercentage = (gint)((float)(pd->bytesget + amount) / (float)pd->bytesdownload * 100);
-			percentage = (guint)(stepfrac * ((float)pd->filesget + ((float)pd->subpercentage / (float)100)));
-		}
 	} else if (ts_type == TS_TYPE_ENUM_REFRESH_CACHE) {
 		if (pd->step == 0)
 			pd->percentage = 1;
@@ -285,12 +273,7 @@ poldek_vf_progress (void *bar, long total, long amount)
 			pd->percentage = (gint)(((float)pd->step / (float)pd->nsources) * 100);
 	}
 
-	if (ts_type == TS_TYPE_ENUM_INSTALL ||
-	    ts_type == TS_TYPE_ENUM_REFRESH_CACHE)
-		pk_backend_set_percentage (backend, pd->percentage);
-	else if (ts_type == TS_TYPE_ENUM_UPDATE)
-		if ((pd->percentage + percentage) > 1)
-			pk_backend_set_percentage (backend, pd->percentage + percentage);
+	pk_backend_set_percentage (backend, pd->percentage);
 
 	/* RefreshCache doesn't use subpercentage */
 	if (ts_type == TS_TYPE_ENUM_INSTALL ||
@@ -373,7 +356,7 @@ ts_confirm (void *data, struct poldek_ts *ts)
 
 	switch (poldek_ts_get_type (ts)) {
 		case POLDEK_TS_TYPE_INSTALL:
-			upkgs = n_array_new (2, NULL, NULL);
+			upkgs = n_array_new (4, (tn_fn_free)pkg_free, NULL);
 
 			pd->step = 0;
 
@@ -474,14 +457,9 @@ ts_confirm (void *data, struct poldek_ts *ts)
 			break;
 	}
 
-	if (ipkgs)
-		n_array_free (ipkgs);
-
-	if (dpkgs)
-		n_array_free (dpkgs);
-
-	if (rpkgs)
-		n_array_free (rpkgs);
+	n_array_cfree (&ipkgs);
+	n_array_cfree (&dpkgs);
+	n_array_cfree (&rpkgs);
 
 	return result;
 }
@@ -491,7 +469,7 @@ ts_confirm (void *data, struct poldek_ts *ts)
  **/
 static gint
 suggests_callback (void *data, const struct poldek_ts *ts, const struct pkg *pkg,
-				   tn_array *caps, tn_array *choices, int hint)
+		   tn_array *caps, tn_array *choices, int hint)
 {
 	/* install all suggested packages */
 	return 1;
@@ -835,7 +813,8 @@ do_newest (tn_array *pkgs)
  * do_requires:
  */
 static void
-do_requires (tn_array *installed, tn_array *available, tn_array *requires, struct pkg *pkg, PkBackend *backend)
+do_requires (tn_array *installed, tn_array *available, tn_array *requires,
+	     struct pkg *pkg, PkBackend *backend)
 {
 	tn_array	*tmp = NULL;
 	gint		i;
@@ -1346,6 +1325,106 @@ search_package_thread (PkBackend *backend)
 	return TRUE;
 }
 
+static gboolean
+update_packages_thread (PkBackend *backend)
+{
+	struct vf_progress	vf_progress;
+	gboolean		update_system;
+	guint			i, toupdate = 0;
+	gchar **package_ids, *command;
+	GString *cmd;
+
+	update_system = pk_backend_get_bool (backend, "update_system");
+	package_ids = pk_backend_get_strv (backend, "package_ids");
+
+	/* sth goes wrong. package_ids has to be set in UpdatePackages */
+	if (update_system == FALSE && package_ids == NULL) {
+		pk_warning ("package_ids cannot be NULL in UpdatePackages method.");
+		pk_backend_finished (backend);
+		return TRUE;
+	}
+
+	setup_vf_progress (&vf_progress, backend);
+
+	pb_load_packages (backend);
+
+	pk_backend_set_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
+	pb_error_clean ();
+
+	cmd = g_string_new ("upgrade ");
+
+	if (update_system) {
+		struct poclidek_rcmd *rcmd;
+
+		rcmd = poclidek_rcmd_new (cctx, NULL);
+
+		if (poclidek_rcmd_execline (rcmd, "cd /all-avail; ls -q -u")) {
+			tn_array *pkgs;
+
+			pkgs = poclidek_rcmd_get_packages (rcmd);
+
+			/* UpdateSystem updates to the newest available packages */
+			do_newest (pkgs);
+
+			for (i = 0; i < n_array_size (pkgs); i++) {
+				struct pkg *pkg;
+
+				pkg = n_array_nth (pkgs, i);
+
+				/* don't try to update blocked packages */
+				if (!(pkg->flags & PKG_HELD)) {
+					g_string_append_printf (cmd, "%s-%s-%s.%s ", pkg->name,
+								pkg->ver, pkg->rel, pkg_arch (pkg));
+
+					toupdate++;
+				}
+			}
+
+			n_array_free (pkgs);
+		}
+
+		poclidek_rcmd_free (rcmd);
+	} else {
+		for (i = 0; i < g_strv_length (package_ids); i++) {
+			struct pkg *pkg;
+
+			pkg = poldek_get_pkg_from_package_id (package_ids[i]);
+
+			g_string_append_printf (cmd, "%s-%s-%s.%s ", pkg->name,
+						pkg->ver, pkg->rel, pkg_arch (pkg));
+
+			toupdate++;
+
+			pkg_free (pkg);
+		}
+	}
+
+	command = g_string_free (cmd, FALSE);
+
+	if (toupdate > 0) {
+		struct poclidek_rcmd *rcmd;
+		struct poldek_ts *ts;
+
+		ts = poldek_ts_new (ctx, 0);
+		rcmd = poclidek_rcmd_new (cctx, ts);
+
+		ts->setop(ts, POLDEK_OP_PARTICLE, 0);
+
+		if (!poclidek_rcmd_execline (rcmd, command))
+			pb_error_show (backend, PK_ERROR_ENUM_TRANSACTION_ERROR);
+
+		poclidek_rcmd_free (rcmd);
+		poldek_ts_free (ts);
+	}
+
+	poldek_backend_percentage_data_destroy (backend);
+
+	g_free (command);
+
+	pk_backend_finished (backend);
+	return TRUE;
+}
+
 static void
 pb_load_packages (PkBackend *backend)
 {
@@ -1505,6 +1584,7 @@ do_poldek_init (PkBackend *backend)
 	/* (...), but we don't need choose_equiv callback */
 	poldek_configure (ctx, POLDEK_CONF_OPT, POLDEK_OP_EQPKG_ASKUSER, 0);
 
+	poldek_configure (ctx, POLDEK_CONF_TSCONFIRM_CB, ts_confirm, backend);
 	/* Install all suggested packages by default */
 	poldek_configure (ctx, POLDEK_CONF_CHOOSESUGGESTS_CB, suggests_callback, NULL);
 
@@ -2052,9 +2132,6 @@ backend_install_packages_thread (PkBackend *backend)
 
 	pb_load_packages (backend);
 
-	/* setup callbacks */
-	poldek_configure (ctx, POLDEK_CONF_TSCONFIRM_CB, ts_confirm, backend);
-
 	ts = poldek_ts_new (ctx, 0);
 	rcmd = poclidek_rcmd_new (cctx, ts);
 
@@ -2196,9 +2273,6 @@ backend_remove_packages_thread (PkBackend *backend)
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 	pb_load_packages (backend);
 
-	/* setup callbacks */
-	poldek_configure (ctx, POLDEK_CONF_TSCONFIRM_CB, ts_confirm, backend);
-
 	ts = poldek_ts_new (ctx, 0);
 	rcmd = poclidek_rcmd_new (cctx, ts);
 
@@ -2306,85 +2380,6 @@ backend_search_name (PkBackend *backend, PkFilterEnum filters, const gchar *sear
 /**
  * backend_update_packages:
  */
-static gboolean
-backend_update_packages_thread (PkBackend *backend)
-{
-	struct poldek_ts	*ts;
-	struct poclidek_rcmd	*rcmd;
-	struct vf_progress	vf_progress;
-	guint			i;
-	gboolean		update_cancelled = FALSE;
-	PercentageData *pd = pk_backend_get_pointer (backend, "percentage_ptr");
-	gchar **package_ids;
-
-	package_ids = pk_backend_get_strv (backend, "package_ids");
-
-	setup_vf_progress (&vf_progress, backend);
-
-	pb_load_packages (backend);
-
-	/* setup callbacks */
-	poldek_configure (ctx, POLDEK_CONF_TSCONFIRM_CB, ts_confirm, backend);
-
-	pk_backend_set_percentage (backend, 1);
-	pd->stepvalue = (float)100 / (float)g_strv_length (package_ids);
-
-	for (i = 0; i < g_strv_length (package_ids); i++) {
-		struct pkg	*pkg = NULL;
-
-		pk_backend_set_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
-		pb_error_clean ();
-
-		pk_backend_set_sub_percentage (backend, 0);
-
-		pkg = poldek_get_pkg_from_package_id (package_ids[i]);
-
-		/* don't try to update blocked packages */
-		if (!(pkg->flags & PKG_HELD)) {
-			gchar	*command, *nvra;
-
-			ts = poldek_ts_new (ctx, 0);
-			rcmd = poclidek_rcmd_new (cctx, ts);
-
-			nvra = poldek_get_nvra_from_package_id (package_ids[i]);
-			command = g_strdup_printf ("upgrade %s", nvra);
-
-			if (!poclidek_rcmd_execline (rcmd, command)) {
-				pb_error_show (backend, PK_ERROR_ENUM_TRANSACTION_ERROR);
-
-				update_cancelled = TRUE;
-			} else {
-				/* allow_cancel is disabled in ts_confirm () */
-				poldek_backend_set_allow_cancel (backend, TRUE, FALSE);
-			}
-
-			g_free (nvra);
-			g_free (command);
-
-			poclidek_rcmd_free (rcmd);
-			poldek_ts_free (ts);
-
-			if (update_cancelled)
-				break;
-		}
-
-		pd->percentage = (gint)((float)(i + 1) * pd->stepvalue);
-
-		if (pd->percentage > 1)
-			pk_backend_set_percentage (backend, pd->percentage);
-
-		pkg_free (pkg);
-	}
-
-	if (!update_cancelled)
-		pk_backend_set_percentage (backend, 100);
-
-	poldek_backend_percentage_data_destroy (backend);
-
-	pk_backend_finished (backend);
-	return TRUE;
-}
-
 static void
 backend_update_packages (PkBackend *backend, gchar **package_ids)
 {
@@ -2399,109 +2394,12 @@ backend_update_packages (PkBackend *backend, gchar **package_ids)
 
 	poldek_backend_percentage_data_create (backend);
 	pk_backend_set_uint (backend, "ts_type", TS_TYPE_ENUM_UPDATE);
-	pk_backend_thread_create (backend, backend_update_packages_thread);
+	pk_backend_thread_create (backend, update_packages_thread);
 }
 
 /**
  * backend_update_system:
  **/
-static gboolean
-backend_update_system_thread (PkBackend *backend)
-{
-	struct vf_progress	vf_progress;
-	struct poldek_ts	*ts;
-	struct poclidek_rcmd	*rcmd;
-	tn_array		*upkgs;
-	gint			i;
-	gboolean		update_cancelled = FALSE;
-	PercentageData *pd = pk_backend_get_pointer (backend, "percentage_ptr");
-
-	setup_vf_progress (&vf_progress, backend);
-
-	pb_load_packages (backend);
-
-	/* setup callbacks */
-	poldek_configure (ctx, POLDEK_CONF_TSCONFIRM_CB, ts_confirm, backend);
-
-	/* get packages to update */
-	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-
-	rcmd = poclidek_rcmd_new (cctx, NULL);
-
-	if (poclidek_rcmd_execline (rcmd, "cd /all-avail; ls -q -u")) {
-		upkgs = poclidek_rcmd_get_packages (rcmd);
-
-		/* return only the newest packages */
-		do_newest (upkgs);
-
-		/* remove from array packages marked as blocked */
-		i = 0;
-
-		while (i < n_array_size (upkgs)) {
-			struct pkg	*pkg = n_array_nth (upkgs, i);
-
-			if (pkg->flags & PKG_HELD) {
-				n_array_remove_nth (upkgs, i);
-				continue;
-			}
-
-			i++;
-		}
-
-		poclidek_rcmd_free (rcmd);
-
-		/* start */
-		pk_backend_set_percentage (backend, 1);
-		pd->stepvalue = (float)100 / (float)n_array_size (upkgs);
-
-		for (i = 0; i < n_array_size (upkgs); i++) {
-			struct pkg	*pkg = n_array_nth (upkgs, i);
-			gchar		*command;
-
-			pk_backend_set_status (backend, PK_STATUS_ENUM_DEP_RESOLVE);
-
-			pb_error_clean ();
-
-			pk_backend_set_sub_percentage (backend, 0);
-
-			ts = poldek_ts_new (ctx, 0);
-			rcmd = poclidek_rcmd_new (cctx, ts);
-
-			command = g_strdup_printf ("upgrade %s-%s-%s.%s", pkg->name, pkg->ver, pkg->rel, pkg_arch (pkg));
-
-			if (!poclidek_rcmd_execline (rcmd, command)) {
-				pb_error_show (backend, PK_ERROR_ENUM_TRANSACTION_ERROR);
-
-				update_cancelled = TRUE;
-			} else {
-				/* allow_cancel is disabled in ts_confirm () */
-				poldek_backend_set_allow_cancel (backend, TRUE, FALSE);
-			}
-
-			g_free (command);
-
-			poclidek_rcmd_free (rcmd);
-			poldek_ts_free (ts);
-
-			if (update_cancelled)
-				break;
-		}
-
-		pd->percentage = (gint)((float)(i + 1) * pd->stepvalue);
-
-		if (pd->percentage > 1)
-			pk_backend_set_percentage (backend, pd->percentage);
-	}
-
-	if (!update_cancelled)
-		pk_backend_set_percentage (backend, 100);
-
-	poldek_backend_percentage_data_destroy (backend);
-
-	pk_backend_finished (backend);
-	return TRUE;
-}
-
 static void
 backend_update_system (PkBackend *backend)
 {
@@ -2516,7 +2414,8 @@ backend_update_system (PkBackend *backend)
 
 	poldek_backend_percentage_data_create (backend);
 	pk_backend_set_uint (backend, "ts_type", TS_TYPE_ENUM_UPDATE);
-	pk_backend_thread_create (backend, backend_update_system_thread);
+	pk_backend_set_bool (backend, "update_system", TRUE);
+	pk_backend_thread_create (backend, update_packages_thread);
 }
 
 /**
commit 2b94d835d0967b26f9f387c16f2a673762175071
Merge: 86fdd6a... 78d655d...
Author: Xavier Conde <xavi.conde at gmail.com>
Date:   Sat Jun 7 21:10:09 2008 +0000

    Merge branch 'master' of git+ssh://transif@git.packagekit.org/srv/git/PackageKit

commit 86fdd6a99e61d813a8e855e186ca6c62d595e816
Author: Xavier Conde <xavi.conde at gmail.com>
Date:   Sat Jun 7 21:10:04 2008 +0000

    2008-06-07  Xavier Conde <xavi.conde at gmail.com> (via xconde at fedoraproject.org)
    
      * po/ca.po: Added Catalan translation by xconde

diff --git a/po/ca.po b/po/ca.po
new file mode 100644
index 0000000..fe8b47c
--- /dev/null
+++ b/po/ca.po
@@ -0,0 +1,320 @@
+# Catalan translations for packagekit package.
+# Copyright (C) 2008 Red Hat, Inc.
+# This file is distributed under the same license as the
+#  packagekit package.
+#
+# Pere Argelich <bakidok at gmail.com>, 2008
+#
+# This file is translated according to the glossary and style guide of
+#   Softcatalà. If you plan to modify this file, please read first the page
+#   of the Catalan translation team for the Fedora project at:
+#   http://www.softcatala.org/projectes/fedora/
+#   and contact the previous translator
+#
+# Aquest fitxer s'ha de traduir d'acord amb el recull de termes i la guia
+#   d'estil de Softcatalà. Si voleu modificar aquest fitxer, llegiu si
+#   us plau la pàgina de catalanització del projecte Fedora a:
+#   http://www.softcatala.org/projectes/fedora/
+#   i contacteu l'anterior traductor/a.
+msgid ""
+msgstr ""
+"Project-Id-Version: packagekit\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2008-06-06 16:45+0100\n"
+"Last-Translator: Pere Argelich <bakidok at gmail.com>\n"
+"Language-Team: Catalan <fedora at softcatala.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../client/pk-console.c:224
+msgid "Update detail"
+msgstr "Detalls de l'actualització"
+
+#: ../client/pk-console.c:425
+msgid "A system restart is required"
+msgstr "Es requereix reiniciar el sistema"
+
+#: ../client/pk-console.c:427
+msgid "A logout and login is required"
+msgstr "Es requereix sortir de la sessió"
+
+#: ../client/pk-console.c:429
+msgid "An application restart is required"
+msgstr "Es requereix reiniciar l'aplicació"
+
+#: ../client/pk-console.c:474
+#, c-format
+msgid "Please enter a number from 1 to %i: "
+msgstr "Si us plau, introduïu un valor d'1 a %i:"
+
+#: ../client/pk-console.c:524
+msgid "Could not find a package match"
+msgstr "No s'han trobat coincidències en cap paquet"
+
+#: ../client/pk-console.c:538
+msgid "There are multiple package matches"
+msgstr "Existeixen coincidències amb múltiples paquets"
+
+#. find out what package the user wants to use
+#: ../client/pk-console.c:545
+msgid "Please enter the package number: "
+msgstr "Si us plau, introduïu el número de paquet:"
+
+#: ../client/pk-console.c:561
+msgid "Could not find a package with that name to install, or package already installed"
+msgstr "No s'ha pogut trobar un paquet amb aquest nom per instal·lar, o el paquet ja es troba instal·lat"
+
+#: ../client/pk-console.c:643
+msgid "Could not find a package with that name to remove"
+msgstr "No s'ha pogut trobar un paquet amb aquest nom per eliminar"
+
+#: ../client/pk-console.c:683
+msgid "The following packages have to be removed"
+msgstr "Els següents paquets seran eliminats"
+
+#. get user input
+#: ../client/pk-console.c:692
+msgid "Okay to remove additional packages?"
+msgstr "Esteu d'acord en eliminar els paquets adicionals?"
+
+#: ../client/pk-console.c:696
+msgid "Cancelled!"
+msgstr "Cancel·lat"
+
+#: ../client/pk-console.c:718
+msgid "Could not find a package with that name to update"
+msgstr "No s'ha pogut trobar un paquet amb aquest nom per actualitzar"
+
+#: ../client/pk-console.c:736
+msgid "Could not find what packages require this package"
+msgstr "No s'han pogut trobar els paquets requerits per a aquest paquet"
+
+#: ../client/pk-console.c:754
+msgid "Could not get dependencies for this package"
+msgstr "No s'han pogut obtenir les dependències per a aquest paquet"
+
+#: ../client/pk-console.c:772
+msgid "Could not find details for this package"
+msgstr "No s'han pogut trobar els detalls per a aquest paquet"
+
+#: ../client/pk-console.c:790
+msgid "Could not find the files for this package"
+msgstr "No s'han pogut trobar els fitxers per a aquest paquet"
+
+#: ../client/pk-console.c:870
+msgid "Package description"
+msgstr "Descripció del paquet"
+
+#: ../client/pk-console.c:893
+msgid "Package files"
+msgstr "Fitxers del paquet"
+
+#: ../client/pk-console.c:901
+msgid "No files"
+msgstr "No hi ha fitxers"
+
+#. get user input
+#: ../client/pk-console.c:933
+msgid "Okay to import key?"
+msgstr "Esteu d'acord en importar la clau?"
+
+#: ../client/pk-console.c:936
+msgid "Did not import key"
+msgstr "No importis la clau"
+
+#. get user input
+#: ../client/pk-console.c:976
+msgid "Do you agree?"
+msgstr "Esteu d'acord?"
+
+#: ../client/pk-console.c:979
+msgid "Did not agree to licence, task will fail"
+msgstr "La llicència no ha estat acceptada, la tasca fallarà"
+
+#: ../client/pk-console.c:1008
+msgid "The daemon crashed mid-transaction!"
+msgstr "El servei ha fallat a meitat de la transacció!"
+
+#. header
+#: ../client/pk-console.c:1061
+msgid "PackageKit Console Interface"
+msgstr "Interfície de consola de PackageKit"
+
+#: ../client/pk-console.c:1061
+msgid "Subcommands:"
+msgstr "Subordres:"
+
+#: ../client/pk-console.c:1165
+#: ../client/pk-monitor.c:104
+#: ../src/pk-main.c:189
+msgid "Show extra debugging information"
+msgstr "Mostra la informació extra de la depuració"
+
+#: ../client/pk-console.c:1167
+#: ../client/pk-monitor.c:106
+msgid "Show the program version and exit"
+msgstr "Mostra la versió del programa i surt"
+
+#: ../client/pk-console.c:1169
+msgid "Set the filter, e.g. installed"
+msgstr "Defineix el filtre, p.ex. instal·lat"
+
+#: ../client/pk-console.c:1171
+msgid "Exit without waiting for actions to complete"
+msgstr "Surt sense esperar que es completin les accions"
+
+#: ../client/pk-console.c:1194
+msgid "Could not connect to system DBUS."
+msgstr "No s'ha pogut connectar al sistema DBUS."
+
+#: ../client/pk-console.c:1288
+msgid "You need to specify a search type"
+msgstr "Cal que especifiqueu un tipus de cerca"
+
+#: ../client/pk-console.c:1293
+#: ../client/pk-console.c:1300
+#: ../client/pk-console.c:1307
+#: ../client/pk-console.c:1314
+#: ../client/pk-console.c:1421
+#: ../client/pk-console.c:1428
+#: ../client/pk-console.c:1435
+#: ../client/pk-console.c:1442
+msgid "You need to specify a search term"
+msgstr "Cal que especifiqueu un terme per a la cerca"
+
+#: ../client/pk-console.c:1319
+msgid "Invalid search type"
+msgstr "El tipus de cerca no és vàlid"
+
+#: ../client/pk-console.c:1324
+msgid "You need to specify a package or file to install"
+msgstr "Cal que especifiqueu un paquet o un fitxer a instal·lar"
+
+#: ../client/pk-console.c:1339
+msgid "You need to specify a type, key_id and package_id"
+msgstr "Cal que especifiqueu un tipus, un identificador de clau i un identificador de paquet"
+
+#: ../client/pk-console.c:1346
+msgid "You need to specify a package to remove"
+msgstr "Cal que especifiqueu un paquet a eliminar"
+
+#: ../client/pk-console.c:1353
+msgid "You need to specify a eula-id"
+msgstr "Cal que especifiqueu un identificador de EULA"
+
+#: ../client/pk-console.c:1369
+msgid "You need to specify a package name to resolve"
+msgstr "Cal que especifiqueu un nom de paquet a resoldre"
+
+#: ../client/pk-console.c:1376
+#: ../client/pk-console.c:1383
+msgid "You need to specify a repo name"
+msgstr "Cal que especifiqueu un nom de repositori"
+
+#: ../client/pk-console.c:1390
+msgid "You need to specify a repo name/parameter and value"
+msgstr "Cal que especifiqueu un nom / paràmetre de repositori i un valor"
+
+#: ../client/pk-console.c:1403
+msgid "You need to specify a time term"
+msgstr "Cal que especifiqueu un valor per a l'hora"
+
+#: ../client/pk-console.c:1408
+msgid "You need to specify a correct role"
+msgstr "Cal que especifiqueu un rol correcte"
+
+#: ../client/pk-console.c:1413
+msgid "Failed to get last time"
+msgstr "S'ha produït un error en obtenir l'última hora"
+
+#: ../client/pk-console.c:1449
+msgid "You need to specify a package to find the details for"
+msgstr "Cal que especifiqueu un paquet per cercar-ne els detalls"
+
+#: ../client/pk-console.c:1456
+msgid "You need to specify a package to find the files for"
+msgstr "Cal que especifiqueu un paquet per cercar-ne fitxers"
+
+#: ../client/pk-console.c:1503
+#, c-format
+msgid "Option '%s' not supported"
+msgstr "L'opció '%s' no està disponible"
+
+#: ../client/pk-console.c:1514
+msgid "Command failed"
+msgstr "L'ordre ha fallat"
+
+#: ../client/pk-console.c:1518
+msgid "You don't have the necessary privileges for this operation"
+msgstr "No teniu suficients privilegis per a aquesta operació"
+
+#: ../client/pk-monitor.c:117
+msgid "PackageKit Monitor"
+msgstr "Monitorització de Packagekit"
+
+#: ../client/pk-import-desktop.c:293
+#: ../client/pk-import-specspo.c:169
+#, c-format
+msgid "Could not open database: %s"
+msgstr "No s'ha pogut obrir la base de dades: %s"
+
+#: ../client/pk-import-desktop.c:294
+#: ../client/pk-import-specspo.c:170
+msgid "You probably need to run this program as the root user"
+msgstr "És probable que necessiteu executar aquesta aplicació com a administrador"
+
+#: ../src/pk-main.c:83
+msgid "Startup failed due to security policies on this machine."
+msgstr "L'inici ha fallat a causa de les polítiques de seguretat d'aquesta màquina."
+
+#: ../src/pk-main.c:84
+msgid "This can happen for two reasons:"
+msgstr "Això pot succeir per dos raons:"
+
+#: ../src/pk-main.c:85
+msgid "The correct user is not launching the executable (usually root)"
+msgstr "Un usuari incorrecte està executant l'aplicació (normalment és el superusuari root)"
+
+#: ../src/pk-main.c:86
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system /etc/dbus-1/system.d directory"
+msgstr "El fitxer org.freedesktop.PackageKit.conf no està instal·lat al directori del sistema /etc/dbus-1/system.d"
+
+#: ../src/pk-main.c:185
+msgid "Packaging backend to use, e.g. dummy"
+msgstr "Administrador de paquets a usar, p.ex. dummy"
+
+#: ../src/pk-main.c:187
+msgid "Daemonize and detach from the terminal"
+msgstr "Inicia el servei i separa del terminal"
+
+#: ../src/pk-main.c:191
+msgid "Disable the idle timer"
+msgstr "Desactiva el temporitzador d'inactivitat"
+
+#: ../src/pk-main.c:193
+msgid "Show version and exit"
+msgstr "Mostra la versió i surt"
+
+#: ../src/pk-main.c:195
+msgid "Exit after a small delay"
+msgstr "Surt després d'una petita pausa"
+
+#: ../src/pk-main.c:197
+msgid "Exit after the engine has loaded"
+msgstr "Surt després de que el motor s'hagi cargat"
+
+#: ../src/pk-main.c:207
+msgid "PackageKit service"
+msgstr "Servei del PackageKit"
+
+#: ../src/pk-main.c:233
+msgid "Cannot connect to the system bus"
+msgstr "No s'ha pogut connectar al bus del sistema"
+
+#: ../src/pk-main.c:273
+#, c-format
+msgid "Error trying to start: %s\n"
+msgstr "S'ha produït un error en intentar iniciar: %s\n"
+
commit 78d655da9e1223d05392b82d23d9df5a25cc609f
Author: Marcin Banasiak <megabajt at pld-linux.org>
Date:   Fri Jun 6 22:02:56 2008 +0200

    poldek: install all suggested packages

diff --git a/backends/poldek/pk-backend-poldek.c b/backends/poldek/pk-backend-poldek.c
index efe1c74..0ecf1f1 100644
--- a/backends/poldek/pk-backend-poldek.c
+++ b/backends/poldek/pk-backend-poldek.c
@@ -487,6 +487,16 @@ ts_confirm (void *data, struct poldek_ts *ts)
 }
 
 /**
+ * suggests_callback:
+ **/
+static gint
+suggests_callback (void *data, const struct poldek_ts *ts, const struct pkg *pkg,
+				   tn_array *caps, tn_array *choices, int hint)
+{
+	/* install all suggested packages */
+	return 1;
+}
+/**
  * setup_vf_progress:
  */
 static void
@@ -1495,6 +1505,9 @@ do_poldek_init (PkBackend *backend)
 	/* (...), but we don't need choose_equiv callback */
 	poldek_configure (ctx, POLDEK_CONF_OPT, POLDEK_OP_EQPKG_ASKUSER, 0);
 
+	/* Install all suggested packages by default */
+	poldek_configure (ctx, POLDEK_CONF_CHOOSESUGGESTS_CB, suggests_callback, NULL);
+
 	sigint_init ();
 }
 
commit acb1a0afe186328773d1e74ef33e69b73a2916f4
Author: Valeriy Lyasotskiy <onestep at ukr.net>
Date:   Fri Jun 6 20:38:16 2008 +0300

    alpm: fixes related to local/installed things change

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index 467e8c6..fd9041b 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -27,6 +27,7 @@
 #define ALPM_LOGFILE "/var/log/pacman.log"
 
 #define ALPM_PKG_EXT ".pkg.tar.gz"
+#define ALPM_LOCAL_DB_ALIAS "installed"
 
 #define ALPM_PROGRESS_UPDATE_INTERVAL 400
 
@@ -48,7 +49,7 @@
 int progress_percentage;
 int subprogress_percentage;
 PkBackend *backend_instance = NULL;
-char *dl_file_name;
+gchar *dl_file_name;
 
 GHashTable *group_mapping;
 
@@ -82,7 +83,7 @@ pkg_from_package_id_str (const gchar *package_id_str)
 
 	/* do all this fancy stuff */
 	pmdb_t *repo = NULL;
-	if (strcmp ("local", pkg_id->data) == 0)
+	if (strcmp ("installed", pkg_id->data) == 0)
 		repo = alpm_option_get_localdb ();
 	else {
 		alpm_list_t *iterator;
@@ -109,19 +110,41 @@ void
 cb_trans_evt (pmtransevt_t event, void *data1, void *data2)
 {
 	// TODO: Add more code here
+	gchar **package_ids;
+	gchar *package_id_needle;
 	gchar *package_id_str;
+	GString *package_id_builder;
 
 	switch (event) {
 		case PM_TRANS_EVT_REMOVE_START:
-			package_id_str = pkg_to_package_id_str (data1, "local");
+			package_id_str = pkg_to_package_id_str (data1, ALPM_LOCAL_DB_ALIAS);
 			pk_backend_package (backend_instance, PK_INFO_ENUM_REMOVING, package_id_str, alpm_pkg_get_desc (data1));
 			g_free (package_id_str);
 			break;
 		case PM_TRANS_EVT_ADD_START:
-			package_id_str = pkg_to_package_id_str (data1, "local");
-			pk_backend_package (backend_instance, PK_INFO_ENUM_INSTALLING, package_id_str, alpm_pkg_get_desc (data1));
 			pk_backend_set_status (backend_instance, PK_STATUS_ENUM_INSTALL);
-			g_free (package_id_str);
+			package_id_needle = pkg_to_package_id_str (data1, "");
+			pk_debug ("needle is %s", package_id_needle);
+			package_ids = pk_backend_get_strv (backend_instance, "package_ids");
+
+			if (package_ids != NULL) {
+				/* search for this package in package_ids */
+				int iterator;
+				for (iterator = 0; iterator < g_strv_length (package_ids); ++iterator)
+					if (strstr (package_ids[iterator], package_id_needle) != NULL) {
+						pk_backend_package (backend_instance, PK_INFO_ENUM_INSTALLING, package_ids[iterator], alpm_pkg_get_desc (data1));
+						break;
+					}
+			} else {
+				/* we are installing a local file */
+				package_id_builder = g_string_new (package_id_needle);
+				g_string_append (package_id_builder, "local");
+				gchar *package_id_str = g_string_free (package_id_builder, FALSE);
+				pk_backend_package (backend_instance, PK_INFO_ENUM_INSTALLING, package_id_str, alpm_pkg_get_desc (data1));
+				g_free (package_id_str);
+			}
+
+			g_free (package_id_needle);
 			break;
 		case PM_TRANS_EVT_UPGRADE_START:
 			package_id_str = pkg_to_package_id_str (data1, "local");
@@ -149,24 +172,29 @@ cb_trans_progress (pmtransprog_t event, const char *pkgname, int percent, int ho
 void
 cb_dl_progress (const char *filename, int file_xfered, int file_total, int list_xfered, int list_total)
 {
-	/* check if we already processed this file name */
-	if (dl_file_name == NULL || strcmp (filename, dl_file_name) != 0) {
-		pk_debug ("alpm: downloading file %s", filename);
+	if (file_xfered == file_total) {
+		/* free filename copy when file is downloaded */
 		g_free (dl_file_name);
-		dl_file_name = strdup(filename);
-
-		/* check if downloaded file is a package */
-		if (strstr (filename, ALPM_PKG_EXT) != NULL) {
-			/* all this stuff is a bit dirty */
-			gchar **package_ids = pk_backend_get_strv (backend_instance, "package_ids");
-
-			int iterator;
-			for (iterator = 0; iterator < g_strv_length (package_ids); ++iterator) {
-				pmpkg_t *pkg = pkg_from_package_id_str (package_ids[iterator]);
-				const char *pkg_filename = alpm_pkg_get_filename (pkg);
-				if (strcmp (pkg_filename, filename) == 0) {
-					pk_backend_package (backend_instance, PK_INFO_ENUM_DOWNLOADING, package_ids[iterator], alpm_pkg_get_desc (pkg));
-					break;
+		dl_file_name = NULL;
+	} else {
+		if (dl_file_name == NULL) {
+			/* we download new file, let's process it */
+			pk_debug ("alpm: downloading file %s", filename);
+			dl_file_name = g_strdup(filename);
+
+			/* check if downloaded file is a package */
+			if (strstr (filename, ALPM_PKG_EXT) != NULL) {
+				/* search for this package in package_ids */
+				gchar **package_ids = pk_backend_get_strv (backend_instance, "package_ids");
+
+				int iterator;
+				for (iterator = 0; iterator < g_strv_length (package_ids); ++iterator) {
+					pmpkg_t *pkg = pkg_from_package_id_str (package_ids[iterator]);
+					const char *pkg_filename = alpm_pkg_get_filename (pkg);
+					if (strcmp (pkg_filename, filename) == 0) {
+						pk_backend_package (backend_instance, PK_INFO_ENUM_DOWNLOADING, package_ids[iterator], alpm_pkg_get_desc (pkg));
+						break;
+					}
 				}
 			}
 		}
@@ -279,7 +307,11 @@ find_packages_by_details (const gchar *name, pmdb_t *db)
 	// determine if repository is local
 	gboolean repo_is_local = (db == alpm_option_get_localdb ());
 	// determine repository name
-	const gchar *repo = alpm_db_get_name (db);
+	const gchar *repo;
+	if (repo_is_local)
+		repo = ALPM_LOCAL_DB_ALIAS;
+	else
+		repo = alpm_db_get_name (db);
 	// set search term
 	alpm_list_t *needle = NULL;
 	needle = alpm_list_add (needle, (gchar *) name);
@@ -313,7 +345,11 @@ find_packages_by_name (const gchar *name, pmdb_t *db, gboolean exact)
 	// determine if repository is local
 	gboolean repo_is_local = (db == alpm_option_get_localdb ());
 	// determine repository name
-	const gchar *repo = alpm_db_get_name (db);
+	const gchar *repo;
+	if (repo_is_local)
+		repo = ALPM_LOCAL_DB_ALIAS;
+	else
+		repo = alpm_db_get_name (db);
 	// get list of packages in repository
 	alpm_list_t *pkgcache = alpm_db_getpkgcache (db);
 
@@ -354,7 +390,11 @@ find_packages_by_group (const gchar *name, pmdb_t *db)
 	// determine if we are searching for packages which belong to an unmapped group
 	gboolean search_other = (strcmp("other", name) == 0);
 	// determine repository name
-	const gchar *repo = alpm_db_get_name (db);
+	const gchar *repo;
+	if (repo_is_local)
+		repo = ALPM_LOCAL_DB_ALIAS;
+	else
+		repo = alpm_db_get_name (db);
 	// get list of packages in repository
 	alpm_list_t *pkgcache = alpm_db_getpkgcache (db);
 
@@ -402,7 +442,11 @@ get_packages (pmdb_t *db)
 	// determine if repository is local
 	gboolean repo_is_local = (db == alpm_option_get_localdb ());
 	// determine repository name
-	const gchar *repo = alpm_db_get_name (db);
+	const gchar *repo;
+	if (repo_is_local)
+		repo = ALPM_LOCAL_DB_ALIAS;
+	else
+		repo = alpm_db_get_name (db);
 	// get list of packages in repository
 	alpm_list_t *cache = alpm_db_getpkgcache (db);
 
@@ -751,6 +795,7 @@ backend_initialize (PkBackend *backend)
 		return;
 	}
 
+	dl_file_name = NULL;
 	alpm_option_set_dlcb (cb_dl_progress);
 
 	/* fill in group mapping */
@@ -1065,9 +1110,6 @@ backend_install_packages_thread (PkBackend *backend)
 	}
 	pk_debug ("alpm: %s", "transaction prepared");
 
-	/* clear dl_file_name before downloading */
-	dl_file_name = NULL;
-
 	/* commit transaction */
 	if (alpm_trans_commit (&data) == -1) {
 		pk_warning ("alpm: %s", alpm_strerrorlast ());
@@ -1077,9 +1119,6 @@ backend_install_packages_thread (PkBackend *backend)
 		return FALSE;
 	}
 
-	/* free dl_file_name as we no longer need it */
-	g_free (dl_file_name);
-
 	alpm_trans_release ();
 	pk_debug ("alpm: %s", "transaction released");
 
commit 666777983bb74da458bf8e7f898a08059143caaa
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 17:05:17 2008 +0100

    bugfix: document better the repo_id parameter for local files

diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml
index 51a165a..d43abb0 100644
--- a/docs/spec/pk-concepts.xml
+++ b/docs/spec/pk-concepts.xml
@@ -31,6 +31,32 @@
       are installable or installed in the client tools.
     </para>
     <para>
+      The data field for an non-installed local package must be
+      <literal>local</literal> as this signifies a repository name is not available
+      and that package resides locally on the client system.
+    </para>
+    <para>
+      For example:
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          <literal>csup;20060318-5;x86_64;local</literal>: for locally available package file.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <literal>csup;20060318-5;x86_64;fedora-devel</literal>: for package that is not installed
+          and can be downladed from the Fedora development repostory.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          <literal>csup;20060318-5;x86_64;installed</literal>: for locally installed package
+        </para>
+      </listitem>
+    </itemizedlist>
+    <para>
       The backend must ensure that the package_id only matches on one
       single package.
       A single package_id must be enough to uniquely identify a single object
commit 29368e524fc8749678712650be093bd847d61e01
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:17:44 2008 +0100

    trivial: don't print how long each task took in pkcon, that's a debugging thing

diff --git a/client/pk-console.c b/client/pk-console.c
index 4e7280e..9581dce 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -416,7 +416,7 @@ pk_console_finished_cb (PkClient *client, PkExitEnum exit, guint runtime, gpoint
 	if (awaiting_space) {
 		g_print ("\n");
 	}
-	g_print ("%s runtime was %.1f seconds\n", role_text, time);
+	pk_debug ("%s runtime was %.1f seconds", role_text, time);
 
 	/* is there any restart to notify the user? */
 	restart = pk_client_get_require_restart (client);
commit e859fb886820dae040d5e7ade5c65390bb87c18d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:12:14 2008 +0100

    trivial: add an example catalog file in the docs

diff --git a/docs/example.catalog b/docs/example.catalog
new file mode 100644
index 0000000..b044de4
--- /dev/null
+++ b/docs/example.catalog
@@ -0,0 +1,16 @@
+[PackageKit Catalog]
+
+# Just a package on all versions of fedora that can provide the dependency.
+# If there are multiple packages then the user will be asked to choose
+InstallProvides(fedora)=audio/QCELP
+
+# Just for Fedora 9, install two development files
+InstallPackages(fedora-9.90)=glib2-devel;PolicyKit-gnome-devel;ocaml-json-wheel-devel
+
+# On any distro, install the package with this file
+InstallFiles=/usr/bin/fontinst
+
+# For each architecture on Fedora 8, install one of the two different files
+InstallFiles(fedora-8-i686)=/usr/lib/pango/1.6.0/modules/pango-arabic-fc.so
+InstallFiles(fedora-8-x64)=/usr/lib64/pango/1.6.0/modules/pango-arabic-fc.so
+
commit dbe9f2368fa2bd7b4bd95aea5acab1629a7a5bad
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:11:42 2008 +0100

    trivial: adjust the PackageKit and gnome-packagekit spec files to install the mime handler

diff --git a/contrib/PackageKit.spec.in b/contrib/PackageKit.spec.in
index 61a67d1..2df1306 100644
--- a/contrib/PackageKit.spec.in
+++ b/contrib/PackageKit.spec.in
@@ -21,6 +21,7 @@ Requires: dbus >= %{dbus_version}
 Requires: PackageKit-libs = %{epoch}:%{version}-%{release}
 Requires: yum-packagekit = %{epoch}:%{version}-%{release}
 Requires: yum >= 3.2.6
+Requires: shared-mime-info
 
 BuildRequires: glib2-devel >= %{glib2_version}
 BuildRequires: dbus-devel  >= %{dbus_version}
@@ -122,6 +123,12 @@ chmod 755 $RPM_BUILD_ROOT%{_libexecdir}/PackageKitDbusTest.py
 %clean
 rm -rf $RPM_BUILD_ROOT
 
+%post
+update-mime-database %{_datadir}/mime
+
+%postun
+update-mime-database %{_datadir}/mime
+
 %post libs -p /sbin/ldconfig
 
 %postun libs -p /sbin/ldconfig
@@ -147,6 +154,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_datadir}/man/man1/*.1.gz
 %{_datadir}/gtk-doc/html/PackageKit
 %{_datadir}/PolicyKit/policy/*.policy
+%{_datadir}/mime/packages/packagekit-catalog.xml
 %{_sbindir}/packagekitd
 %{_bindir}/pkmon
 %{_bindir}/pkcon
diff --git a/contrib/gnome-packagekit.spec.in b/contrib/gnome-packagekit.spec.in
index ded7799..15a2afd 100644
--- a/contrib/gnome-packagekit.spec.in
+++ b/contrib/gnome-packagekit.spec.in
@@ -20,6 +20,7 @@ Requires:  libnotify >= 0.4.3
 Requires:  dbus-glib >= %{dbus_version}
 Requires:  dbus-x11 >= %{dbus_version}
 Requires:  PackageKit >= %{packagekit_version}
+Requires:  shared-mime-info
 Requires(post):   scrollkeeper
 Requires(pre):    GConf2
 Requires(post):   GConf2
@@ -92,7 +93,8 @@ touch --no-create %{_datadir}/icons/hicolor
 if [ -x /usr/bin/gtk-update-icon-cache ]; then
     gtk-update-icon-cache -q %{_datadir}/icons/hicolor
 fi
-/usr/bin/update-desktop-database %{_datadir}/applications
+update-desktop-database %{_datadir}/applications
+update-mime-database %{_datadir}/mime
 
 %pre
 if [ "$1" -gt 1 ]; then
@@ -114,7 +116,8 @@ touch --no-create %{_datadir}/icons/hicolor
 if [ -x /usr/bin/gtk-update-icon-cache ]; then
     gtk-update-icon-cache -q %{_datadir}/icons/hicolor
 fi
-/usr/bin/update-desktop-database %{_datadir}/applications
+update-desktop-database %{_datadir}/applications
+update-mime-database %{_datadir}/mime
 
 %files -f %{name}.lang
 %defattr(-,root,root,-)
commit 5c9aa64e7b9b985f7feb373d86027e96b3afb1fb
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:11:19 2008 +0100

    trivial: adjust the PackageKit and gnome-packagekit spec files to install the mime handler

diff --git a/contrib/PackageKit.catalog b/contrib/PackageKit.catalog
new file mode 100644
index 0000000..8165924
--- /dev/null
+++ b/contrib/PackageKit.catalog
@@ -0,0 +1,14 @@
+[PackageKit Catalog]
+
+# Common packages
+InstallPackages=autoconf;automake;intltool;libtool;pkgconfig
+
+# Fedora
+InstallPackages(fedora)=glib2-devel;gvfs-devel;dbus-glib-devel;NetworkManager-glib-devel;PolicyKit-devel;
+
+# Pardus
+InstallPackages(pardus)=NetworkManager-devel;PolicyKit-devel;autoconf;automake;dbus-devel;dbus-glib-devel;docbook-to-man;gettext-devel;glib2-devel;gtk-doc;poldek-devel;python-devel;readline-devel;rpm-pythonprov;sqlite3-devel
+
+# Forsight
+InstallPackages(forsight)=gnome-development;dbus-development
+
diff --git a/contrib/gnome-packagekit.catalog b/contrib/gnome-packagekit.catalog
new file mode 100644
index 0000000..1fc53e7
--- /dev/null
+++ b/contrib/gnome-packagekit.catalog
@@ -0,0 +1,17 @@
+[PackageKit Catalog]
+
+# Common packages
+InstallPackages=autoconf;automake;intltool;libtool;pkgconfig
+
+# Fedora 9 does not have Unique
+InstallPackages(fedora-9)=PackageKit-devel;glib2-devel;gtk2-devel;libsexy-devel;libglade2-devel;libnotify-devel;PolicyKit-gnome-devel
+
+# Rawhide is fedora 9.90
+InstallPackages(fedora-9.90)=PackageKit-devel;glib2-devel;gtk2-devel;libsexy-devel;libglade2-devel;libnotify-devel;PolicyKit-gnome-devel;unique-devel
+
+# Pardus
+InstallPackages(pardus)=GConf2-devel;PackageKit-devel;PolicyKit-gnome-devel;dbus-devel;dbus-glib-devel;gettext-devel;gnome-doc-utils;gtk+2-devel;libglade2-devel;libnotify-devel;libsexy-devel
+
+# Forsight
+InstallPackages(forsight)=gnome-development;dbus-development
+
commit f75a3a1cdae734c1320ed65a3e0056fa2af791bb
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:10:39 2008 +0100

    feature: add a mime handler for .catalog files

diff --git a/data/.gitignore b/data/.gitignore
index 3152d6e..d1a4fa8 100644
--- a/data/.gitignore
+++ b/data/.gitignore
@@ -5,4 +5,5 @@ org.freedesktop.PackageKitYumBackend.conf
 org.freedesktop.PackageKitYumBackend.service
 org.freedesktop.PackageKitAptBackend.conf
 org.freedesktop.PackageKitAptBackend.service
+packagekit-catalog.xml
 
diff --git a/data/Makefile.am b/data/Makefile.am
index dcd9c18..df2b3f6 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -19,6 +19,11 @@ crondata_DATA = packagekit-background
 pmutilsdir = $(libdir)/pm-utils/sleep.d
 pmutils_DATA = 95packagekit
 
+ at INTLTOOL_XML_RULE@
+mimedir = $(datadir)/mime/packages
+mime_in_files = packagekit-catalog.xml.in
+mime_DATA = $(mime_in_files:.xml.in=.xml)
+
 dbusdir = ${SYSCONFDIR}/dbus-1/system.d
 dist_dbus_DATA = 					\
 	org.freedesktop.PackageKit.conf			\
@@ -74,6 +79,7 @@ EXTRA_DIST =						\
 	$(serviceyum_in_files)				\
 	$(servicetest_in_files)				\
 	$(serviceapt_in_files)				\
+	$(mime_in_files)				\
 	$(localcache_DATA)				\
 	$(database_DATA)				\
 	$(NULL)
@@ -85,6 +91,7 @@ install-data-hook:
 	chmod a+x $(DESTDIR)$(libdir)/pm-utils/sleep.d/95packagekit;
 
 DISTCLEANFILES =					\
+	$(mime_DATA)					\
 	org.freedesktop.PackageKit.service		\
 	org.freedesktop.PackageKitTestBackend.service	\
 	org.freedesktop.PackageKitYumBackend.service	\
diff --git a/data/packagekit-catalog.xml.in b/data/packagekit-catalog.xml.in
new file mode 100644
index 0000000..399b0fa
--- /dev/null
+++ b/data/packagekit-catalog.xml.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+  <mime-type type="application/x-catalog">
+    <_comment>PackageKit Catalog</_comment>
+    <glob pattern="*.catalog"/>
+    <generic-icon name="package-x-generic"/>
+  </mime-type>
+</mime-info>
+
commit 5069740ac58d74e7121ab91c1953ef5e6d78146f
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:09:40 2008 +0100

    trivial: add some FAQ text on how to use catalogs

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index 1fb8563..888d150 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -22,6 +22,7 @@
 <h2>Table Of Contents</h2>
 <ul>
 <li><a href="#how-complete">How complete are the backends?</a></li>
+<li><a href="#catalogs">What's a package catalog?</a></li>
 <li><a href="#1-click-install">Does PackageKit support 1-Click Install?</a></li>
 <li><a href="#run-as-root">When run as root, gpk-application and pkcon do not work!</a></li>
 <li><a href="#session-system">Why is there a session service and and a system service?</a></li>
@@ -56,6 +57,74 @@ You can see the latest feature matrix <a href="pk-matrix.html">here</a>.
 </p>
 
 <hr>
+<h3><a name="catalogs">What's a package catalog?</a></h3>
+<p>
+There's one use case that I'm very interested in, and that is getting new users with the correct
+environment to build and start hacking on software or using other software tools.
+For instance, on <a href="http://www.packagekit.org">www.packagekit.org</a> in the FAQ section,
+we can have a link to install build files to <a href="packagekit.catalog">start hacking on PackageKit</a>.
+</p>
+<p>
+Now, this <code>.catalog</code> file is handled by <code>gpk-install-catalog</code> that parses
+this file and causes the appropriate packages to be installed if they are not already installed.
+This rocks as we can get GTK+, Xorg hackers up to speed with the minimum of fuss and confusion.
+It also lets people put links on webpages to <i>install all the stuff you need</i> when writing a
+<i>How to use a scanner in GIMP</i> howto.
+</p>
+<p>
+So, what does a .catalog file look like?
+</p>
+<pre>
+[PackageKit Catalog]
+
+# Just a package on all versions of fedora that can provide the dependency.
+# If there are multiple packages then the user will be asked to choose
+InstallProvides(fedora)=audio/QCELP
+
+# Just for Fedora 9, install two development files
+InstallPackages(fedora-9)=glib2-devel;PolicyKit-gnome-devel
+
+# On any distro, install the package with this file
+InstallFiles=/usr/bin/fontinst
+
+# For each architecture on Fedora 8, install one of the two different compat files
+InstallFiles(fedora-8-i686)=/usr/lib/pango/1.6.0/modules/pango-arabic-fc.so
+InstallFiles(fedora-8-x64)=/usr/lib64/pango/1.6.0/modules/pango-arabic-fc.so
+</pre>
+<p>
+You'll notice the <code>distro-id</code> in between the <code>()</code>'s - this lets a packager
+fine tune the package name, where for instance in Debian the package is called <code>policykit</code>
+and Fedora <code>PolicyKit</code>.
+You can specify a granularity of distribution, distribution-version or
+distribution-version-architecture - PackageKit will process all the entries that apply.
+It's of course better to not specify a <code>()</code> if possible, as this lets the file work on
+as many distributions as possible out of the box.
+</p>
+<p>
+There's also no version checking - intentionally - the distro should be specified and have the
+correct data.
+If there's an optional package not in earlier versions then you can do something like this:
+</p>
+<pre>
+[PackageKit Catalog]
+
+# Fedora 9 does not have Unique
+InstallPackages(fedora-9)=glib2-devel;PolicyKit-gnome-devel
+
+# Rawhide is fedora 9.90
+InstallPackages(fedora-9.90)=glib2-devel;PolicyKit-gnome-devel;unique-devel
+</pre>
+<p>
+There's also no description of the catalog that needs translating and verifying - they are just
+lists of packages, files and provides that might be useful.
+All the translations come from the distributions metadata, and it's up to the user to verify the
+package lists that are asked to be installed, so there are no signing or trust issues.
+</p>
+<p>
+Note: this isn't designed to replace one click install, it just does something that is similar in
+a different way.
+</p>
+<hr>
 <h3><a name="1-click-install">Does PackageKit support 1-Click Install?</a></h3>
 <p>
 No, as they are a potential security problem. The issues are as follows:
@@ -84,6 +153,8 @@ they are not going to understand the description.
 <p>
 So what's the solution? Using a standard <code>$vendor-release.rpm</code> or <code>.deb</code>
 you can ship the standard repo or source with a signed GPG key.
+PackageKit also supports <a href="#catalogs">catalogs</a> which can install sets of files provided by
+your distro.
 </p>
 <p>
 Quoting Sebastian Heinlein,
commit 5077185f3e06443162aac11a3f356b87c27e8fce
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jun 6 16:09:01 2008 +0100

    feature: Add PkCatalog for installing catalogs of applications. Catalog is the new name for Bundle

diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index 6935e66..2203ebf 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS = 1.7
 NULL =
 
 TEST_FILES =						\
+	test.catalog					\
 	pk-spawn-test.sh				\
 	pk-spawn-proxy.sh				\
 	pk-spawn-test-sigquit.sh			\
diff --git a/data/tests/test.catalog b/data/tests/test.catalog
new file mode 100644
index 0000000..bedb9d5
--- /dev/null
+++ b/data/tests/test.catalog
@@ -0,0 +1,16 @@
+[PackageKit Catalog]
+
+# Just a package on all versions of fedora that can provide the dependency.
+# If there are multiple packages then the user will be asked to choose
+InstallProvides(fedora)=audio/QCELP
+
+# Just for Fedora 9, install two development files
+InstallPackages(fedora-9.90)=ocaml-json-wheel-devel
+
+# On any distro, install the package with this file
+InstallFiles=/usr/bin/kpowersave
+
+# For each architecture on Fedora 8, install one of the two different files
+InstallFiles(fedora-8-i686)=/usr/lib/pango/1.6.0/modules/pango-arabic-fc.so
+InstallFiles(fedora-8-x64)=/usr/lib64/pango/1.6.0/modules/pango-arabic-fc.so
+
diff --git a/libpackagekit/Makefile.am b/libpackagekit/Makefile.am
index 8f1f2c5..fa5bb6a 100644
--- a/libpackagekit/Makefile.am
+++ b/libpackagekit/Makefile.am
@@ -43,6 +43,7 @@ libpackagekit_include_HEADERS =					\
 	pk-enum.h						\
 	pk-common.h						\
 	pk-client.h						\
+	pk-catalog.h						\
 	pk-control.h						\
 	pk-task-list.h						\
 	$(NULL)
@@ -70,6 +71,8 @@ libpackagekit_la_SOURCES =					\
 	pk-common.h						\
 	pk-client.c						\
 	pk-client.h						\
+	pk-catalog.c						\
+	pk-catalog.h						\
 	pk-control.c						\
 	pk-control.h						\
 	pk-task-list.c						\
diff --git a/libpackagekit/pk-catalog.c b/libpackagekit/pk-catalog.c
new file mode 100644
index 0000000..17a0643
--- /dev/null
+++ b/libpackagekit/pk-catalog.c
@@ -0,0 +1,414 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib/gi18n.h>
+
+#include "pk-debug.h"
+#include "pk-common.h"
+#include "pk-client.h"
+#include "pk-package-list.h"
+#include "pk-marshal.h"
+#include "pk-catalog.h"
+
+static void     pk_catalog_class_init	(PkCatalogClass	*klass);
+static void     pk_catalog_init		(PkCatalog	*catalog);
+static void     pk_catalog_finalize	(GObject	*object);
+
+#define PK_CATALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_CATALOG, PkCatalogPrivate))
+
+struct PkCatalogPrivate
+{
+	GKeyFile		*file;
+	gchar			*distro_id;
+	const gchar		*type;
+	PkClient		*client;
+	PkPackageList		*list;
+	gboolean		 is_cancelled;
+};
+
+enum {
+	PK_CATALOG_PROGRESS,
+	PK_CATALOG_LAST_SIGNAL
+};
+
+static guint signals [PK_CATALOG_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (PkCatalog, pk_catalog, G_TYPE_OBJECT)
+#define PK_CATALOG_FILE_HEADER	"PackageKit Catalog"
+
+/**
+ * pk_catalog_process_type_part:
+ **/
+static gboolean
+pk_catalog_process_type_part (PkCatalog *catalog, GPtrArray *array, const gchar *distro_id_part)
+{
+	gchar **list;
+	gchar *key;
+	guint len;
+	guint i;
+
+	/* cancelled? */
+	if (catalog->priv->is_cancelled) {
+		pk_debug ("escaping as cancelled!");
+		return FALSE;
+	}
+
+	/* make key */
+	if (distro_id_part == NULL) {
+		key = g_strdup (catalog->priv->type);
+	} else {
+		key = g_strdup_printf ("%s(%s)", catalog->priv->type, distro_id_part);
+	}
+	pk_debug ("key=%s", key);
+	list = g_key_file_get_string_list (catalog->priv->file, PK_CATALOG_FILE_HEADER, key, NULL, NULL);
+	g_free (key);
+
+	/* we have no key of this name */
+	if (list == NULL) {
+		return FALSE;
+	}
+
+	/* add to array */
+	len = g_strv_length (list);
+	for (i=0; i<len; i++) {
+		pk_debug ("add to array %i=%s", i, list[i]);
+		g_ptr_array_add (array, g_strdup (list[i]));
+	}
+	g_strfreev (list);
+	return TRUE;
+}
+
+/**
+ * pk_catalog_process_type:
+ **/
+static gboolean
+pk_catalog_process_type (PkCatalog *catalog)
+{
+	PkCatalogProgress mode = 0;
+	PkPackageList *list;
+	GPtrArray *array;
+	GError *error = NULL;
+	gchar **parts = NULL;
+	gchar *distro_id_part;
+	const gchar *package;
+	gboolean ret = TRUE;
+	guint i;
+
+	/* cancelled? */
+	if (catalog->priv->is_cancelled) {
+		pk_debug ("escaping as cancelled!");
+		return FALSE;
+	}
+
+	parts = g_strsplit (catalog->priv->distro_id, "-", 0);
+	array = g_ptr_array_new ();
+
+	/* no specifier */
+	pk_catalog_process_type_part (catalog, array, NULL);
+
+	/* distro */
+	pk_catalog_process_type_part (catalog, array, parts[0]);
+
+	/* distro-ver */
+	distro_id_part = g_strjoin ("-", parts[0], parts[1], NULL);
+	pk_catalog_process_type_part (catalog, array, distro_id_part);
+	g_free (distro_id_part);
+
+	/* distro-ver-arch */
+	pk_catalog_process_type_part (catalog, array, catalog->priv->distro_id);
+
+	/* find mode */
+	if (pk_strequal (catalog->priv->type, "InstallPackages")) {
+		mode = PK_CATALOG_PROGRESS_PACKAGES;
+	} else if (pk_strequal (catalog->priv->type, "InstallFiles")) {
+		mode = PK_CATALOG_PROGRESS_FILES;
+	} else if (pk_strequal (catalog->priv->type, "InstallProvides")) {
+		mode = PK_CATALOG_PROGRESS_PROVIDES;
+	}
+
+	/* do each entry */
+	for (i=0; i<array->len; i++) {
+		if (catalog->priv->is_cancelled) {
+			pk_debug ("escaping as cancelled!");
+			break;
+		}
+
+		/* reset */
+		ret = pk_client_reset (catalog->priv->client, &error);
+		if (!ret) {
+			pk_warning ("reset failed: %s", error->message);
+			g_error_free (error);
+			break;
+		}
+
+		/* get data */
+		package = (const gchar *) g_ptr_array_index (array, i);
+
+		/* tell the client what we are doing */
+		g_signal_emit (catalog, signals [PK_CATALOG_PROGRESS], 0, mode, package);
+
+		/* do the actions */
+		if (mode == PK_CATALOG_PROGRESS_PACKAGES) {
+			ret = pk_client_resolve (catalog->priv->client, PK_FILTER_ENUM_NOT_INSTALLED, package, &error);
+		} else if (mode == PK_CATALOG_PROGRESS_FILES) {
+			ret = pk_client_search_file (catalog->priv->client, PK_FILTER_ENUM_NOT_INSTALLED, package, &error);
+		} else if (mode == PK_CATALOG_PROGRESS_PROVIDES) {
+			ret = pk_client_what_provides (catalog->priv->client, PK_FILTER_ENUM_NOT_INSTALLED, 0, package, &error);
+		}
+		if (!ret) {
+			pk_warning ("method failed: %s", error->message);
+			g_error_free (error);
+			break;
+		}
+
+		/* add to list any results */
+		list = pk_client_get_package_list (catalog->priv->client);
+		pk_package_list_add_list (catalog->priv->list, list);
+		g_object_unref (list);
+	}
+
+	g_strfreev (parts);
+	g_ptr_array_free (array, TRUE);
+	return ret;
+}
+
+/**
+ * pk_catalog_process_file:
+ **/
+static gboolean
+pk_catalog_process_file (PkCatalog *catalog, const gchar *filename)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	/* cancelled? */
+	if (catalog->priv->is_cancelled) {
+		pk_debug ("escaping as cancelled!");
+		return FALSE;
+	}
+
+	/* load all data */
+	ret = g_key_file_load_from_file (catalog->priv->file, filename, G_KEY_FILE_NONE, &error);
+	if (!ret) {
+		pk_warning ("cannot open file %s, %s", filename, error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+
+	/* InstallPackages */
+	catalog->priv->type = "InstallPackages";
+	pk_catalog_process_type (catalog);
+
+	/* InstallFiles */
+	catalog->priv->type = "InstallFiles";
+	pk_catalog_process_type (catalog);
+
+	/* InstallProvides */
+	catalog->priv->type = "InstallProvides";
+	pk_catalog_process_type (catalog);
+
+	return TRUE;
+}
+
+/**
+ * pk_catalog_cancel:
+ **/
+gboolean
+pk_catalog_cancel (PkCatalog *catalog)
+{
+	gboolean ret;
+	GError *error = NULL;
+
+	if (catalog->priv->is_cancelled) {
+		pk_warning ("already cancelled");
+		return FALSE;
+	}
+	catalog->priv->is_cancelled = TRUE;
+
+	/* cancel whatever is in progress */
+	ret = pk_client_cancel (catalog->priv->client, &error);
+	if (!ret) {
+		pk_warning ("cancel failed: %s", error->message);
+		g_error_free (error);
+	}
+	return TRUE;
+}
+
+/**
+ * pk_catalog_process_files:
+ **/
+PkPackageList *
+pk_catalog_process_files (PkCatalog *catalog, gchar **filenames)
+{
+	guint len;
+	guint i;
+
+	/* process each file */
+	len = g_strv_length (filenames);
+	for (i=0; i<len; i++) {
+		if (catalog->priv->is_cancelled) {
+			pk_debug ("escaping as cancelled!");
+			break;
+		}
+		pk_debug ("filenames[%i]=%s", i, filenames[i]);
+		pk_catalog_process_file (catalog, filenames[i]);
+	}
+
+	g_object_ref (catalog->priv->list);
+	return catalog->priv->list;
+}
+
+/**
+ * pk_catalog_class_init:
+ * @klass: The PkCatalogClass
+ **/
+static void
+pk_catalog_class_init (PkCatalogClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = pk_catalog_finalize;
+	g_type_class_add_private (klass, sizeof (PkCatalogPrivate));
+	signals [PK_CATALOG_PROGRESS] =
+		g_signal_new ("progress",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      0, NULL, NULL, pk_marshal_VOID__UINT_STRING,
+			      G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING);
+}
+
+/**
+ * pk_catalog_init:
+ * @catalog: This class instance
+ **/
+static void
+pk_catalog_init (PkCatalog *catalog)
+{
+	catalog->priv = PK_CATALOG_GET_PRIVATE (catalog);
+	catalog->priv->type = NULL;
+	catalog->priv->is_cancelled = FALSE;
+	catalog->priv->file = g_key_file_new ();
+	catalog->priv->list = pk_package_list_new ();
+
+	/* name-version-arch */
+	catalog->priv->distro_id = pk_get_distro_id ();
+	if (catalog->priv->distro_id == NULL) {
+		pk_error ("no distro_id, your distro needs to implement this in pk-common.c!");
+	}
+
+	catalog->priv->client = pk_client_new ();
+	pk_client_set_use_buffer (catalog->priv->client, TRUE, NULL);
+	pk_client_set_synchronous (catalog->priv->client, TRUE, NULL);
+}
+
+/**
+ * pk_catalog_finalize:
+ * @object: The object to finalize
+ **/
+static void
+pk_catalog_finalize (GObject *object)
+{
+	PkCatalog *catalog;
+
+	g_return_if_fail (PK_IS_CATALOG (object));
+
+	catalog = PK_CATALOG (object);
+
+	g_return_if_fail (catalog->priv != NULL);
+	g_key_file_free (catalog->priv->file);
+	g_free (catalog->priv->distro_id);
+	g_object_unref (catalog->priv->list);
+	g_object_unref (catalog->priv->client);
+
+	G_OBJECT_CLASS (pk_catalog_parent_class)->finalize (object);
+}
+
+/**
+ * pk_catalog_new:
+ *
+ * Return value: a new PkCatalog object.
+ **/
+PkCatalog *
+pk_catalog_new (void)
+{
+	PkCatalog *catalog;
+	catalog = g_object_new (PK_TYPE_CATALOG, NULL);
+	return PK_CATALOG (catalog);
+}
+
+/***************************************************************************
+ ***                          MAKE CHECK TESTS                           ***
+ ***************************************************************************/
+#ifdef PK_BUILD_TESTS
+#include <libselftest.h>
+
+void
+libst_catalog (LibSelfTest *test)
+{
+	PkCatalog *catalog;
+	PkPackageList *list;
+	gchar **filenames;
+	gchar *path;
+	guint size;
+
+	if (libst_start (test, "PkCatalog", CLASS_AUTO) == FALSE) {
+		return;
+	}
+
+	/************************************************************/
+	libst_title (test, "get catalog");
+	catalog = pk_catalog_new ();
+	if (catalog != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "process the files getting non-null");
+	path = libst_get_data_file ("test.catalog");
+	filenames = g_strsplit (path, " ", 0);
+	list = pk_catalog_process_files (catalog, filenames);
+	g_free (path);
+	g_strfreev (filenames);
+	if (list != NULL) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "have we got packages?");
+	size = pk_package_list_get_size (list);
+	if (size > 0) {
+		libst_success (test, "%i packages", size);
+	} else {
+		libst_failed (test, NULL);
+	}
+	g_object_unref (list);
+	g_object_unref (catalog);
+
+	libst_end (test);
+}
+#endif
+
diff --git a/libpackagekit/pk-catalog.h b/libpackagekit/pk-catalog.h
new file mode 100644
index 0000000..9392df8
--- /dev/null
+++ b/libpackagekit/pk-catalog.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_CATALOG_H
+#define __PK_CATALOG_H
+
+#include <glib-object.h>
+#include <pk-package-list.h>
+
+G_BEGIN_DECLS
+
+#define PK_TYPE_CATALOG		(pk_catalog_get_type ())
+#define PK_CATALOG(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), PK_TYPE_CATALOG, PkCatalog))
+#define PK_CATALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), PK_TYPE_CATALOG, PkCatalogClass))
+#define PK_IS_CATALOG(o)	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PK_TYPE_CATALOG))
+#define PK_IS_CATALOG_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_CATALOG))
+#define PK_CATALOG_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_CATALOG, PkCatalogClass))
+#define PK_CATALOG_ERROR	(pk_catalog_error_quark ())
+#define PK_CATALOG_TYPE_ERROR	(pk_catalog_error_get_type ())
+
+typedef struct PkCatalogPrivate PkCatalogPrivate;
+
+typedef struct
+{
+	 GObject		 parent;
+	 PkCatalogPrivate	*priv;
+} PkCatalog;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+} PkCatalogClass;
+
+typedef enum {
+	PK_CATALOG_PROGRESS_PACKAGES,
+	PK_CATALOG_PROGRESS_FILES,
+	PK_CATALOG_PROGRESS_PROVIDES,
+	PK_CATALOG_PROGRESS_LAST
+} PkCatalogProgress;
+
+GType		 pk_catalog_get_type		  	(void) G_GNUC_CONST;
+PkCatalog	*pk_catalog_new				(void);
+PkPackageList	*pk_catalog_process_files		(PkCatalog		*catalog,
+							 gchar			**filenames);
+gboolean	 pk_catalog_cancel			(PkCatalog		*catalog);
+
+G_END_DECLS
+
+#endif /* __PK_CATALOG_H */
+
diff --git a/libpackagekit/pk-self-test.c b/libpackagekit/pk-self-test.c
index bf151fb..b03dfd2 100644
--- a/libpackagekit/pk-self-test.c
+++ b/libpackagekit/pk-self-test.c
@@ -38,6 +38,7 @@ void libst_extra (LibSelfTest *test);
 void libst_client (LibSelfTest *test);
 void libst_control (LibSelfTest *test);
 void libst_task_list (LibSelfTest *test);
+void libst_catalog (LibSelfTest *test);
 
 int
 main (int argc, char **argv)
@@ -57,6 +58,7 @@ main (int argc, char **argv)
 	libst_enum (&test);
 	libst_extra (&test);
 	libst_client (&test);
+	libst_catalog (&test);
 	libst_control (&test);
 	libst_task_list (&test);
 
commit a34e1c4e17f7220594b1a18777b66b043967961d
Author: Valeriy Lyasotskiy <onestep at ukr.net>
Date:   Fri Jun 6 17:18:49 2008 +0300

    alpm: added download notification support for backend_install_packages

diff --git a/backends/alpm/pk-backend-alpm.c b/backends/alpm/pk-backend-alpm.c
index ef9a024..467e8c6 100644
--- a/backends/alpm/pk-backend-alpm.c
+++ b/backends/alpm/pk-backend-alpm.c
@@ -26,6 +26,8 @@
 #define ALPM_CACHEDIR "/var/cache/pacman/pkg"
 #define ALPM_LOGFILE "/var/log/pacman.log"
 
+#define ALPM_PKG_EXT ".pkg.tar.gz"
+
 #define ALPM_PROGRESS_UPDATE_INTERVAL 400
 
 #include <gmodule.h>
@@ -46,6 +48,7 @@
 int progress_percentage;
 int subprogress_percentage;
 PkBackend *backend_instance = NULL;
+char *dl_file_name;
 
 GHashTable *group_mapping;
 
@@ -72,6 +75,36 @@ pkg_to_package_id_str (pmpkg_t *pkg, gchar *repo)
 	return pk_package_id_build (alpm_pkg_get_name (pkg), alpm_pkg_get_version (pkg), arch, repo);
 }
 
+pmpkg_t *
+pkg_from_package_id_str (const gchar *package_id_str)
+{
+	PkPackageId *pkg_id = pk_package_id_new_from_string (package_id_str);
+
+	/* do all this fancy stuff */
+	pmdb_t *repo = NULL;
+	if (strcmp ("local", pkg_id->data) == 0)
+		repo = alpm_option_get_localdb ();
+	else {
+		alpm_list_t *iterator;
+		for (iterator = alpm_option_get_syncdbs (); iterator; iterator = alpm_list_next (iterator)) {
+			repo = alpm_list_getdata (iterator);
+			if (strcmp (alpm_db_get_name (repo), pkg_id->data) == 0)
+				break;
+		}
+	}
+
+	pmpkg_t *pkg;
+	if (repo != NULL)
+		pkg = alpm_db_get_pkg (repo, pkg_id->name);
+	else
+		pkg = NULL;
+
+	/* free package id as we no longer need it */
+	pk_package_id_free (pkg_id);
+
+	return pkg;
+}
+
 void
 cb_trans_evt (pmtransevt_t event, void *data1, void *data2)
 {
@@ -87,6 +120,7 @@ cb_trans_evt (pmtransevt_t event, void *data1, void *data2)
 		case PM_TRANS_EVT_ADD_START:
 			package_id_str = pkg_to_package_id_str (data1, "local");
 			pk_backend_package (backend_instance, PK_INFO_ENUM_INSTALLING, package_id_str, alpm_pkg_get_desc (data1));
+			pk_backend_set_status (backend_instance, PK_STATUS_ENUM_INSTALL);
 			g_free (package_id_str);
 			break;
 		case PM_TRANS_EVT_UPGRADE_START:
@@ -115,8 +149,31 @@ cb_trans_progress (pmtransprog_t event, const char *pkgname, int percent, int ho
 void
 cb_dl_progress (const char *filename, int file_xfered, int file_total, int list_xfered, int list_total)
 {
+	/* check if we already processed this file name */
+	if (dl_file_name == NULL || strcmp (filename, dl_file_name) != 0) {
+		pk_debug ("alpm: downloading file %s", filename);
+		g_free (dl_file_name);
+		dl_file_name = strdup(filename);
+
+		/* check if downloaded file is a package */
+		if (strstr (filename, ALPM_PKG_EXT) != NULL) {
+			/* all this stuff is a bit dirty */
+			gchar **package_ids = pk_backend_get_strv (backend_instance, "package_ids");
+
+			int iterator;
+			for (iterator = 0; iterator < g_strv_length (package_ids); ++iterator) {
+				pmpkg_t *pkg = pkg_from_package_id_str (package_ids[iterator]);
+				const char *pkg_filename = alpm_pkg_get_filename (pkg);
+				if (strcmp (pkg_filename, filename) == 0) {
+					pk_backend_package (backend_instance, PK_INFO_ENUM_DOWNLOADING, package_ids[iterator], alpm_pkg_get_desc (pkg));
+					break;
+				}
+			}
+		}
+	}
+
 	int percent = (int) ((float) file_xfered / (float) file_total) * 100;
-	pk_debug ("alpm: percentage is %i", percent);
+	pk_debug ("alpm: download percentage of %s is %i", filename, percent);
 	// pk_backend_set_percentage ((PkBackend *) install_backend, percent);
 }
 
@@ -174,36 +231,6 @@ pkg_equals_to (pmpkg_t *pkg, const gchar *name, const gchar *version)
 	return TRUE;
 }
 
-pmpkg_t *
-get_pkg_from_package_id (const gchar *package_id)
-{
-	PkPackageId *pkg_id = pk_package_id_new_from_string (package_id);
-
-	/* do all this fancy stuff */
-	pmdb_t *repo = NULL;
-	if (strcmp ("local", pkg_id->data) == 0)
-		repo = alpm_option_get_localdb ();
-	else {
-		alpm_list_t *iterator;
-		for (iterator = alpm_option_get_syncdbs (); iterator; iterator = alpm_list_next (iterator)) {
-			repo = alpm_list_getdata (iterator);
-			if (strcmp (alpm_db_get_name (repo), pkg_id->data) == 0)
-				break;
-		}
-	}
-
-	pmpkg_t *pkg;
-	if (repo != NULL)
-		pkg = alpm_db_get_pkg (repo, pkg_id->name);
-	else
-		pkg = NULL;
-
-	/* free package id as we no longer need it */
-	pk_package_id_free (pkg_id);
-
-	return pkg;
-}
-
 static void
 add_package (PkBackend *backend, PackageSource *package)
 {
@@ -810,9 +837,9 @@ static void
 backend_get_details (PkBackend *backend, const gchar *package_id)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pmpkg_t *pkg = get_pkg_from_package_id (package_id);
+	pmpkg_t *pkg = pkg_from_package_id_str (package_id);
 	if (pkg == NULL) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, alpm_strerror (pm_errno));
+		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, alpm_strerrorlast ());
 		pk_backend_finished (backend);
 		return;
 	}
@@ -843,9 +870,9 @@ static void
 backend_get_files (PkBackend *backend, const gchar *package_id)
 {
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
-	pmpkg_t *pkg = get_pkg_from_package_id (package_id);
+	pmpkg_t *pkg = pkg_from_package_id_str (package_id);
 	if (pkg == NULL) {
-		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, alpm_strerror (pm_errno));
+		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, alpm_strerrorlast ());
 		pk_backend_finished (backend);
 		return;
 	}
@@ -910,7 +937,7 @@ backend_get_repo_list (PkBackend *backend, PkFilterEnum filters)
 
 	alpm_list_t *repos = alpm_option_get_syncdbs ();
 	if (repos == NULL)
-		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, alpm_strerror (pm_errno));
+		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, alpm_strerrorlast ());
 
 	// Iterate on repository list
 	alpm_list_t *iterator;
@@ -1038,6 +1065,9 @@ backend_install_packages_thread (PkBackend *backend)
 	}
 	pk_debug ("alpm: %s", "transaction prepared");
 
+	/* clear dl_file_name before downloading */
+	dl_file_name = NULL;
+
 	/* commit transaction */
 	if (alpm_trans_commit (&data) == -1) {
 		pk_warning ("alpm: %s", alpm_strerrorlast ());
@@ -1047,6 +1077,9 @@ backend_install_packages_thread (PkBackend *backend)
 		return FALSE;
 	}
 
+	/* free dl_file_name as we no longer need it */
+	g_free (dl_file_name);
+
 	alpm_trans_release ();
 	pk_debug ("alpm: %s", "transaction released");
 
@@ -1060,8 +1093,6 @@ backend_install_packages_thread (PkBackend *backend)
 static void
 backend_install_packages (PkBackend *backend, gchar **package_ids)
 {
-	pk_backend_set_status (backend, PK_STATUS_ENUM_INSTALL);
-
 	pk_backend_thread_create (backend, backend_install_packages_thread);
 }
 


More information about the PackageKit-commit mailing list