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

Richard Hughes hughsient at kemper.freedesktop.org
Tue Sep 16 09:02:45 PDT 2008


 NEWS                                               |  102 ++++
 RELEASE                                            |    1 
 backends/apt/aptDBUSBackend.py                     |    4 
 backends/urpmi/helpers/get-requires.pl             |   10 
 backends/urpmi/helpers/resolve.pl                  |    7 
 backends/urpmi/helpers/urpmi-dispatched-backend.pl |  478 +++++++++++++++++-
 backends/yum/yumBackend.py                         |   20 
 backends/zypp/zypp-events.h                        |    2 
 backends/zypp/zypp-utils.h                         |   10 
 client/pk-console.c                                |   14 
 client/pk-generate-pack-main.c                     |    2 
 configure.ac                                       |    2 
 data/pk-upgrade-distro.sh                          |   11 
 docs/html/pk-authors.html                          |    4 
 docs/html/pk-download.html                         |   10 
 libpackagekit/pk-bitfield.c                        |   18 
 libpackagekit/pk-bitfield.h                        |    1 
 libpackagekit/pk-client.h                          |    2 
 libpackagekit/pk-common.c                          |   10 
 libpackagekit/pk-common.h                          |    4 
 libpackagekit/pk-control.c                         |  159 +++---
 libpackagekit/pk-control.h                         |   15 
 libpackagekit/pk-package-ids.c                     |    2 
 libpackagekit/pk-package-list.c                    |    2 
 python/packagekit/Makefile.am                      |    1 
 python/packagekit/client.py                        |  534 +++++++++++++++++++++
 python/wrapper-test.py                             |  101 +++
 src/pk-backend-spawn.c                             |    2 
 src/pk-network-nm.h                                |    2 
 src/pk-network-unix.h                              |    2 
 src/pk-network.h                                   |    2 
 src/pk-spawn.h                                     |    2 
 src/pk-transaction-list.c                          |    2 
 src/pk-transaction-list.h                          |    2 
 src/pk-transaction.c                               |    2 
 35 files changed, 1368 insertions(+), 174 deletions(-)

New commits:
commit 8092cc30e82bd379f234e24366c6a888ee0aceef
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 16:57:45 2008 +0100

    Release version 0.3.3

diff --git a/NEWS b/NEWS
index 18bda42..2dadc37 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,105 @@
+Version 0.3.3
+~~~~~~~~~~~~~~
+Released: 2008-09-16
+
+Notes:
+ - This release fixes a serious bug where the daemon would sometimes stop
+   handling requests under heavy load.
+ - A new package type of Collection has been added that is designed to work
+   as an abstract package. It can be used to install or remove groups of packages.
+
+New Features:
+ - Add PK_INFO_ENUM_COLLECTION_INSTALLED and PK_INFO_ENUM_COLLECTION_AVAILABLE (Richard Hughes)
+ - Add pk-upgrade-distro.sh so we can actually do the distro upgrade action (Richard Hughes)
+ - Add support for running the Ubuntu dist upgrade tool (Sebastian Heinlein)
+ - Add PK_FILTER_ENUM_COLLECTIONS and PK_FILTER_ENUM_NOT_COLLECTIONS functionality (Tim Lauridsen)
+ - Add documentation about how the udev firmware loading stuff actually works (Richard Hughes)
+ - Added client Python API based on the packagekitwrapper.py (Tim Lauridsen)
+ - Python client API - many improvements (Tim Lauridsen)
+
+Bugfixes:
+ - Don't assume /bin/sh supports echo -e (James Westby)
+ - Complete handling of local backend directory for test (James Westby)
+ - When we have finished RefreshCache delete the udev file if it exists (Richard Hughes)
+ - Fix the race where firemware is requested by udev and and old file is overwritten (Richard Hughes)
+ - Actually print the transactions without using --verbose when using pkmon (Richard Hughes)
+ - Use a proper error enum when we have no more mirrors to try (Richard Hughes)
+ - Don't convert null sections of a package_id instead use an empty string (Richard Hughes)
+ - Turn off -Wformat-security as old gtk-doc generators break the build (Richard Hughes)
+ - Use a bitfield when searching for files in the catalog (Richard Hughes)
+ - Execute the pk_transaction_run handler in an idle callback (Richard Hughes)
+ - Allow the catalog list to be split with more than just ; chars (Richard Hughes)
+ - Fix up all the memory leaks found by the self tests in src and libpackagekit (Richard Hughes)
+ - Make PkBitfield a 64 bit type now we have 33 group enums (Richard Hughes)
+ - Emit custom exit status from PkSpawn so we can tell the exit status (Richard Hughes)
+ - Only return the icon name in PkExtra if it's an icon name, and not an actual icon (Richard Hughes)
+ - PkExtra is a singleton, so don't error out when we try to reuse it (Richard Hughes)
+ - Add GError parameters to all the public functions in PkControl that can fail (Richard Hughes)
+
+Backends:
+ - apt: Handle inconsistent source repo state (James Westby)
+ - apt: Only define the enhanced softwareproperties class if possible (Sebastian Heinlein)
+ - apt: Disable the sources list repository if it is inconsistent (Sebastian Heinlein)
+ - apt: Add missing support for cdrom sources (Sebastian Heinlein)
+ - apt: Check the cache at first in doUpdatePackages (Sebastian Heinlein)
+ - apt: Add support for collections. Based on the metapackages section (Sebastian Heinlein)
+ - apt: Use a dictonary for the section to group mapping (Sebastian Heinlein)
+ - apt: Make sure that we are can lock the pkg system before installing local packages (Sebastian Heinlein)
+ - apt: Fix path of the reboot-required stamp (Sebastian Heinlein)
+ - dummy: Make what-provides take some time, and also special case some codec names (Richard Hughes)
+ - dummy: Make install_files and get_depends a little smarter (Richard Hughes)
+ - smart: Only show the best requires/provides, and remove the package itself (Anders F Bjorklund)
+ - smart: Better error reporting for install/remove of non-existing package (Anders F Bjorklund)
+ - smart: Fix progress report bug that was stopping update_system (Anders F Bjorklund)
+ - smart: Add basename_filtering (Anders F Bjorklund)
+ - smart: Need to reset backend between runs, when using dispatching mode (Anders F Bjorklund)
+ - smart: Use filters for get_updates (Anders F Bjorklund)
+ - smart: Set special repo data for installed/local (Anders F Bjorklund)
+ - smart: Fix unicode decode errors by using a temporary variable (Anders F Bjorklund)
+ - smart: Avoid looking in external pathlists for installed packages (Anders F Bjorklund)
+ - smart: Send more status updates when using dispatcher (Anders F Bjorklund)
+ - smart: Avoid KeyError when no extra deps (Anders F Bjorklund)
+ - smart: Add yum/yast metapackages group (Anders F Bjorklund)
+ - smart: Add alternative groups from opensuse rpm (Anders F Bjorklund)
+ - smart: Search for rpm subgroups, if no group matches (Anders F Bjorklund)
+ - smart: Add collections_filtering (Anders F Bjorklund)
+ - smart: Set special status for collection packages (Anders F Bjorklund)
+ - smart: Report get_details error when package not found or in wrong channel (Anders F Bjorklund)
+ - smart: Report get_fileserror when package not found or in wrong channel (Anders F Bjorklund)
+ - smart: Add mandriva rpm groups (Anders F Bjorklund)
+ - smart: Sync smart groups with urpmi groups somewhat (Anders F Bjorklund)
+ - smart: Move emulators to virtualization (Anders F Bjorklund)
+ - smart: Add more rpm groups from opensuse (Anders F Bjorklund)
+ - urpmi: Warn the user when installation failed because of bad signatures (Aurelien Lefebvre)
+ - urpmi: Best error's handle in refresh-cache method (Aurelien Lefebvre)
+ - urpmi: get-detail method now supports package ids list (Aurelien Lefebvre)
+ - urpmi: get-update-details now supports package ids list argument (Aurelien Lefebvre)
+ - urpmi: get-requires now supports package ids list argument (Aurelien Lefebvre)
+ - urpmi: resolve now supports package ids list argument (Aurelien Lefebvre)
+ - urpmi: get-files now supports package ids list argument (Aurelien Lefebvre)
+ - urpmi: get-depends now supports package ids list argument (Aurelien Lefebvre)
+ - urpmi: get_distro_upgrades method implemented (Aurelien Lefebvre)
+ - urpmi: Start converting methods to a dispatched backend (Aurelien Lefebvre)
+ - urpmi: Added support for install-packages to install more than one package (Aurelien Lefebvre)
+ - yum: Disable the YumDirect code, it dont work (Tim Lauridsen)
+ - yum: Add some code to support metapackage installation (Tim Lauridsen)
+ - yum: More metapackage functionality (Tim Lauridsen)
+ - yum: Add some percentage to collections (Tim Lauridsen)
+ - yum: Remove-packages should not fail on meta package (Tim Lauridsen)
+ - yum: Make remove-packages handle meta packages (Tim Lauridsen)
+ - yum: Make get-requires handle meta packages (comps groups) (Tim Lauridsen)
+ - yum: Handle unknown group in search-group (Tim Lauridsen)
+ - yum: Make get-details work with meta-packages (comps groups) (Tim Lauridsen)
+ - yum: Now we depend on 3.2.19, rip out YumDirectSQL as we can use yum directly
+        rather than fumble about in the sqlite files (Richard Hughes)
+ - yum: Add a workaround when getObsoletesTuples fails, fixes fd#17528 (Richard Hughes)
+ - yum: Support the collections group (Richard Hughes)
+ - yum: Handle the collections filter like we do all the other filters (Richard Hughes)
+ - zypp: Update the repo location (Scott Reeves)
+ - zypp: Implement fate #301904 to warn for outdated repo (Stefan Haas)
+ - zypp: Added get_distro_upgrades (Stefan Haas)
+ - zypp: Reset force flag also if something fails (Stefan Haas)
+
 Version 0.3.2
 ~~~~~~~~~~~~~~
 Released: 2008-09-08
diff --git a/RELEASE b/RELEASE
index 240ef43..de1e974 100644
--- a/RELEASE
+++ b/RELEASE
@@ -4,6 +4,7 @@ PackageKit Release Notes
    format as usual. Ignore any trivial commits.
 
 git-shortlog PACKAGEKIT_0_3_2.. | grep -v trivial | grep -v Merge > NEWS.new
+git-shortlog GNOME_PACKAGEKIT_0_3_2.. | grep -v trivial | grep -v Merge > NEWS.new
 
 2. Add download date to docs/html/pk-download.html, save file.
 
diff --git a/configure.ac b/configure.ac
index 2024ef2..d7c5709 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,7 @@ DEVELOPMENT_RELEASE=no
 # REVISION	If the API and ABI remains the same, but bugs are fixed.
 # AGE		If libpackagekit can be linked into executables which can be
 # 		built with previous versions of this library. Don't use.
-LT_CURRENT=5
+LT_CURRENT=6
 LT_REVISION=0
 LT_AGE=0
 AC_SUBST(LT_CURRENT)
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 83862f1..4dee921 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -73,6 +73,7 @@ Releases are normally once every 1-2 weeks.
 <tr><td>0.3.0</td><td></td><td>2008-08-18</td></tr>
 <tr><td>0.3.1</td><td></td><td>2008-08-27</td></tr>
 <tr><td>0.3.2</td><td></td><td>2008-09-08</td></tr>
+<tr><td>0.3.3</td><td></td><td>2008-09-16</td></tr>
 </table>
 <h3>
 ABI Stable Versions:
commit 0c9422f8ab945c0ead9405a55673968b37844e99
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:49:28 2008 +0200

    update mandriva description in pk-download.html

diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 29268c9..83862f1 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -45,8 +45,9 @@ easier to install.
    repository file and run: <code>zypper install PackageKit gnome-packagekit</code> (as root)
   </li>
   <li>
-   Mandriva 2009: Yes, add the <a href="http://wiki.mandriva.com/en/Development"><tt>cooker</tt></a>
-   repository and run: <code>urpmi packagekit gnome-packagekit</code> (as root)
+  Mandriva : PackageKit will be available on the next release of Mandriva (2009.0). You can already 
+  try it by adding the <a href="http://wiki.mandriva.com/en/Development"><tt>cooker</tt></a> repository.<br/>
+  Be carefull, it will update your system to the development branch of Mandriva. Use it at your own risk.
   </li>
   <li>
    Others: Probably not, although you can compile from source. See below for more details.
commit c526aaa6beccd5e3d17fe798c6bcb6b1ea7c1361
Merge: 7242813... d039ae6...
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:34:05 2008 +0200

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

commit 7242813fa99cd5991b533783d7af0daf2f01e64b
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:33:28 2008 +0200

    urpmi: added update-system and get-distro-upgrades method in dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index f579fdb..2ea85ee 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -15,7 +15,7 @@
 #
 # get-depends                   DONE
 # get-details                   DONE
-# get-distro-upgrades
+# get-distro-upgrades           DONE
 # get-files                     DONE
 # get-packages                  DONE
 # get-requires                  DONE
@@ -30,7 +30,7 @@
 # search-group                  DONE
 # search-name                   DONE
 # update-packages               DONE
-# update-system
+# update-system                 DONE
 #
 
 use strict;
@@ -72,6 +72,9 @@ while(<STDIN>) {
   elsif($command eq "get-details") {
     get_details($urpm, \@args);
   }
+  elsif($command eq "get-distro-upgrades") {
+    get_distro_upgrades();
+  }
   elsif($command eq "get-files") {
     get_files($urpm, \@args);
   }
@@ -115,6 +118,9 @@ while(<STDIN>) {
   elsif($command eq "update-packages") {
     update_packages($urpm, \@args);
   }
+  elsif($command eq "update-system") {
+    update_system($urpm);
+  }
 }
 
 
@@ -188,6 +194,48 @@ sub get_details {
   _finished();
 }
 
+sub get_distro_upgrades {
+
+  pk_print_status(PK_STATUS_ENUM_QUERY);
+
+  open(PRODUCT_FILE, "/etc/product.id");
+
+  my %product_id;
+  %product_id = _parse_line(<PRODUCT_FILE>);
+  close(PRODUCT_FILE);
+
+  my $distribfile_path = "/tmp/distrib.list";
+  _download_distrib_file($distribfile_path, \%product_id);
+
+  -f $distribfile_path or goto finished;
+
+  my @distribs;
+  open(DISTRIB_FILE, $distribfile_path);
+  while(<DISTRIB_FILE>) {
+    my %distrib = _parse_line($_);
+    push(@distribs, \%distrib);
+  }
+  close(DISTRIB_FILE);
+
+  my $distrib;
+  foreach (@distribs) {
+    if($_->{version} == $product_id{version}) {
+      $distrib = $_;
+    }
+  }
+
+  $distrib or goto finished;
+  @distribs = sort { $b->{release_date} <=> $a->{release_date} } @distribs;
+
+  my $newer_version = _get_newer_distrib($distrib->{version}, \@distribs);
+  $newer_version or goto finished;
+  pk_print_distro_upgrade(PK_DISTRO_UPGRADE_ENUM_STABLE, join(" ", "Mandriva", $product_id{product}, $newer_version->{version}), "");
+
+  unlink($distribfile_path);
+  finished:
+  _finished();
+}
+
 sub get_files {
   
   my ($urpm, $args) = @_;
@@ -633,6 +681,15 @@ sub update_packages {
   _finished();
 }
 
+sub update_system {
+  
+  my ($urpm) = @_;
+  eval {
+    perform_installation($urpm, {}, auto_select => 1);
+  };
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
@@ -725,3 +782,54 @@ sub _print_package_update_details {
     $restart ? PK_RESTART_ENUM_SYSTEM : PK_RESTART_ENUM_APPLICATION,
     $desc);
 }
+
+sub _parse_line {
+  my ($line) = @_;
+  my %hash;
+  my @affects = split(/,/, $line);
+  foreach my $affect (@affects) {
+    my ($variable, $value) = split(/=/, $affect);
+    chomp($variable);
+    chomp($value);
+    $hash{$variable} = $value;
+  }
+  return %hash;
+}
+
+sub _download_distrib_file {
+
+  my ($outfile, $product_id) = @_;
+  
+  -x "/usr/bin/wget" or die "wget is missing\n";
+  
+  my $api_url = sprintf("http://api.mandriva.com/distributions/%s.%s.list?product=%s",
+                  lc($product_id->{type}),
+                  lc($product_id->{arch}),
+                  lc($product_id->{product}));
+  
+  my $wget_command = join(" ", 
+                          "/usr/bin/wget",
+                          "--quiet",
+                          "--output-document", $outfile,
+                          $api_url);
+  
+  my $wget_pid = open(my $wget, "$wget_command |");
+  close($wget);
+}
+
+sub _get_newer_distrib {
+
+  my ($installed_version, $distrib_list) = @_;
+  my $installed_distrib;
+  foreach (@$distrib_list) {
+    if($_->{version} == $installed_version) {
+      $installed_distrib = $_;
+    }
+  }
+  $installed_distrib or return;
+  foreach (@$distrib_list) {
+    if($installed_distrib->{release_date} < $_->{release_date}) {
+      return $_;
+    }
+  }
+}
commit d039ae69f15a851db6db8c34a48da8625b87e004
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 15:22:06 2008 +0100

    trivial: add a new convenience helper, pk_bitfield_invert()

diff --git a/libpackagekit/pk-bitfield.c b/libpackagekit/pk-bitfield.c
index 768d4d2..cfe774f 100644
--- a/libpackagekit/pk-bitfield.c
+++ b/libpackagekit/pk-bitfield.c
@@ -323,6 +323,24 @@ pk_bitfield_test (EggTest *test)
 	g_free (text);
 
 	/************************************************************/
+	egg_test_title (test, "check we can invert a bit 1 -> 0");
+	values = pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT) | pk_bitfield_value (PK_FILTER_ENUM_NOT_NEWEST);
+	pk_bitfield_invert (values, PK_FILTER_ENUM_NOT_DEVELOPMENT);
+	if (values == pk_bitfield_value (PK_FILTER_ENUM_NOT_NEWEST))
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "values were %" PK_BITFIELD_FORMAT, values);
+
+	/************************************************************/
+	egg_test_title (test, "check we can invert a bit 0 -> 1");
+	values = 0;
+	pk_bitfield_invert (values, PK_FILTER_ENUM_NOT_DEVELOPMENT);
+	if (values == pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT))
+		egg_test_success (test, NULL);
+	else
+		egg_test_failed (test, "values were %" PK_BITFIELD_FORMAT, values);
+
+	/************************************************************/
 	egg_test_title (test, "check we can convert filter bitfield to text (single)");
 	text = pk_filter_bitfield_to_text (pk_bitfield_value (PK_FILTER_ENUM_NOT_DEVELOPMENT));
 	if (egg_strequal (text, "~devel"))
diff --git a/libpackagekit/pk-bitfield.h b/libpackagekit/pk-bitfield.h
index db331f1..72438b2 100644
--- a/libpackagekit/pk-bitfield.h
+++ b/libpackagekit/pk-bitfield.h
@@ -34,6 +34,7 @@ typedef guint64 PkBitfield;
 /* convenience functions as it's easy to forget the bitwise operators */
 #define pk_bitfield_add(bitfield,enum)		do { ((bitfield) |= (pk_bitfield_value(enum))); } while (0)
 #define pk_bitfield_remove(bitfield,enum)	do { ((bitfield) &= ~(pk_bitfield_value(enum))); } while (0)
+#define pk_bitfield_invert(bitfield,enum)	do { ((bitfield) ^= (pk_bitfield_value(enum))); } while (0)
 #define pk_bitfield_contain(bitfield,enum)	(((bitfield) & (pk_bitfield_value(enum))) > 0)
 #define pk_bitfield_value(enum)			((PkBitfield) 1 << (enum))
 
commit 398301f7f832409d76beb3e90250bfcd43cb056a
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:18:55 2008 +0200

    urpmi: added update-packages method to dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index 5a430e7..f579fdb 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -29,7 +29,7 @@
 # search-file                   DONE
 # search-group                  DONE
 # search-name                   DONE
-# update-packages
+# update-packages               DONE
 # update-system
 #
 
@@ -112,6 +112,9 @@ while(<STDIN>) {
   elsif($command eq "search-group") {
     search_group($urpm, \@args);
   }
+  elsif($command eq "update-packages") {
+    update_packages($urpm, \@args);
+  }
 }
 
 
@@ -598,6 +601,38 @@ sub search_group {
   _finished();
 }
 
+sub update_packages {
+
+  my ($urpm, $args) = @_;
+
+  my @names;
+  foreach(@{$args}) {
+    my @pkgid = split(/;/, $_);
+    push @names, $pkgid[0];
+  }
+
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+
+  my %requested;
+
+  my @depslist = @{$urpm->{depslist}};
+  my $pkg = undef;
+  foreach my $depslistpkg (@depslist) {
+    foreach my $name (@names) {
+      if($depslistpkg->name =~ /^$name$/ && $depslistpkg->flag_upgrade) {
+        $requested{$depslistpkg->id} = 1;
+        goto tonext;
+      }
+    }
+    tonext:
+  }
+  eval {
+    perform_installation($urpm, \%requested);
+  };
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit 9844885ad53c94ab9025cef8eae9a378915941dd
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:08:13 2008 +0200

    urpmi: added search-group method in dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index 45f4108..5a430e7 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -27,7 +27,7 @@
 # resolve                       DONE
 # search-details                DONE
 # search-file                   DONE
-# search-group
+# search-group                  DONE
 # search-name                   DONE
 # update-packages
 # update-system
@@ -48,6 +48,7 @@ use urpmi_backend::actions;
 use urpmi_backend::open_db;
 use urpmi_backend::tools;
 use urpmi_backend::filters;
+use urpmi_backend::groups;
 
 use perl_packagekit::enums;
 use perl_packagekit::prints;
@@ -108,6 +109,9 @@ while(<STDIN>) {
   elsif($command eq "search-file") {
     search_file($urpm, \@args);
   }
+  elsif($command eq "search-group") {
+    search_group($urpm, \@args);
+  }
 }
 
 
@@ -558,6 +562,42 @@ sub search_file {
   _finished();
 }
 
+sub search_group {
+
+  my ($urpm, $args) = @_;
+  my @filters = split(/;/, @{$args}[0]);
+  my $pk_group = @{$args}[1];
+  
+  pk_print_status(PK_STATUS_ENUM_QUERY);
+
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+
+  if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+    $db->traverse(sub {
+        my ($pkg) = @_;
+        if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+          if(package_belongs_to_pk_group($pkg, $pk_group)) {
+            pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+          }
+        }
+      });
+  }
+
+  if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+    foreach my $pkg(@{$urpm->{depslist}}) {
+      if($pkg->flag_upgrade) {
+        if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+          if(package_belongs_to_pk_group($pkg, $pk_group)) {
+            pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+          }
+        }
+      }  
+    }
+  }
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit d46141ff724d7f49b375d22eddb0f10bbc4c246a
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 16:00:44 2008 +0200

    urpmi: search_file method added in dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index 3e65d3b..45f4108 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -26,7 +26,7 @@
 # remove-packages               DONE
 # resolve                       DONE
 # search-details                DONE
-# search-file
+# search-file                   DONE
 # search-group
 # search-name                   DONE
 # update-packages
@@ -105,6 +105,9 @@ while(<STDIN>) {
   elsif($command eq "search-details") {
     search_details($urpm, \@args);
   }
+  elsif($command eq "search-file") {
+    search_file($urpm, \@args);
+  }
 }
 
 
@@ -528,6 +531,33 @@ sub search_details {
   _finished();
 }
 
+sub search_file {
+
+  my ($urpm, $args) = @_;
+  my @filters = split(/;/, @{$args}[0]);
+  my $search_term = @{$args}[1];
+
+  my %requested;
+
+  pk_print_status(PK_STATUS_ENUM_QUERY);
+
+  perform_file_search($urpm, \%requested, $search_term, fuzzy => 1);
+
+  foreach(keys %requested) {
+    my $p = @{$urpm->{depslist}}[$_];
+    if(filter($p, \@filters, { FILTER_INSTALLED => 1, FILTER_DEVELOPMENT=> 1, FILTER_GUI => 1})) {
+      my $version = find_installed_version($p);
+      if($version eq $p->version."-".$p->release) {
+        pk_print_package(INFO_INSTALLED, get_package_id($p), ensure_utf8($p->summary));
+      }
+      else {
+        pk_print_package(INFO_AVAILABLE, get_package_id($p), ensure_utf8($p->summary));
+      }
+    }
+  }
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit c90bad1ff51c485e604d15a6d52e9274f2867d0c
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 15:49:53 2008 +0200

    urpmi: added get_details method to dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index 3707746..3e65d3b 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -25,7 +25,7 @@
 # refresh-cache                 DONE
 # remove-packages               DONE
 # resolve                       DONE
-# search-details
+# search-details                DONE
 # search-file
 # search-group
 # search-name                   DONE
@@ -102,6 +102,9 @@ while(<STDIN>) {
   elsif($command eq "resolve") {
     resolve($urpm, \@args);
   }
+  elsif($command eq "search-details") {
+    search_details($urpm, \@args);
+  }
 }
 
 
@@ -488,6 +491,43 @@ sub resolve {
   _finished();
 }
 
+sub search_details {
+
+  my ($urpm, $args) = @_;
+  my @filters = split(/;/, @{$args}[0]);
+  shift @{$args};
+  my $search_term = pop @{$args};
+
+  pk_print_status(PK_STATUS_ENUM_QUERY);
+
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+
+  if(not grep(/^${\FILTER_NOT_INSTALLED}$/, @filters)) {
+    $db->traverse(sub {
+        my ($pkg) = @_;
+        if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+          if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) {
+            pk_print_package(INFO_INSTALLED, get_package_id($pkg), ensure_utf8($pkg->summary));
+          }
+        }
+      });
+  }
+
+  if(not grep(/^${\FILTER_INSTALLED}$/, @filters)) {
+    foreach my $pkg(@{$urpm->{depslist}}) {
+      if($pkg->flag_upgrade) {
+        if(filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1})) {
+          if($pkg->name =~ /$search_term/ || $pkg->summary =~ /$search_term/ || $pkg->url =~ /$search_term/) {
+            pk_print_package(INFO_AVAILABLE, get_package_id($pkg), ensure_utf8($pkg->summary));
+          }
+        }
+      }  
+    }
+  }
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit 2eaa1df00a795be3ba068d53f92480b74bb1c106
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 15:37:13 2008 +0200

    urpmi: added resolve method to dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index baa18d3..3707746 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -24,7 +24,7 @@
 # install-packages		DONE
 # refresh-cache                 DONE
 # remove-packages               DONE
-# resolve
+# resolve                       DONE
 # search-details
 # search-file
 # search-group
@@ -99,6 +99,9 @@ while(<STDIN>) {
   elsif($command eq "remove-packages") {
     remove_packages($urpm, \@args);
   }
+  elsif($command eq "resolve") {
+    resolve($urpm, \@args);
+  }
 }
 
 
@@ -445,6 +448,46 @@ sub remove_packages {
   _finished();
 }
 
+sub resolve {
+
+  my ($urpm, $args) = @_;
+
+  my @filters = split(/;/, @{$args}[0]);
+  shift @{$args};
+  my @patterns = @{$args};
+
+  pk_print_status(PK_STATUS_ENUM_QUERY);
+
+  my %requested;
+  urpm::select::search_packages($urpm, \%requested, \@patterns, 
+    fuzzy => 0, 
+    caseinsensitive => 0,
+    all => 0
+  );
+
+  my @requested_keys = keys %requested;
+  my $db = open_rpm_db();
+  $urpm->compute_installed_flags($db);
+
+  foreach (@requested_keys) {
+    my $pkg = @{$urpm->{depslist}}[$_];
+    ($_ && $pkg) or next;
+
+    # We exit the script if found package does not match with specified filters
+    filter($pkg, \@filters, {FILTER_DEVELOPMENT => 1, FILTER_GUI => 1}) or next;
+
+    if($pkg->version."-".$pkg->release eq find_installed_version($pkg)) {
+      grep(/^${\FILTER_NOT_INSTALLED}$/, @filters) and next;
+      pk_print_package(INFO_INSTALLED, get_package_id($pkg), $pkg->summary);
+    }
+    else {
+      grep(/^${\FILTER_INSTALLED}$/, @filters) and next;
+      pk_print_package(INFO_AVAILABLE, get_package_id($pkg), $pkg->summary);
+    }
+  }
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit de0a6a4e80b992fce63b2046fb1cb0bca28289dd
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Sep 16 15:32:12 2008 +0200

    python: make the PolicyKit auth work right

diff --git a/python/packagekit/client.py b/python/packagekit/client.py
index 2447cfb..d51c69d 100644
--- a/python/packagekit/client.py
+++ b/python/packagekit/client.py
@@ -9,6 +9,7 @@
 #
 # Synchronous PackageKit client wrapper API for Python.
 
+import os
 import gobject
 import dbus
 from enums import *
@@ -514,9 +515,9 @@ def polkit_auth_wrapper(fn, *args, **kwargs):
             # last words in message are privilege and auth result
             (priv, auth_result) = e.message.split()[-2:]
             if auth_result.startswith('auth_'):
-                pk_auth = dbus.Interface(dbus.SessionBus().get_object(
-                    'org.freedesktop.PolicyKit.AuthenticationAgent', '/', False),
-                    'org.freedesktop.PolicyKit.AuthenticationAgent')
+                pk_auth = dbus.SessionBus().get_object(
+                    'org.freedesktop.PolicyKit.AuthenticationAgent', '/', 'org.gnome.PolicyKit.AuthorizationManager.SingleInstance')
+
                 # TODO: provide xid
                 res = pk_auth.ObtainAuthorization(priv, dbus.UInt32(0),
                     dbus.UInt32(os.getpid()), timeout=300)
commit c9c8bd5e206bf5f94a4a97c6c7ac8828cb8ae15d
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 15:28:53 2008 +0200

    urpmi: remove-packages method added to dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index be42b9a..baa18d3 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -22,8 +22,8 @@
 # get-update-detail             DONE
 # get-updates                   DONE
 # install-packages		DONE
-# refresh-cache
-# remove-packages
+# refresh-cache                 DONE
+# remove-packages               DONE
 # resolve
 # search-details
 # search-file
@@ -96,6 +96,9 @@ while(<STDIN>) {
     refresh_cache($urpm);
     urpm::media::configure($urpm);
   }
+  elsif($command eq "remove-packages") {
+    remove_packages($urpm, \@args);
+  }
 }
 
 
@@ -382,6 +385,66 @@ sub refresh_cache {
 
 }
 
+sub remove_packages {
+
+  my ($urpm, $args) = @_;
+
+  my $notfound = 0;
+  my $notfound_callback = sub {
+    $notfound = 1;
+  };
+
+  my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 1);
+
+  my $allowdeps_text = shift @{$args};
+  my $allowdeps_option = $allowdeps_text eq "yes" ? 1 : 0;
+  my @packageidstab = @{$args};
+
+  my @names;
+  foreach(@packageidstab) {
+    my @pkg_id = (split(/;/, $_));
+    push @names, $pkg_id[0];
+  }
+
+  pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
+
+  my $state = {};
+  my @breaking_pkgs = ();
+  my @to_remove = urpm::select::find_packages_to_remove($urpm,
+    $state,
+    \@names,
+    callback_notfound => $notfound_callback,
+    callback_fuzzy => $notfound_callback,
+    callback_base => sub {
+      my $urpm = shift @_;
+      push @breaking_pkgs, @_;
+    }
+  );
+
+  if($notfound) {
+    pk_print_error(PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "Some selected packages are not installed on your system");
+  }
+  elsif(@breaking_pkgs) {
+    pk_print_error(PK_ERROR_ENUM_CANNOT_REMOVE_SYSTEM_PACKAGE, "Removing selected packages will break your system");
+  }
+  elsif(!$allowdeps_option && scalar(@to_remove) != scalar(@names)) {
+    pk_print_error(PK_ERROR_ENUM_TRANSACTION_ERROR, "Packages can't be removed because dependencies remove is forbidden");
+  }
+  else {
+    pk_print_status(PK_STATUS_ENUM_REMOVE);
+    urpm::install::install($urpm,
+      \@to_remove, {}, {},
+      callback_report_uninst => sub {
+        my @return = split(/ /, $_[0]);
+        pk_print_package(INFO_REMOVING, fullname_to_package_id($return[$#return]), "");
+      }
+    );
+  }
+
+  $urpmi_lock->unlock;
+  _finished();
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit 4cf637c06c44d6bc27e09c3d747786cdaa6ddf5b
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Sep 16 14:56:02 2008 +0200

    python: minor fixes to python client API

diff --git a/python/packagekit/client.py b/python/packagekit/client.py
index 62cf3be..2447cfb 100644
--- a/python/packagekit/client.py
+++ b/python/packagekit/client.py
@@ -415,6 +415,7 @@ class PackageKitClient:
         self._error_enum = enum
 
     def _h_finished(self, status, code):
+        self._finished_status = status
         self.main_loop.quit()
 
     def _h_progress(self, per, subper, el, rem):
@@ -460,15 +461,16 @@ class PackageKitClient:
         pk_xn.connect_to_signal('ErrorCode', self._h_error)
         pk_xn.connect_to_signal('Finished', self._h_finished)
         if action == "install":
-            pk_xn.InstallPackages(package_ids)
+           polkit_auth_wrapper(lambda : pk_xn.InstallPackages(package_ids))
         elif action == "remove":
-            pk_xn.RemovePackages(package_ids, allow_deps, auto_remove)
+            polkit_auth_wrapper(lambda : pk_xn.RemovePackages(package_ids, allow_deps, auto_remove))
         elif action == "update":
-            pk_xn.UpdatePackages(package_ids)
+            polkit_auth_wrapper(lambda : pk_xn.UpdatePackages(package_ids))
         self._wait()
         if self._error_enum:
             raise PackageKitError(self._error_enum)
         if self._finished_status != 'success':
+            print self._finished_status
             raise PackageKitError('internal-error')
 
     def _get_xn(self):
@@ -495,7 +497,7 @@ class PackageKitClient:
 
 #### PolicyKit authentication borrowed wrapper ##
 class PermissionDeniedByPolicy(dbus.DBusException):
-    _dbus_error_name = 'org.freedesktop.PackageKit.PermissionDeniedByPolicy'
+    _dbus_error_name = 'org.freedesktop.PackageKit.Transaction.RefusedByPolicy'
 
 
 def polkit_auth_wrapper(fn, *args, **kwargs):
@@ -518,6 +520,7 @@ def polkit_auth_wrapper(fn, *args, **kwargs):
                 # TODO: provide xid
                 res = pk_auth.ObtainAuthorization(priv, dbus.UInt32(0),
                     dbus.UInt32(os.getpid()), timeout=300)
+                print res
                 if res:
                     return fn(*args, **kwargs)
             raise PermissionDeniedByPolicy(priv + ' ' + auth_result)
@@ -525,5 +528,6 @@ def polkit_auth_wrapper(fn, *args, **kwargs):
             raise
 
 
+
 if __name__ == '__main__':
     pass
diff --git a/python/wrapper-test.py b/python/wrapper-test.py
index 5e98a98..61870f6 100755
--- a/python/wrapper-test.py
+++ b/python/wrapper-test.py
@@ -86,12 +86,14 @@ if __name__ == '__main__':
         print '---- InstallPackages() -----'
         pkg = pk.Resolve(FILTER_NOT_INSTALLED, 'yumex')
         if pkg:
+            print "Installing : %s " % pkg[0]['id']
             pk.InstallPackages(pkg[0]['id'], cb)
 
     if "remove-packages" in cmd:
         print '---- RemovePackages() -----'
-        pkg = pk.Resolve(FILTER_NOT_INSTALLED, 'yumex')
+        pkg = pk.Resolve(FILTER_INSTALLED, 'yumex')
         if pkg:
+            print "Removing : %s " % pkg[0]['id']
             pk.RemovePackages(pkg[0]['id'], cb)
 
 
commit 61de8e0e7c5a13de1a1fb6583189e90a81780daf
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Sep 16 13:54:30 2008 +0200

    python client API:
    * ImplemtedGetUpdateDetails
    * Fixed some syntax errors
    * auto convert str -> list in package_ids.
    * make wrapper-test take cmd line argument for better testing

diff --git a/python/packagekit/client.py b/python/packagekit/client.py
index 55da659..62cf3be 100644
--- a/python/packagekit/client.py
+++ b/python/packagekit/client.py
@@ -100,6 +100,31 @@ class PackageKitClient:
         self._wrapCall(pk_xn, method, {'Details' : details_cb})
         return result
 
+    def _wrapUpdateDetailsCall(self, pk_xn, method):
+        '''
+        Wraps a call which emits Finished, ErrorCode on completion and
+        Details for information returns a list of dicts with 'id',
+        'license', 'group', 'description', 'upstream_url', 'size'.keys
+        '''
+        result = []
+        details_cb =  lambda id, updates, obsoletes, vendor_url, bugzilla_url, \
+                             cve_url, restart, update_text, changelog, state, \
+                             issued, updated: result.append(
+        {"id" : id,
+         "updates"      : updates,
+         "obsoletes"    : obsoletes,
+         "vendor_url"   : vendor_url,
+         "bugzilla_url" : bugzilla_url,
+         "cve_url"      : cve_url,
+         "restart"      : restart,
+         "update_text"  : update_text,
+         "changelog"    : changelog,
+         "state"        : state,
+         "issued"       : issued,
+         "updated"      : updated})
+        self._wrapCall(pk_xn, method, {'UpdateDetail' : details_cb})
+        return result
+
     def _wrapReposCall(self, pk_xn, method):
         '''
         Wraps a call which emits Finished, ErrorCode and RepoDetail
@@ -134,19 +159,21 @@ class PackageKitClient:
         for all matches, where installed is a boolean and id and
         short_description are strings.
         '''
+        package = self._to_list(package) # Make sure we have a list
         xn = self._get_xn()
         return self._wrapPackageCall(xn, lambda : xn.Resolve(filter, package))
 
 
-    def GetDetails(self, package_id):
+    def GetDetails(self, package_ids):
         '''
-        Get details about a PackageKit package_id.
+        Get details about a PackageKit package_ids.
 
         Return dict with keys (id, license, group, description,
         upstream_url, size).
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         xn = self._get_xn()
-        return self._wrapDetailsCall(xn, lambda : xn.GetDetails(package_id))
+        return self._wrapDetailsCall(xn, lambda : xn.GetDetails(package_ids))
 
     def SearchName(self, filter, name):
         '''
@@ -188,6 +215,7 @@ class PackageKitClient:
 
         On failure this throws a PackageKitError or a DBusException.
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         self._doPackages(package_ids, progress_cb, 'install')
 
     def UpdatePackages(self, package_ids, progress_cb=None):
@@ -200,6 +228,7 @@ class PackageKitClient:
 
         On failure this throws a PackageKitError or a DBusException.
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         self._doPackages(package_ids, progress_cb, 'update')
 
     def RemovePackages(self, package_ids, progress_cb=None, allow_deps=False,
@@ -215,6 +244,7 @@ class PackageKitClient:
 
         On failure this throws a PackageKitError or a DBusException.
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         self._doPackages(package_ids, progress_cb, 'remove', allow_deps,
             auto_remove)
 
@@ -293,6 +323,7 @@ class PackageKitClient:
         '''
         Search for dependencies for packages
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         xn = self._get_xn()
         return self._wrapPackageCall(xn,
                                      lambda : xn.GetDepends(filter,package_ids,recursive))
@@ -307,12 +338,18 @@ class PackageKitClient:
         '''
         Search for requirements for packages
         '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
         xn = self._get_xn()
         return self._wrapPackageCall(xn,
                                      lambda : xn.GetRequires(filter,package_ids,recursive))
 
     def GetUpdateDetail(self,package_ids):
-        raise PackageKitError(ERROR_NOT_SUPPORTED)
+        '''
+        Get details for updates
+        '''
+        package_ids = self._to_list(package_ids) # Make sure we have a list
+        xn = self._get_xn()
+        return self._wrapUpdateDetailsCall(xn, lambda : xn.GetUpdateDetail(package_ids))
 
     def GetDistroUpgrades(self):
         raise PackageKitError(ERROR_NOT_SUPPORTED)
@@ -320,7 +357,7 @@ class PackageKitClient:
     def InstallFiles(self,trusted,files):
         raise PackageKitError(ERROR_NOT_SUPPORTED)
 
-    def InstallSignatures(self.sig_type,key_id,package_id):
+    def InstallSignatures(self,sig_type,key_id,package_id):
         raise PackageKitError(ERROR_NOT_SUPPORTED)
 
     def RepoEnable(self,repo_id,enabled):
@@ -358,6 +395,12 @@ class PackageKitClient:
             obj = obj.encode('utf-8', errors)
         return obj
 
+    def _to_list(self, obj, errors='replace'):
+        '''convert 'unicode' to an encoded utf-8 byte string '''
+        if isinstance(obj, str):
+            obj = [obj]
+        return obj
+
     def _wait(self):
         '''Wait until an async PK operation finishes.'''
         self.main_loop.run()
diff --git a/python/wrapper-test.py b/python/wrapper-test.py
index 63cd154..5e98a98 100755
--- a/python/wrapper-test.py
+++ b/python/wrapper-test.py
@@ -23,55 +23,76 @@ from packagekit.client import PackageKitClient
 from packagekit.enums import *
 
 if __name__ == '__main__':
-    pk = PackageKitClient()
-
-    #print '---- RefreshCache() -----'''
-    #print pk.RefreshCache()
-
-    print '---- Resolve() -----'
-    pkg = pk.Resolve(FILTER_NONE, ['yum'])
-    print pkg[0]
-
-    print '---- GetPackages() ----'
-    packages = pk.GetPackages(FILTER_INSTALLED)
-    i = 0
-    for pkg in packages:
-        i += 1
-        if i == 20:
-            break
-        (name,ver,arch,repo) = tuple(pkg['id'].split(";"))
-        p =  "%s-%s.%s" % (name,ver,arch)
-        print "%-40s : %s" % (p,pkg['summary'])
-        details = pk.GetDetails([pkg['id']])
-        print 79 *"-"
-        print details[0]['detail']
-
-    print '---- SearchFiles() ----'
-    print pk.SearchFile(FILTER_INSTALLED,"/usr/bin/yum")
+    if len(sys.argv) > 1:
+        cmd = sys.argv[1:]
+    else:
+        cmd = 'all'
 
-    print '---- GetUpdates() ----'
-    print pk.GetUpdates(FILTER_INSTALLED)
+    pk = PackageKitClient()
 
-    print '---- SearchName() -----'
-    print pk.SearchName(FILTER_NOT_INSTALLED, 'coreutils')
-    print pk.SearchName(FILTER_INSTALLED, 'coreutils')
+    if 'all' in cmd or "refresh-cache" in cmd:
+        print '---- RefreshCache() -----'''
+        print pk.RefreshCache()
+
+    if 'all' in cmd or "resolve" in cmd:
+        print '---- Resolve() -----'
+        pkg = pk.Resolve(FILTER_NONE, 'yum')
+        if pkg:
+            print pkg
+
+    if 'all' in cmd or "get-packages" in cmd:
+        print '---- GetPackages() ----'
+        packages = pk.GetPackages(FILTER_INSTALLED)
+        i = 0
+        for pkg in packages:
+            i += 1
+            if i == 20:
+                break
+            (name,ver,arch,repo) = tuple(pkg['id'].split(";"))
+            p =  "%s-%s.%s" % (name,ver,arch)
+            print "%-40s : %s" % (p,pkg['summary'])
+            details = pk.GetDetails(pkg['id'])
+            print 79 *"-"
+            print details[0]['detail']
+
+    if 'all' in cmd or "search-file" in cmd:
+        print '---- SearchFile() ----'
+        print pk.SearchFile(FILTER_INSTALLED,"/usr/bin/yum")
+
+    if 'all' in cmd or "get-updates" in cmd:
+        print '---- GetUpdates() ----'
+        pkgs = pk.GetUpdates(FILTER_INSTALLED)
+        if pkgs: # We have updates
+            for p in pkgs:
+                print p['id']
+                print pk.GetUpdateDetail(p['id'])
+
+    if 'all' in cmd or "search-name" in cmd:
+        print '---- SearchName() -----'
+        print pk.SearchName(FILTER_NOT_INSTALLED, 'coreutils')
+        print pk.SearchName(FILTER_INSTALLED, 'coreutils')
 
-    sys.exit(0)
 
     def cb(status, pc, spc, el, rem, c):
         print 'install pkg: %s, %i%%, cancel allowed: %s' % (status, pc, str(c))
         return True
         #return pc < 12
 
-    print '---- UpdateSystem() ----'
-    print pk.UpdateSystem()
-
-    print '---- InstallPackages() -----'
-    pk.InstallPackages(['pmount;0.9.17-2;i386;Ubuntu', 'quilt;0.46-6;all;Ubuntu'], cb)
-
-
-    print '---- RemovePackages() -----'
-    pk.RemovePackages(['pmount;0.9.17-2;i386;Ubuntu', 'quilt;0.46-6;all;Ubuntu'], cb)
+    if "updates-system" in cmd:
+        print '---- UpdateSystem() ----'
+        print pk.UpdateSystem()
+
+    if "install-packages" in cmd:
+        print '---- InstallPackages() -----'
+        pkg = pk.Resolve(FILTER_NOT_INSTALLED, 'yumex')
+        if pkg:
+            pk.InstallPackages(pkg[0]['id'], cb)
+
+    if "remove-packages" in cmd:
+        print '---- RemovePackages() -----'
+        pkg = pk.Resolve(FILTER_NOT_INSTALLED, 'yumex')
+        if pkg:
+            pk.RemovePackages(pkg[0]['id'], cb)
 
 
     pk.SuggestDaemonQuit()
commit 4591486abc7eb202152f382658861b2acd057a59
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 12:37:42 2008 +0100

    trivial, abi: rename some argv to strv to match glib

diff --git a/client/pk-console.c b/client/pk-console.c
index cac0f08..42dc597 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -644,7 +644,7 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	/* any to process? */
 	if (array_packages->len > 0) {
 		/* convert to strv */
-		package_ids = pk_ptr_array_to_argv (array_packages);
+		package_ids = pk_ptr_array_to_strv (array_packages);
 
 		/* reset */
 		ret = pk_client_reset (client, error);
@@ -663,7 +663,7 @@ pk_console_install_stuff (PkClient *client, gchar **packages, GError **error)
 	/* any to process? */
 	if (array_files->len > 0) {
 		/* convert to strv */
-		files = pk_ptr_array_to_argv (array_files);
+		files = pk_ptr_array_to_strv (array_files);
 
 		/* save for untrusted callback */
 		g_strfreev (files_cache);
@@ -747,7 +747,7 @@ pk_console_remove_packages (PkClient *client, gchar **packages, GError **error)
 	}
 
 	/* convert to strv */
-	package_ids = pk_ptr_array_to_argv (array);
+	package_ids = pk_ptr_array_to_strv (array);
 
 	/* are we dumb and can't check for requires? */
 	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_REQUIRES)) {
@@ -855,7 +855,7 @@ pk_console_download_packages (PkClient *client, gchar **packages, const gchar *d
 	/* any to process? */
 	if (array_packages->len > 0) {
 		/* convert to strv */
-		package_ids = pk_ptr_array_to_argv (array_packages);
+		package_ids = pk_ptr_array_to_strv (array_packages);
 
 		/* reset */
 		ret = pk_client_reset (client, error);
diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index d97ffb4..2d5c6ca 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -343,7 +343,7 @@ pk_strvalidate (const gchar *text)
 }
 
 /**
- * pk_ptr_array_to_argv:
+ * pk_ptr_array_to_strv:
  * @array: the GPtrArray of strings
  *
  * Form a composite string array of strings.
@@ -352,7 +352,7 @@ pk_strvalidate (const gchar *text)
  * Return value: the string array, or %NULL if invalid
  **/
 gchar **
-pk_ptr_array_to_argv (GPtrArray *array)
+pk_ptr_array_to_strv (GPtrArray *array)
 {
 	gchar **strv_array;
 	const gchar *value_temp;
@@ -373,7 +373,7 @@ pk_ptr_array_to_argv (GPtrArray *array)
 }
 
 /**
- * pk_argv_to_ptr_array:
+ * pk_strv_to_ptr_array:
  * @array: the gchar** array of strings
  *
  * Form a GPtrArray array of strings.
@@ -382,7 +382,7 @@ pk_ptr_array_to_argv (GPtrArray *array)
  * Return value: the string array, or %NULL if invalid
  **/
 GPtrArray *
-pk_argv_to_ptr_array (gchar **array)
+pk_strv_to_ptr_array (gchar **array)
 {
 	guint i;
 	guint length;
@@ -457,7 +457,7 @@ pk_va_list_to_argv (const gchar *string_first, va_list *args)
 	}
 
 	/* convert the array to a strv type */
-	array = pk_ptr_array_to_argv (ptr_array);
+	array = pk_ptr_array_to_strv (ptr_array);
 
 	/* get rid of the array, and free the contents */
 	g_ptr_array_foreach (ptr_array, (GFunc) g_free, NULL);
diff --git a/libpackagekit/pk-common.h b/libpackagekit/pk-common.h
index b0001f0..aebd9d3 100644
--- a/libpackagekit/pk-common.h
+++ b/libpackagekit/pk-common.h
@@ -65,9 +65,9 @@ gboolean	 pk_strvalidate				(const gchar	*text)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		*pk_strsafe				(const gchar	*text)
 							 G_GNUC_WARN_UNUSED_RESULT;
-gchar		**pk_ptr_array_to_argv			(GPtrArray	*array)
+gchar		**pk_ptr_array_to_strv			(GPtrArray	*array)
 							 G_GNUC_WARN_UNUSED_RESULT;
-GPtrArray	*pk_argv_to_ptr_array			(gchar		**array)
+GPtrArray	*pk_strv_to_ptr_array			(gchar		**array)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		**pk_va_list_to_argv			(const gchar	*string_first,
 							 va_list	*args)
diff --git a/libpackagekit/pk-package-ids.c b/libpackagekit/pk-package-ids.c
index c179853..08ccbfc 100644
--- a/libpackagekit/pk-package-ids.c
+++ b/libpackagekit/pk-package-ids.c
@@ -68,7 +68,7 @@ pk_package_ids_from_id (const gchar *package_id)
 gchar **
 pk_package_ids_from_array (GPtrArray *array)
 {
-	return pk_ptr_array_to_argv (array);
+	return pk_ptr_array_to_strv (array);
 }
 
 /**
diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index f72628a..8f55d44 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -184,7 +184,7 @@ pk_package_list_to_argv (PkPackageList *plist)
 	}
 
 	/* convert to argv */
-	package_ids = pk_ptr_array_to_argv (array);
+	package_ids = pk_ptr_array_to_strv (array);
 	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
 	g_ptr_array_free (array, TRUE);
 
diff --git a/src/pk-backend-spawn.c b/src/pk-backend-spawn.c
index 1c4fb4f..93dcd06 100644
--- a/src/pk-backend-spawn.c
+++ b/src/pk-backend-spawn.c
@@ -472,7 +472,7 @@ pk_backend_spawn_get_envp (PkBackendSpawn *backend_spawn)
 	}
 	g_free (value);
 
-	envp = pk_ptr_array_to_argv (array);
+	envp = pk_ptr_array_to_strv (array);
 	g_ptr_array_foreach (array, (GFunc) g_free, NULL);
 	g_ptr_array_free (array, TRUE);
 	return envp;
diff --git a/src/pk-transaction-list.c b/src/pk-transaction-list.c
index 2bdb9d6..c079489 100644
--- a/src/pk-transaction-list.c
+++ b/src/pk-transaction-list.c
@@ -429,7 +429,7 @@ pk_transaction_list_get_array (PkTransactionList *tlist)
 			g_ptr_array_add (parray, g_strdup (item->tid));
 	}
 	egg_debug ("%i transactions in list, %i active", length, parray->len);
-	array = pk_ptr_array_to_argv (parray);
+	array = pk_ptr_array_to_strv (parray);
 	g_ptr_array_foreach (parray, (GFunc) g_free, NULL);
 	g_ptr_array_free (parray, TRUE);
 
diff --git a/src/pk-transaction.c b/src/pk-transaction.c
index 196b8ee..6b20c51 100644
--- a/src/pk-transaction.c
+++ b/src/pk-transaction.c
@@ -2102,7 +2102,7 @@ pk_transaction_get_update_detail (PkTransaction *transaction, gchar **package_id
 
 	/* get the new list */
 	egg_debug ("%i more to process", array->len);
-	package_ids_new = pk_ptr_array_to_argv (array);
+	package_ids_new = pk_ptr_array_to_strv (array);
 
 	/* alter list */
 	g_strfreev (transaction->priv->cached_package_ids);
commit 2f3ff1e00aaf12bee19eb518ecd2923b2f6c1404
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Sep 16 13:01:21 2008 +0200

    Added client Python API based on the packagekitwrapper.py
    * Added missing PK API methods (Not all is implemented yet, just stubs)
    * Make it handle Unicode
    * Added wrapper-test.py to test the API

diff --git a/python/packagekit/Makefile.am b/python/packagekit/Makefile.am
index 4c65216..8aec249 100644
--- a/python/packagekit/Makefile.am
+++ b/python/packagekit/Makefile.am
@@ -16,6 +16,7 @@ packagekitpython_PYTHON =				\
 	pkdbus.py					\
 	progress.py					\
 	package.py					\
+	client.py					\
 	$(NULL)
 
 clean-local :
diff --git a/python/packagekit/client.py b/python/packagekit/client.py
new file mode 100644
index 0000000..55da659
--- /dev/null
+++ b/python/packagekit/client.py
@@ -0,0 +1,486 @@
+#!/usr/bin/python
+#
+# (c) 2008
+#    Canonical Ltd.
+#    Aidan Skinner <aidan at skinner.me.uk>
+#    Martin Pitt <martin.pitt at ubuntu.com>
+#    Tim Lauridsen <timlau at fedoraproject.org>
+# License: LGPL 2.1 or later
+#
+# Synchronous PackageKit client wrapper API for Python.
+
+import gobject
+import dbus
+from enums import *
+
+class PackageKitError(Exception):
+    '''PackageKit error.
+
+    This class mainly wraps a PackageKit "error enum". See
+    http://www.packagekit.org/pk-reference.html#introduction-errors for details
+    and possible values.
+    '''
+    def __init__(self, error):
+        self.error = error
+
+    def __str__(self):
+        return self.error
+
+class PackageKitClient:
+    '''PackageKit client wrapper class.
+
+    This exclusively uses synchonous calls. Functions which take a long time
+    (install/remove packages) have callbacks for progress feedback.
+    '''
+    def __init__(self, main_loop=None):
+        '''Initialize a PackageKit client.
+
+        If main_loop is None, this sets up its own gobject.MainLoop(),
+        otherwise it attaches to the specified one.
+        '''
+        self.pk_control = None
+        if main_loop is None:
+            import dbus.mainloop.glib
+            main_loop = gobject.MainLoop()
+            dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+        self.main_loop = main_loop
+
+        self.bus = dbus.SystemBus()
+
+    def _wrapCall(self, pk_xn, method, callbacks):
+        '''
+        Wraps a call which emits Finished and ErrorCode on completion
+        '''
+        pk_xn.connect_to_signal('Finished', self._h_finished)
+        pk_xn.connect_to_signal('ErrorCode', self._h_error)
+        for cb in callbacks.keys():
+            pk_xn.connect_to_signal(cb, callbacks[cb])
+
+        polkit_auth_wrapper(method)
+        self._wait()
+        if self._error_enum:
+            raise PackageKitError(self._error_enum)
+
+
+    def _wrapBasicCall(self, pk_xn, method):
+        return self._wrapCall(pk_xn, method, {})
+
+    def _wrapPackageCall(self, pk_xn, method):
+        '''
+        Wraps a call which emits Finished, ErrorCode on completion and
+        Package for information returns a list of dicts with
+        'installed', 'id' and 'summary' keys
+        '''
+
+        result = []
+        package_cb = lambda i, id, summary: result.append(
+            {'installed' : (i == 'installed'),
+             'id': str(id),
+             'summary' : self._to_utf8(summary)
+             })
+        self._wrapCall(pk_xn, method, {'Package' : package_cb})
+        return result
+
+    def _wrapDetailsCall(self, pk_xn, method):
+        '''
+        Wraps a call which emits Finished, ErrorCode on completion and
+        Details for information returns a list of dicts with 'id',
+        'license', 'group', 'description', 'upstream_url', 'size'.keys
+        '''
+        result = []
+        details_cb = lambda id, license, group, detail, url, size: result.append(
+        {"id" : (str(id)),
+          "license" : (str(license)),
+          "group" : (str(group)),
+          "detail" : (self._to_utf8(detail)),
+          "url" : str(url),
+          "size" : int(size)
+          })
+
+        self._wrapCall(pk_xn, method, {'Details' : details_cb})
+        return result
+
+    def _wrapReposCall(self, pk_xn, method):
+        '''
+        Wraps a call which emits Finished, ErrorCode and RepoDetail
+        for information returns a list of dicts with 'id',
+        'description', 'enabled' keys
+        '''
+        result = []
+        repo_cb = lambda id, description, enabled: result.append
+        ({'id' : str(id),
+          'desc' : self._to_utf8(description),
+          'enabled' : enabled})
+        self._wrapCall(pk_xn, method, {'RepoDetail' : repo_cb})
+        return result
+
+
+    def SuggestDaemonQuit(self):
+        '''Ask the PackageKit daemon to shutdown.'''
+
+        try:
+            self.pk_control.SuggestDaemonQuit()
+        except (AttributeError, dbus.DBusException), e:
+            # not initialized, or daemon timed out
+            pass
+
+    def Resolve(self, filter, package):
+        '''
+        Resolve a package name to a PackageKit package_id filter and
+        package are directly passed to the PackageKit transaction
+        D-BUS method Resolve()
+
+        Return Dict with keys of (installed, id, short_description)
+        for all matches, where installed is a boolean and id and
+        short_description are strings.
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn, lambda : xn.Resolve(filter, package))
+
+
+    def GetDetails(self, package_id):
+        '''
+        Get details about a PackageKit package_id.
+
+        Return dict with keys (id, license, group, description,
+        upstream_url, size).
+        '''
+        xn = self._get_xn()
+        return self._wrapDetailsCall(xn, lambda : xn.GetDetails(package_id))
+
+    def SearchName(self, filter, name):
+        '''
+        Search a package by name.
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn, lambda : xn.SearchName(filter, name))
+
+    def SearchGroup(self, filter, group_id):
+        '''
+        Search for a group.
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn, lambda : xn.SearchGroup(filter, group_id))
+
+    def SearchDetails(self, filter, name):
+        '''
+        Search a packages details.
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn,
+                                     lambda : xn.SearchDetails(filter, name))
+
+    def SearchFile(self, filter, search):
+        '''
+        Search for a file.
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn,
+                                     lambda : xn.SearchFile(filter, search))
+
+    def InstallPackages(self, package_ids, progress_cb=None):
+        '''Install a list of package IDs.
+
+        progress_cb is a function taking arguments (status, percentage,
+        subpercentage, elapsed, remaining, allow_cancel). If it returns False,
+        the action is cancelled (if allow_cancel == True), otherwise it
+        continues.
+
+        On failure this throws a PackageKitError or a DBusException.
+        '''
+        self._doPackages(package_ids, progress_cb, 'install')
+
+    def UpdatePackages(self, package_ids, progress_cb=None):
+        '''UPdate a list of package IDs.
+
+        progress_cb is a function taking arguments (status, percentage,
+        subpercentage, elapsed, remaining, allow_cancel). If it returns False,
+        the action is cancelled (if allow_cancel == True), otherwise it
+        continues.
+
+        On failure this throws a PackageKitError or a DBusException.
+        '''
+        self._doPackages(package_ids, progress_cb, 'update')
+
+    def RemovePackages(self, package_ids, progress_cb=None, allow_deps=False,
+        auto_remove=True):
+        '''Remove a list of package IDs.
+
+        progress_cb is a function taking arguments (status, percentage,
+        subpercentage, elapsed, remaining, allow_cancel). If it returns False,
+        the action is cancelled (if allow_cancel == True), otherwise it
+        continues.
+
+        allow_deps and auto_remove are passed to the PackageKit function.
+
+        On failure this throws a PackageKitError or a DBusException.
+        '''
+        self._doPackages(package_ids, progress_cb, 'remove', allow_deps,
+            auto_remove)
+
+    def RefreshCache(self, force=False):
+        '''
+        Refresh the cache, i.e. download new metadata from a
+        remote URL so that package lists are up to date. This action
+        may take a few minutes and should be done when the session and
+        system are idle.
+        '''
+        xn = self._get_xn()
+        self._wrapBasicCall(xn, lambda : xn.RefreshCache(force))
+
+
+    def GetRepoList(self, filter=None):
+        '''
+        Returns the list of repositories used in the system
+
+        filter is a correct filter, e.g. None or 'installed;~devel'
+
+        '''
+        if (filter == None):
+            filter = 'none'
+        xn = self._get_xn()
+        return self._wrapReposCall(xn, lambda : xn.GetRepoList(filter))
+
+
+    def RepoEnable(self, repo_id, enabled):
+        '''
+        Enables the repository specified.
+
+        repo_id is a repository identifier, e.g. fedora-development-debuginfo
+
+        enabled true if enabled, false if disabled
+
+        '''
+        xn = self._get_xn()
+        self._wrapBasicCall(xn, lambda : xn.RepoEnable(repo_id, enabled))
+
+    def GetUpdates(self, filter=None):
+        '''
+        This method should return a list of packages that are installed and
+        are upgradable.
+
+        It should only return the newest update for each installed package.
+        '''
+        xn = self._get_xn()
+        if (filter == None):
+            filter = 'none'
+        return self._wrapPackageCall(xn, lambda : xn.GetUpdates(filter))
+
+    def GetPackages(self, filter=None):
+        '''
+        This method should return a total list of packages, limmited by the
+        filter used
+        '''
+        xn = self._get_xn()
+        if (filter == None):
+            filter = FILTER_NONE
+        return self._wrapPackageCall(xn, lambda : xn.GetPackages(filter))
+
+    def UpdateSystem(self):
+        '''
+        This method should return a list of packages that are
+        installed and are upgradable.
+
+        It should only return the newest update for each installed package.
+        '''
+        xn = self._get_xn()
+        self._wrapPackageCall(xn, lambda : xn.UpdateSystem())
+
+    def DownloadPackages(self,package_ids):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def GetDepends(self,filter,package_ids,recursive=False):
+        '''
+        Search for dependencies for packages
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn,
+                                     lambda : xn.GetDepends(filter,package_ids,recursive))
+
+    def GetFiles(self,package_ids):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def GetRepoList(self,filter):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def GetRequires(self,filter,package_ids,recursive=False):
+        '''
+        Search for requirements for packages
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn,
+                                     lambda : xn.GetRequires(filter,package_ids,recursive))
+
+    def GetUpdateDetail(self,package_ids):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def GetDistroUpgrades(self):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def InstallFiles(self,trusted,files):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def InstallSignatures(self.sig_type,key_id,package_id):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def RepoEnable(self,repo_id,enabled):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def RepoSetData(self,repo_id,parameter,value):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def Rollback(self,transaction_id):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def WhatProvides(self,provide_type,search):
+        '''
+        Search for packages that provide the supplied attributes
+        '''
+        xn = self._get_xn()
+        return self._wrapPackageCall(xn,
+                                     lambda : xn.WhatProvides(provide_type,search))
+
+    def SetLocale(self,code):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+    def AcceptEula(self,eula_id):
+        raise PackageKitError(ERROR_NOT_SUPPORTED)
+
+
+
+    #
+    # Internal helper functions
+    #
+
+    def _to_utf8(self, obj, errors='replace'):
+        '''convert 'unicode' to an encoded utf-8 byte string '''
+        if isinstance(obj, unicode):
+            obj = obj.encode('utf-8', errors)
+        return obj
+
+    def _wait(self):
+        '''Wait until an async PK operation finishes.'''
+        self.main_loop.run()
+
+    def _h_status(self, status):
+        self._status = status
+
+    def _h_allowcancel(self, allow):
+        self._allow_cancel = allow
+
+    def _h_error(self, enum, desc):
+        self._error_enum = enum
+
+    def _h_finished(self, status, code):
+        self.main_loop.quit()
+
+    def _h_progress(self, per, subper, el, rem):
+        def _cancel(xn):
+            try:
+                xn.Cancel()
+            except dbus.DBusException, e:
+                if e._dbus_error_name == 'org.freedesktop.PackageKit.Transaction.CannotCancel':
+                    pass
+                else:
+                    raise
+
+        ret = self._progress_cb(self._status, int(per),
+            int(subper), int(el), int(rem), self._allow_cancel)
+        if not ret:
+            # we get backend timeout exceptions more likely when we call this
+            # directly, so delay it a bit
+            gobject.timeout_add(10, _cancel, pk_xn)
+
+    def _auth(self):
+        policykit = self.bus.get_object(
+            'org.freedesktop.PolicyKit.AuthenticationAgent', '/',
+            'org.freedesktop.PolicyKit.AuthenticationAgent')
+        if(policykit == None):
+           print("Error: Could not get PolicyKit D-Bus Interface\n")
+        granted = policykit.ObtainAuthorization("org.freedesktop.packagekit.update-system",
+                                                (dbus.UInt32)(xid),
+                                                (dbus.UInt32)(os.getpid()))
+
+    def _doPackages(self, package_ids, progress_cb, action,
+        allow_deps=None, auto_remove=None):
+        '''Shared implementation of InstallPackages,UpdatePackages and RemovePackages.'''
+
+        self._status = None
+        self._allow_cancel = False
+
+        pk_xn = self._get_xn()
+        if progress_cb:
+            pk_xn.connect_to_signal('StatusChanged', self._h_status)
+            pk_xn.connect_to_signal('AllowCancel', self._h_allowcancel)
+            pk_xn.connect_to_signal('ProgressChanged', self._h_progress)
+            self._progress_cb = progress_cb
+        pk_xn.connect_to_signal('ErrorCode', self._h_error)
+        pk_xn.connect_to_signal('Finished', self._h_finished)
+        if action == "install":
+            pk_xn.InstallPackages(package_ids)
+        elif action == "remove":
+            pk_xn.RemovePackages(package_ids, allow_deps, auto_remove)
+        elif action == "update":
+            pk_xn.UpdatePackages(package_ids)
+        self._wait()
+        if self._error_enum:
+            raise PackageKitError(self._error_enum)
+        if self._finished_status != 'success':
+            raise PackageKitError('internal-error')
+
+    def _get_xn(self):
+        '''Create a new PackageKit Transaction object.'''
+
+        self._error_enum = None
+        self._finished_status = None
+        try:
+            tid = self.pk_control.GetTid()
+        except (AttributeError, dbus.DBusException), e:
+            if self.pk_control == None or (hasattr(e, '_dbus_error_name') and \
+                e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown'):
+                # first initialization (lazy) or timeout
+                self.pk_control = dbus.Interface(self.bus.get_object(
+                        'org.freedesktop.PackageKit',
+                        '/org/freedesktop/PackageKit',
+                    False), 'org.freedesktop.PackageKit')
+                tid = self.pk_control.GetTid()
+            else:
+                raise
+
+        return dbus.Interface(self.bus.get_object('org.freedesktop.PackageKit',
+            tid, False), 'org.freedesktop.PackageKit.Transaction')
+
+#### PolicyKit authentication borrowed wrapper ##
+class PermissionDeniedByPolicy(dbus.DBusException):
+    _dbus_error_name = 'org.freedesktop.PackageKit.PermissionDeniedByPolicy'
+
+
+def polkit_auth_wrapper(fn, *args, **kwargs):
+    '''Function call wrapper for PolicyKit authentication.
+
+    Call fn(*args, **kwargs). If it fails with a PermissionDeniedByPolicy
+    and the caller can authenticate to get the missing privilege, the PolicyKit
+    authentication agent is called, and the function call is attempted again.
+    '''
+    try:
+        return fn(*args, **kwargs)
+    except dbus.DBusException, e:
+        if e._dbus_error_name == PermissionDeniedByPolicy._dbus_error_name:
+            # last words in message are privilege and auth result
+            (priv, auth_result) = e.message.split()[-2:]
+            if auth_result.startswith('auth_'):
+                pk_auth = dbus.Interface(dbus.SessionBus().get_object(
+                    'org.freedesktop.PolicyKit.AuthenticationAgent', '/', False),
+                    'org.freedesktop.PolicyKit.AuthenticationAgent')
+                # TODO: provide xid
+                res = pk_auth.ObtainAuthorization(priv, dbus.UInt32(0),
+                    dbus.UInt32(os.getpid()), timeout=300)
+                if res:
+                    return fn(*args, **kwargs)
+            raise PermissionDeniedByPolicy(priv + ' ' + auth_result)
+        else:
+            raise
+
+
+if __name__ == '__main__':
+    pass
diff --git a/python/wrapper-test.py b/python/wrapper-test.py
new file mode 100755
index 0000000..63cd154
--- /dev/null
+++ b/python/wrapper-test.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# 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.
+
+# Copyright (C) 2008
+#    Tim Lauridsen <timlau at fedoraproject.org>
+
+import sys
+from packagekit.client import PackageKitClient
+from packagekit.enums import *
+
+if __name__ == '__main__':
+    pk = PackageKitClient()
+
+    #print '---- RefreshCache() -----'''
+    #print pk.RefreshCache()
+
+    print '---- Resolve() -----'
+    pkg = pk.Resolve(FILTER_NONE, ['yum'])
+    print pkg[0]
+
+    print '---- GetPackages() ----'
+    packages = pk.GetPackages(FILTER_INSTALLED)
+    i = 0
+    for pkg in packages:
+        i += 1
+        if i == 20:
+            break
+        (name,ver,arch,repo) = tuple(pkg['id'].split(";"))
+        p =  "%s-%s.%s" % (name,ver,arch)
+        print "%-40s : %s" % (p,pkg['summary'])
+        details = pk.GetDetails([pkg['id']])
+        print 79 *"-"
+        print details[0]['detail']
+
+    print '---- SearchFiles() ----'
+    print pk.SearchFile(FILTER_INSTALLED,"/usr/bin/yum")
+
+    print '---- GetUpdates() ----'
+    print pk.GetUpdates(FILTER_INSTALLED)
+
+    print '---- SearchName() -----'
+    print pk.SearchName(FILTER_NOT_INSTALLED, 'coreutils')
+    print pk.SearchName(FILTER_INSTALLED, 'coreutils')
+
+    sys.exit(0)
+
+    def cb(status, pc, spc, el, rem, c):
+        print 'install pkg: %s, %i%%, cancel allowed: %s' % (status, pc, str(c))
+        return True
+        #return pc < 12
+
+    print '---- UpdateSystem() ----'
+    print pk.UpdateSystem()
+
+    print '---- InstallPackages() -----'
+    pk.InstallPackages(['pmount;0.9.17-2;i386;Ubuntu', 'quilt;0.46-6;all;Ubuntu'], cb)
+
+
+    print '---- RemovePackages() -----'
+    pk.RemovePackages(['pmount;0.9.17-2;i386;Ubuntu', 'quilt;0.46-6;all;Ubuntu'], cb)
+
+
+    pk.SuggestDaemonQuit()
+
commit 96c5f935265c86643754b357095320f15d0ce705
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 11:28:18 2008 +0100

    bugfix, abi: Add GError parameters to all the public functions in PkControl that can fail

diff --git a/client/pk-console.c b/client/pk-console.c
index af580b2..cac0f08 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1409,7 +1409,7 @@ main (int argc, char *argv[])
 
 	/* we need the roles early, as we only show the user only what they can do */
 	control = pk_control_new ();
-	roles = pk_control_get_actions (control);
+	roles = pk_control_get_actions (control, NULL);
 	summary = pk_console_get_summary (roles);
 
 	context = g_option_context_new ("PackageKit Console Program");
@@ -1693,7 +1693,7 @@ main (int argc, char *argv[])
 		ret = TRUE;
 
 	} else if (strcmp (mode, "get-filters") == 0) {
-		filters = pk_control_get_filters (control);
+		filters = pk_control_get_filters (control, NULL);
 		text = pk_filter_bitfield_to_text (filters);
 		g_strdelimit (text, ";", '\n');
 		g_print ("%s\n", text);
@@ -1703,7 +1703,7 @@ main (int argc, char *argv[])
 		ret = TRUE;
 
 	} else if (strcmp (mode, "get-groups") == 0) {
-		groups = pk_control_get_groups (control);
+		groups = pk_control_get_groups (control, NULL);
 		text = pk_group_bitfield_to_text (groups);
 		g_strdelimit (text, ";", '\n');
 		g_print ("%s\n", text);
diff --git a/client/pk-generate-pack-main.c b/client/pk-generate-pack-main.c
index 98582f7..9655dc6 100644
--- a/client/pk-generate-pack-main.c
+++ b/client/pk-generate-pack-main.c
@@ -94,7 +94,7 @@ main (int argc, char *argv[])
 
 	/* are we dumb and can't check for depends? */
 	control = pk_control_new ();
-	roles = pk_control_get_actions (control);
+	roles = pk_control_get_actions (control, NULL);
 	if (!pk_bitfield_contain (roles, PK_ROLE_ENUM_GET_DEPENDS)) {
 		g_print ("Please use a backend that supports GetDepends!\n");
 		goto out;
diff --git a/libpackagekit/pk-control.c b/libpackagekit/pk-control.c
index 7d31997..f717590 100644
--- a/libpackagekit/pk-control.c
+++ b/libpackagekit/pk-control.c
@@ -94,9 +94,8 @@ GQuark
 pk_control_error_quark (void)
 {
 	static GQuark quark = 0;
-	if (!quark) {
+	if (!quark)
 		quark = g_quark_from_static_string ("pk_control_error");
-	}
 	return quark;
 }
 
@@ -141,56 +140,39 @@ out:
 }
 
 /**
- * pk_control_error_fixup:
- * @error: a %GError
- **/
-static gboolean
-pk_control_error_fixup (GError **error)
-{
-	if (error != NULL && *error != NULL) {
-		/* get some proper debugging */
-		if ((*error)->domain == DBUS_GERROR &&
-		    (*error)->code == DBUS_GERROR_REMOTE_EXCEPTION) {
-			/* use one of our local codes */
-			egg_debug ("fixing up code from %i", (*error)->code);
-			(*error)->code = PK_CONTROL_ERROR_FAILED;
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-/**
  * pk_control_get_actions:
  * @control: a valid #PkControl instance
+ * @error: a %GError to put the error code and message in, or %NULL
  *
  * Actions are roles that the daemon can do with the current backend
  *
  * Return value: an enumerated list of the actions the backend supports
  **/
 PkBitfield
-pk_control_get_actions (PkControl *control)
+pk_control_get_actions (PkControl *control, GError **error)
 {
 	gboolean ret;
-	GError *error = NULL;
+	GError *error_local = NULL;
 	gchar *actions;
 	PkBitfield roles_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* check to see if we have a valid proxy */
 	if (control->priv->proxy == NULL) {
 		egg_warning ("No proxy for manager");
 		goto out;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetActions", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetActions", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &actions,
 				 G_TYPE_INVALID);
 	if (!ret) {
 		/* abort as the DBUS method failed */
-		egg_warning ("GetActions failed :%s", error->message);
-		g_error_free (error);
+		egg_warning ("GetActions failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -206,33 +188,36 @@ out:
  * @control: a valid #PkControl instance
  * @proxy_http: a HTTP proxy string such as "username:password at server.lan:8080"
  * @proxy_ftp: a FTP proxy string such as "server.lan:8080"
+ * @error: a %GError to put the error code and message in, or %NULL
  *
  * Set a proxy on the PK daemon
  *
  * Return value: if we set the proxy successfully
  **/
 gboolean
-pk_control_set_proxy (PkControl *control, const gchar *proxy_http, const gchar *proxy_ftp)
+pk_control_set_proxy (PkControl *control, const gchar *proxy_http, const gchar *proxy_ftp, GError **error)
 {
 	gboolean ret = FALSE;
-	GError *error = NULL;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* check to see if we have a valid proxy */
 	if (control->priv->proxy == NULL) {
 		egg_warning ("No proxy for manager");
 		goto out;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "SetProxy", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "SetProxy", &error_local,
 				 G_TYPE_STRING, proxy_http,
 				 G_TYPE_STRING, proxy_ftp,
 				 G_TYPE_INVALID,
 				 G_TYPE_INVALID);
 	if (!ret) {
 		/* abort as the DBUS method failed */
-		egg_warning ("SetProxy failed :%s", error->message);
-		g_error_free (error);
+		egg_warning ("SetProxy failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 	}
 out:
 	return ret;
@@ -241,6 +226,7 @@ out:
 /**
  * pk_control_get_groups:
  * @control: a valid #PkControl instance
+ * @error: a %GError to put the error code and message in, or %NULL
  *
  * The group list is enumerated so it can be localised and have deep
  * integration with desktops.
@@ -249,28 +235,30 @@ out:
  * Return value: an enumerated list of the groups the backend supports
  **/
 PkBitfield
-pk_control_get_groups (PkControl *control)
+pk_control_get_groups (PkControl *control, GError **error)
 {
 	gboolean ret;
-	GError *error = NULL;
+	GError *error_local = NULL;
 	gchar *groups;
 	PkBitfield groups_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_GROUP_ENUM_UNKNOWN);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* check to see if we have a valid proxy */
 	if (control->priv->proxy == NULL) {
 		egg_warning ("No proxy for manager");
 		goto out;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetGroups", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetGroups", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &groups,
 				 G_TYPE_INVALID);
 	if (!ret) {
 		/* abort as the DBUS method failed */
-		egg_warning ("GetGroups failed :%s", error->message);
-		g_error_free (error);
+		egg_warning ("GetGroups failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -284,32 +272,35 @@ out:
 /**
  * pk_control_get_network_state:
  * @control: a valid #PkControl instance
+ * @error: a %GError to put the error code and message in, or %NULL
  *
  * Return value: an enumerated network state
  **/
 PkNetworkEnum
-pk_control_get_network_state (PkControl *control)
+pk_control_get_network_state (PkControl *control, GError **error)
 {
 	gboolean ret;
-	GError *error = NULL;
+	GError *error_local = NULL;
 	gchar *network_state;
 	PkNetworkEnum network_state_enum = PK_NETWORK_ENUM_UNKNOWN;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_NETWORK_ENUM_UNKNOWN);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* check to see if we have a valid proxy */
 	if (control->priv->proxy == NULL) {
 		egg_warning ("No proxy for manager");
 		goto out;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetNetworkState", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetNetworkState", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &network_state,
 				 G_TYPE_INVALID);
 	if (!ret) {
 		/* abort as the DBUS method failed */
-		egg_warning ("GetNetworkState failed :%s", error->message);
-		g_error_free (error);
+		egg_warning ("GetNetworkState failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -323,34 +314,37 @@ out:
 /**
  * pk_control_get_filters:
  * @control: a valid #PkControl instance
+ * @error: a %GError to put the error code and message in, or %NULL
  *
  * Filters are how the backend can specify what type of package is returned.
  *
  * Return value: an enumerated list of the filters the backend supports
  **/
 PkBitfield
-pk_control_get_filters (PkControl *control)
+pk_control_get_filters (PkControl *control, GError **error)
 {
 	gboolean ret;
-	GError *error = NULL;
+	GError *error_local = NULL;
 	gchar *filters;
 	PkBitfield filters_enum = 0;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), PK_FILTER_ENUM_UNKNOWN);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* check to see if we have a valid proxy */
 	if (control->priv->proxy == NULL) {
 		egg_warning ("No proxy for manager");
 		goto out;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetFilters", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetFilters", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &filters,
 				 G_TYPE_INVALID);
 	if (!ret) {
 		/* abort as the DBUS method failed */
-		egg_warning ("GetFilters failed :%s", error->message);
-		g_error_free (error);
+		egg_warning ("GetFilters failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -379,6 +373,7 @@ pk_control_get_backend_detail (PkControl *control, gchar **name, gchar **author,
 	gboolean ret;
 	gchar *tname;
 	gchar *tauthor;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), FALSE);
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -388,13 +383,15 @@ pk_control_get_backend_detail (PkControl *control, gchar **name, gchar **author,
 		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, "No proxy for manager");
 		return FALSE;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetBackendDetail", error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetBackendDetail", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &tname,
 				 G_TYPE_STRING, &tauthor,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
 	if (!ret) {
-		pk_control_error_fixup (error);
+		egg_warning ("GetFilters failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		return FALSE;
 	}
 
@@ -430,6 +427,7 @@ pk_control_get_time_since_action (PkControl *control, PkRoleEnum role, guint *se
 {
 	gboolean ret;
 	const gchar *role_text;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), FALSE);
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -441,17 +439,22 @@ pk_control_get_time_since_action (PkControl *control, PkRoleEnum role, guint *se
 		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, "No proxy for manager");
 		return FALSE;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetTimeSinceAction", error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetTimeSinceAction", &error_local,
 				 G_TYPE_STRING, role_text,
 				 G_TYPE_INVALID,
 				 G_TYPE_UINT, seconds,
 				 G_TYPE_INVALID);
-	pk_control_error_fixup (error);
+	if (!ret) {
+		egg_warning ("GetTimeSinceAction failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
+	}
 	return ret;
 }
 
 /**
  * pk_control_set_locale:
+ * @error: a %GError to put the error code and message in, or %NULL
  **/
 static gboolean
 pk_control_set_locale (PkControl *control, const gchar *tid, GError **error)
@@ -459,7 +462,9 @@ pk_control_set_locale (PkControl *control, const gchar *tid, GError **error)
 	PkClient *client;
 	gboolean ret;
 	gchar *locale; /* does not need to be freed */
+	GError *error_local = NULL;
 
+	g_return_val_if_fail (PK_IS_CONTROL (control), FALSE);
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	client = pk_client_new ();
@@ -473,7 +478,9 @@ pk_control_set_locale (PkControl *control, const gchar *tid, GError **error)
 	locale = setlocale (LC_ALL, NULL);
 	ret = pk_client_set_locale (client, locale, error);
 	if (!ret) {
-		egg_warning ("failed to set the locale: %s", (*error)->message);
+		egg_warning ("SetLocale failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 out:
@@ -496,6 +503,7 @@ pk_control_allocate_transaction_id (PkControl *control, gchar **tid, GError **er
 {
 	gboolean ret;
 	gchar *tid_local = NULL;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), FALSE);
 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -505,12 +513,14 @@ pk_control_allocate_transaction_id (PkControl *control, gchar **tid, GError **er
 		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, "No proxy for GetTid");
 		return FALSE;
 	}
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetTid", error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetTid", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRING, &tid_local,
 				 G_TYPE_INVALID);
 	if (!ret) {
-		pk_control_error_fixup (error);
+		egg_warning ("GetTid failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -524,7 +534,9 @@ pk_control_allocate_transaction_id (PkControl *control, gchar **tid, GError **er
 	/* automatically set the locale */
 	ret = pk_control_set_locale (control, tid_local, error);
 	if (!ret) {
-		pk_control_error_fixup (error);
+		egg_warning ("GetTid failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 		goto out;
 	}
 
@@ -566,12 +578,13 @@ pk_control_transaction_list_print (PkControl *control)
  * Not normally required, but force a refresh
  **/
 static gboolean
-pk_control_transaction_list_refresh (PkControl *control)
+pk_control_transaction_list_refresh (PkControl *control, GError **error)
 {
 	gboolean ret;
-	GError *error;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (PK_IS_CONTROL (control), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
 	/* clear old data */
 	if (control->priv->array != NULL) {
@@ -579,21 +592,18 @@ pk_control_transaction_list_refresh (PkControl *control)
 		control->priv->array = NULL;
 	}
 	error = NULL;
-	ret = dbus_g_proxy_call (control->priv->proxy, "GetTransactionList", &error,
+	ret = dbus_g_proxy_call (control->priv->proxy, "GetTransactionList", &error_local,
 				 G_TYPE_INVALID,
 				 G_TYPE_STRV, &control->priv->array,
 				 G_TYPE_INVALID);
-	if (error != NULL) {
-		egg_warning ("ERROR: %s", error->message);
-		g_error_free (error);
-	}
-	if (ret == FALSE) {
-		/* abort as the DBUS method failed */
-		egg_warning ("GetTransactionList failed!");
+	if (!ret) {
 		control->priv->array = NULL;
-		return FALSE;
+		egg_warning ("GetTransactionList failed :%s", error_local->message);
+		pk_control_error_set (error, PK_CONTROL_ERROR_FAILED, error_local->message);
+		g_error_free (error_local);
 	}
-	return TRUE;
+
+	return ret;
 }
 
 /**
@@ -615,9 +625,8 @@ pk_control_transaction_list_changed_cb (DBusGProxy *proxy, gchar **array, PkCont
 	g_return_if_fail (PK_IS_CONTROL (control));
 
 	/* clear old data */
-	if (control->priv->array != NULL) {
+	if (control->priv->array != NULL)
 		g_strfreev (control->priv->array);
-	}
 	control->priv->array = g_strdupv (array);
 	egg_debug ("emit transaction-list-changed");
 	g_signal_emit (control , signals [PK_CONTROL_LIST_CHANGED], 0);
@@ -630,9 +639,8 @@ static void
 pk_control_connection_changed_cb (PkConnection *pconnection, gboolean connected, PkControl *control)
 {
 	/* force a refresh so we have valid data*/
-	if (connected) {
-		pk_control_transaction_list_refresh (control);
-	}
+	if (connected)
+		pk_control_transaction_list_refresh (control, NULL);
 }
 
 /**
@@ -797,6 +805,7 @@ pk_control_class_init (PkControlClass *klass)
 static void
 pk_control_init (PkControl *control)
 {
+	gboolean ret;
 	GError *error = NULL;
 
 	control->priv = PK_CONTROL_GET_PRIVATE (control);
@@ -852,7 +861,11 @@ pk_control_init (PkControl *control)
 				     G_CALLBACK (pk_control_locked_cb), control, NULL);
 
 	/* force a refresh so we have valid data*/
-	pk_control_transaction_list_refresh (control);
+	ret = pk_control_transaction_list_refresh (control, &error);
+	if (!ret) {
+		egg_warning ("failed to get list: %s", error->message);
+		g_error_free (error);
+	}
 }
 
 /**
diff --git a/libpackagekit/pk-control.h b/libpackagekit/pk-control.h
index 4e90be6..1d46e41 100644
--- a/libpackagekit/pk-control.h
+++ b/libpackagekit/pk-control.h
@@ -91,11 +91,16 @@ gboolean	 pk_control_allocate_transaction_id	(PkControl	*control,
 							 GError		**error);
 gboolean	 pk_control_set_proxy			(PkControl	*control,
 							 const gchar	*proxy_http,
-							 const gchar	*proxy_ftp);
-PkBitfield	 pk_control_get_actions			(PkControl	*control);
-PkBitfield pk_control_get_filters			(PkControl	*control);
-PkBitfield	 pk_control_get_groups			(PkControl	*control);
-PkNetworkEnum	 pk_control_get_network_state		(PkControl	*control);
+							 const gchar	*proxy_ftp,
+							 GError		**error);
+PkBitfield	 pk_control_get_actions			(PkControl	*control,
+							 GError		**error);
+PkBitfield	 pk_control_get_filters			(PkControl	*control,
+							 GError		**error);
+PkBitfield	 pk_control_get_groups			(PkControl	*control,
+							 GError		**error);
+PkNetworkEnum	 pk_control_get_network_state		(PkControl	*control,
+							 GError		**error);
 gboolean	 pk_control_get_backend_detail		(PkControl	*control,
 							 gchar		**name,
 							 gchar		**author,
commit 14f993a2a8d1e65dbafd4796ae70b55d46ab5477
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 11:50:38 2008 +0200

    urpmi: refresh-cache method added in dispatched backend

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index abaf563..be42b9a 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -92,6 +92,10 @@ while(<STDIN>) {
   elsif($command eq "search-name") {
     search_name($urpm, \@args);
   }
+  elsif($command eq "refresh-cache") {
+    refresh_cache($urpm);
+    urpm::media::configure($urpm);
+  }
 }
 
 
@@ -355,6 +359,29 @@ sub search_name {
   _finished();
 }
 
+sub refresh_cache {
+
+  my ($urpm) = @_;
+
+  $urpm->{fatal} = sub { 
+    pk_print_error(PK_ERROR_ENUM_TRANSACTION_ERROR, $_[1]."\n"); 
+    die;
+  };
+  my $urpmi_lock = urpm::lock::urpmi_db($urpm, 'exclusive', wait => 0);
+  urpm::media::read_config($urpm);
+
+  my @entries = map { $_->{name} } @{$urpm->{media}};
+  @entries == 0 and pk_print_error(PK_ERROR_ENUM_TRANSACTION_ERROR, "nothing to update (use urpmi.addmedia to add a media)\n");
+
+  my %options = ( all => 1 );
+  
+  eval {
+    my $ok = urpm::media::update_media($urpm, %options, quiet => 0);
+  };
+  _finished();
+
+}
+
 sub _finished {
   pk_print_status(PK_STATUS_ENUM_FINISHED);
 }
commit 5189c768cacf2165e98e0e4432ed99c598edd8bc
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 11:36:26 2008 +0200

    urpmi: urpmi-dispatched-backend update

diff --git a/backends/urpmi/helpers/urpmi-dispatched-backend.pl b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
index 65442d7..abaf563 100755
--- a/backends/urpmi/helpers/urpmi-dispatched-backend.pl
+++ b/backends/urpmi/helpers/urpmi-dispatched-backend.pl
@@ -65,32 +65,32 @@ while(<STDIN>) {
   chomp($_);
   my @args = split (/ /, $_);
   my $command = shift(@args);
-  if($command eq "search-name") {
-    search_name($urpm, @args);
-  }
-  elsif($command eq "get-depends") {
-    get_depends($urpm, @args);
+  if($command eq "get-depends") {
+    get_depends($urpm, \@args);
   }
   elsif($command eq "get-details") {
-    get_details($urpm, @args);
+    get_details($urpm, \@args);
   }
   elsif($command eq "get-files") {
-    get_files($urpm, @args);
+    get_files($urpm, \@args);
   }
   elsif($command eq "get-packages") {
-    get_packages($urpm, @args);
+    get_packages($urpm, \@args);
   }
   elsif($command eq "get-requires") {
-    get_requires($urpm, @args);
+    get_requires($urpm, \@args);
   }
   elsif($command eq "get-update-detail") {
-    get_update_detail($urpm, @args);
+    get_update_detail($urpm, \@args);
   }
   elsif($command eq "get-updates") {
-    get_updates($urpm, @args);
+    get_updates($urpm, \@args);
   }
   elsif($command eq "install-packages") {
-    install_packages($urpm, @args);
+    install_packages($urpm, \@args);
+  }
+  elsif($command eq "search-name") {
+    search_name($urpm, \@args);
   }
 }
 
@@ -98,11 +98,13 @@ while(<STDIN>) {
 
 sub get_depends {
 
-  my ($urpm, $filters, $packageids, $recursive_option) = @_;
+  my ($urpm, $args) = @_;
   
-  my @filterstab = split(/;/, $filters);
-  my @packageidstab = split(/\|/, $packageids);
-  $recursive_option = 1;
+  my @filterstab = split(/;/, @{$args}[0]);
+  shift @{$args};
+  my $recursive_text = pop @{$args};
+  my $recursive_option = $recursive_text eq "yes" ? 1 : 0;
+  my @packageidstab = @{$args};
   
   pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
   
@@ -152,9 +154,9 @@ sub get_depends {
 
 sub get_details {
 
-  my ($urpm, $packageids) = @_;
+  my ($urpm, $args) = @_;
   
-  my @packageidstab = split(/\|/, $packageids);
+  my @packageidstab = @{$args};
   pk_print_status(PK_STATUS_ENUM_QUERY);
 
   foreach (@packageidstab) {
@@ -165,9 +167,9 @@ sub get_details {
 
 sub get_files {
   
-  my ($urpm, $packageids) = @_;
+  my ($urpm, $args) = @_;
   
-  my @packageidstab = split(/\|/, $packageids);
+  my @packageidstab = @{$args};
   pk_print_status(PK_STATUS_ENUM_QUERY);
   
   foreach (@packageidstab) {
@@ -178,8 +180,8 @@ sub get_files {
 
 sub get_packages {
 
-  my ($urpm, $filters) = @_;
-  my @filterstab = split(/;/, $filters);
+  my ($urpm, $args) = @_;
+  my @filterstab = split(/;/, @{$args}[0]);
   
   pk_print_status(PK_STATUS_ENUM_QUERY);
   
@@ -211,11 +213,13 @@ sub get_packages {
 
 sub get_requires {
   
-  my ($urpm, $filters, $packageids, $recursive_option) = @_;
+  my ($urpm, $args) = @_;
   
-  my @filterstab = split(/;/, $filters);
-  my @packageidstab = split(/\|/, $packageids);
-  my $recursive = $recursive_option eq "yes" ? 1 : 0;
+  my @filterstab = split(/;/, @{$args}[0]);
+  shift @{$args};
+  my $recursive_text = pop @{$args};
+  my $recursive_option = $recursive_text eq "yes" ? 1 : 0;
+  my @packageidstab = @{$args};
   
   my @pkgnames;
   foreach (@packageidstab) {
@@ -224,7 +228,7 @@ sub get_requires {
   }
   
   pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
-  my @requires = perform_requires_search($urpm, \@pkgnames, $recursive);
+  my @requires = perform_requires_search($urpm, \@pkgnames, $recursive_option);
   
   foreach(@requires) {
     if(filter($_, \@filterstab, { FILTER_GUI => 1, FILTER_DEVELOPMENT => 1 })) {
@@ -241,10 +245,10 @@ sub get_requires {
 
 sub get_update_detail {
 
-  my ($urpm, $packageids) = @_;
+  my ($urpm, $args) = @_;
   
   pk_print_status(PK_STATUS_ENUM_QUERY);
-  my @packageidstab = split(/\|/, $packageids);
+  my @packageidstab = @{$args};
   
   foreach (@packageidstab) {
     _print_package_update_details($urpm, $_);
@@ -254,9 +258,10 @@ sub get_update_detail {
 
 sub get_updates {
 
-  my ($urpm, $filters) = @_;
+  my ($urpm, $args) = @_;
   # Fix me
   # Filter are to be implemented.
+  my $filters = @{$args}[0];
   
   pk_print_status(PK_STATUS_ENUM_DEP_RESOLVE);
 
@@ -283,9 +288,9 @@ sub get_updates {
 
 sub install_packages {
 
-  my ($urpm, $packageids) = @_;
+  my ($urpm, $args) = @_;
 
-  my @packageidstab = split(/\|/, $packageids);
+  my @packageidstab = @{$args};
   
   my @names;
   foreach(@packageidstab) {
@@ -307,11 +312,12 @@ sub install_packages {
 
 sub search_name {
 
-  my ($urpm, $filters, $search_term) = @_;
+  my ($urpm, $args) = @_;
   
   pk_print_status(PK_STATUS_ENUM_QUERY);
 
-  my @filterstab = split(/;/, $filters);
+  my @filterstab = split(/;/, @{$args}[0]);
+  my $search_term = @{$args}[1];
   
   my $basename_option = FILTER_BASENAME;
   $basename_option = grep(/$basename_option/, @filterstab);
commit a24369951ba45dfff07df4149d866103bb70cbde
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 10:58:45 2008 +0200

    urpmi: resolve: multiple pkg args are now treated as separated by spaces

diff --git a/backends/urpmi/helpers/resolve.pl b/backends/urpmi/helpers/resolve.pl
index 1d4056a..2248e53 100755
--- a/backends/urpmi/helpers/resolve.pl
+++ b/backends/urpmi/helpers/resolve.pl
@@ -28,10 +28,11 @@ use urpmi_backend::filters;
 use perl_packagekit::enums;
 use perl_packagekit::prints;
 
-# Two arguments (filter and package name)
-$#ARGV == 1 or exit 1;
+# At least two arguments (filter and packages name)
+$#ARGV > 0 or exit 1;
 my @filters = split(/;/, $ARGV[0]);
-my @patterns = split(/\|/, $ARGV[1]);
+shift @ARGV;
+my @patterns = @ARGV;
 
 my $urpm = urpm->new_parse_cmdline;
 urpm::media::configure($urpm);
commit 720be2e29c22658331dc4c3173601f38d754ff5f
Author: Aurelien Lefebvre <alefebvre at mandriva.com>
Date:   Tue Sep 16 10:36:34 2008 +0200

    urpmi: get-requires: multiple pkg args are now treated as separated by spaces

diff --git a/backends/urpmi/helpers/get-requires.pl b/backends/urpmi/helpers/get-requires.pl
index 063c8ef..a49e198 100755
--- a/backends/urpmi/helpers/get-requires.pl
+++ b/backends/urpmi/helpers/get-requires.pl
@@ -29,17 +29,19 @@ use urpmi_backend::filters;
 use perl_packagekit::enums;
 use perl_packagekit::prints;
 
-# 3 arguments
+# At least 3 arguments
 # (filter, package ids, and recursive option)
-$#ARGV == 2 or exit 1;
+$#ARGV > 1 or exit 1;
 
 my @filters = split(/;/, $ARGV[0]);
-my $recursive_option = $ARGV[2] eq "yes" ? 1 : 0;
+shift @ARGV;
+my $recursive_text = pop @ARGV;
+my $recursive_option = $recursive_text eq "yes" ? 1 : 0;
 
 my $urpm = urpm->new_parse_cmdline;
 urpm::media::configure($urpm);
 
-my @pkgids = split(/\|/, $ARGV[1]);
+my @pkgids = @ARGV;
 my @pkgnames;
 foreach (@pkgids) {
   my $pkg = get_package_by_package_id($urpm, $_);
commit bbd53f86898f424e75a010444597ccbf97ca5fd8
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 09:27:27 2008 +0100

    trivial: remove the scourge of trailing whitespace

diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
index d252061..0f08f94 100644
--- a/backends/zypp/zypp-events.h
+++ b/backends/zypp/zypp-events.h
@@ -386,7 +386,7 @@ struct DigestReportReceiver : public zypp::callback::ReceiveReport<zypp::DigestR
 				file.c_str (), requested.c_str (), found.c_str ());
 		gboolean ok = zypp_signature_required(_backend, file);
 
-		return ok;	
+		return ok;
 	}
 };
 
diff --git a/backends/zypp/zypp-utils.h b/backends/zypp/zypp-utils.h
index 280286e..d60b44b 100644
--- a/backends/zypp/zypp-utils.h
+++ b/backends/zypp/zypp-utils.h
@@ -88,10 +88,10 @@ gboolean zypp_is_changeable_media (const zypp::Url &url);
  */
 zypp::ResPool zypp_build_pool (gboolean include_local);
 
-/**  
-* check and warns the user that a repository may be outdated  
-*/  
-void warn_outdated_repos(PkBackend *backend, const zypp::ResPool & pool);  
+/**
+* check and warns the user that a repository may be outdated
+*/
+void warn_outdated_repos(PkBackend *backend, const zypp::ResPool & pool);
 
 /**
  * Build and return a ResPool that contains only the local resolvables.
@@ -140,7 +140,7 @@ zypp::sat::Solvable zypp_get_package_by_id (const gchar *package_id);
 gchar * zypp_build_package_id_from_resolvable (zypp::sat::Solvable resolvable);
 
 /**
-  * Get the RepoInfo 
+  * Get the RepoInfo
   */
 zypp::RepoInfo
 zypp_get_Repository (PkBackend *backend, const gchar *alias);
diff --git a/docs/html/pk-authors.html b/docs/html/pk-authors.html
index 4e59527..cd4a134 100644
--- a/docs/html/pk-authors.html
+++ b/docs/html/pk-authors.html
@@ -178,9 +178,9 @@
  <td>
   <h2>S.Çağlar Onur</h2>
   <p>
-   Çağlar has 4 years of experience developing open source software. He has a B.S. in Computer Engineering 
+   Çağlar has 4 years of experience developing open source software. He has a B.S. in Computer Engineering
    and he is working as a full-time developer of <a href="http://www.pardus.org.tr/eng/">Pardus Linux</a> since 2003.
-   He is also the Release Manager of "Pardus 2007" and <a href="http://www.ohloh.net/accounts/9088">contributes</a> 
+   He is also the Release Manager of "Pardus 2007" and <a href="http://www.ohloh.net/accounts/9088">contributes</a>
    some FLOSS projects as a part of his daily job.
   </p>
   <p>
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 9462747..29268c9 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -34,9 +34,9 @@ easier to install.
   <li>
   Ubuntu: Ubuntu 8.04 Hardy Heron ships an obsolete version (0.1.6) of PackageKit by default.
   Intrepid, the upcoming Ubuntu release, features 0.2.4, but we plan to ship 0.3.2.<br/>
-  You can find the latest version of the 0.3 series for Hardy and Intrepid in this 
+  You can find the latest version of the 0.3 series for Hardy and Intrepid in this
   <a href="https://edge.launchpad.net/~packagekit/+archive">Personal Package Archive</a>.
-  <a href="https://help.ubuntu.com/8.04/add-applications/C/extra-repositories-adding.html">Add</a> 
+  <a href="https://help.ubuntu.com/8.04/add-applications/C/extra-repositories-adding.html">Add</a>
   the repository and <a href="https://help.ubuntu.com/8.04/add-applications/C/advanced.html">
   install</a> the packages <code>packagekit</code> and <code>packagekit-gnome</code>.
   </li>
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 2d59e6c..84f1337 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -201,7 +201,7 @@ gboolean	 pk_client_download_packages		(PkClient	*client,
 							 gchar		**package_ids,
 							 const gchar	*directory,
 							 GError		**error)
-							 G_GNUC_WARN_UNUSED_RESULT;	
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_updates			(PkClient	*client,
 							 PkBitfield filters,
 							 GError		**error)
diff --git a/src/pk-network-nm.h b/src/pk-network-nm.h
index 0b0e5ec..c79d075 100644
--- a/src/pk-network-nm.h
+++ b/src/pk-network-nm.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
 #define PK_IS_NETWORK_NM_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_NM))
 #define PK_NETWORK_NM_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_NM, PkNetworkNmClass))
 #define PK_NETWORK_NM_ERROR		(pk_network_nm_error_quark ())
-#define PK_NETWORK_NM_TYPE_ERROR	(pk_network_nm_error_get_type ()) 
+#define PK_NETWORK_NM_TYPE_ERROR	(pk_network_nm_error_get_type ())
 
 typedef struct _PkNetworkNmPrivate	PkNetworkNmPrivate;
 typedef struct _PkNetworkNm		PkNetworkNm;
diff --git a/src/pk-network-unix.h b/src/pk-network-unix.h
index 2c4ce26..b88b1ba 100644
--- a/src/pk-network-unix.h
+++ b/src/pk-network-unix.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
 #define PK_IS_NETWORK_UNIX_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK_UNIX))
 #define PK_NETWORK_UNIX_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK_UNIX, PkNetworkUnixClass))
 #define PK_NETWORK_UNIX_ERROR		(pk_network_unix_error_quark ())
-#define PK_NETWORK_UNIX_TYPE_ERROR	(pk_network_unix_error_get_type ()) 
+#define PK_NETWORK_UNIX_TYPE_ERROR	(pk_network_unix_error_get_type ())
 
 typedef struct _PkNetworkUnixPrivate	PkNetworkUnixPrivate;
 typedef struct _PkNetworkUnix		PkNetworkUnix;
diff --git a/src/pk-network.h b/src/pk-network.h
index df3f2f5..d9f7d4f 100644
--- a/src/pk-network.h
+++ b/src/pk-network.h
@@ -41,7 +41,7 @@ G_BEGIN_DECLS
 #define PK_IS_NETWORK_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_NETWORK))
 #define PK_NETWORK_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_NETWORK, PkNetworkClass))
 #define PK_NETWORK_ERROR	(pk_network_error_quark ())
-#define PK_NETWORK_TYPE_ERROR	(pk_network_error_get_type ()) 
+#define PK_NETWORK_TYPE_ERROR	(pk_network_error_get_type ())
 
 typedef struct _PkNetworkPrivate	PkNetworkPrivate;
 typedef struct _PkNetwork		PkNetwork;
diff --git a/src/pk-spawn.h b/src/pk-spawn.h
index 14741e5..3c181dd 100644
--- a/src/pk-spawn.h
+++ b/src/pk-spawn.h
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
 #define PK_IS_SPAWN_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_SPAWN))
 #define PK_SPAWN_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_SPAWN, PkSpawnClass))
 #define PK_SPAWN_ERROR		(pk_spawn_error_quark ())
-#define PK_SPAWN_TYPE_ERROR	(pk_spawn_error_get_type ()) 
+#define PK_SPAWN_TYPE_ERROR	(pk_spawn_error_get_type ())
 
 typedef struct PkSpawnPrivate PkSpawnPrivate;
 
diff --git a/src/pk-transaction-list.h b/src/pk-transaction-list.h
index 6aa90fc..4e9bf32 100644
--- a/src/pk-transaction-list.h
+++ b/src/pk-transaction-list.h
@@ -35,7 +35,7 @@ G_BEGIN_DECLS
 #define PK_IS_TRANSACTION_LIST_CLASS(k)		(G_TYPE_CHECK_CLASS_TYPE ((k), PK_TYPE_TRANSACTION_LIST))
 #define PK_TRANSACTION_LIST_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), PK_TYPE_TRANSACTION_LIST, PkTransactionListClass))
 #define PK_TRANSACTION_LIST_ERROR		(pk_transaction_list_error_quark ())
-#define PK_TRANSACTION_LIST_TYPE_ERROR		(pk_transaction_list_error_get_type ()) 
+#define PK_TRANSACTION_LIST_TYPE_ERROR		(pk_transaction_list_error_get_type ())
 
 typedef struct PkTransactionListPrivate PkTransactionListPrivate;
 
commit 599f08c8d9fa24c271627e80b3e7be40c1e727a0
Merge: 575d007... eb2dd54...
Author: Richard Hughes <richard at hughsie.com>
Date:   Tue Sep 16 09:13:33 2008 +0100

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

commit eb2dd54de3dc8bdaacd133609de2b48f0d0751d7
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Tue Sep 16 10:02:27 2008 +0200

    yum: make get-details work with meta-packages (comps groups)

diff --git a/backends/yum/yumBackend.py b/backends/yum/yumBackend.py
index 6de0e55..59a1880 100755
--- a/backends/yum/yumBackend.py
+++ b/backends/yum/yumBackend.py
@@ -1124,7 +1124,7 @@ class PackageKitYumBackend(PackageKitBaseBackend,PackagekitPackage):
                         self.error(ERROR_LOCAL_INSTALL_FAILED,"Can't install %s" % inst_file)
             except yum.Errors.InstallError,e:
                 self.error(ERROR_LOCAL_INSTALL_FAILED,str(e))
-	shutil.rmtree(tempdir)
+        shutil.rmtree(tempdir)
 
     def _check_local_file(self, pkg):
         """
@@ -1305,11 +1305,21 @@ class PackageKitYumBackend(PackageKitBaseBackend,PackagekitPackage):
         self.status(STATUS_INFO)
 
         for package in package_ids:
-            pkg,inst = self._findPackage(package)
-            if pkg:
-                self._show_details_pkg(pkg)
+            grp = self._is_meta_package(package)
+            if grp:
+                id = "%s;meta;meta;meta" % grp.groupid
+                desc = grp.description
+                desc = desc.replace('\n\n',';')
+                desc = desc.replace('\n',' ')
+                group = grp.name
+                self.details(id,"",group,desc,"",0)
+
             else:
-                self.error(ERROR_PACKAGE_NOT_FOUND,'Package %s was not found' % package)
+                pkg,inst = self._findPackage(package)
+                if pkg:
+                    self._show_details_pkg(pkg)
+                else:
+                    self.error(ERROR_PACKAGE_NOT_FOUND,'Package %s was not found' % package)
 
     def _show_details_pkg(self,pkg):
 
commit ea6aba1cb2a2b5418ae79252af570658c6aa55f9
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Tue Sep 16 09:11:44 2008 +0200

    APT: Fix path of the reboot-required stamp

diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 5971e80..2b467fc 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -396,8 +396,8 @@ class PackageKitInstallProgress(apt.progress.InstallProgress):
                                   "and need investiagtion: %s" % \
                                   "\n".join(self.conffile_prompts))
         # Check for required restarts
-        if os.path.exists("/var/run/restart-required") and \
-           os.path.getmtime("/var/run/restart-required") > self.start_time:
+        if os.path.exists("/var/run/reboot-required") and \
+           os.path.getmtime("/var/run/reboot-required") > self.start_time:
             self._backend.RequireRestart(RESTART_SYSTEM, "")
 
 
commit 03ed00c7ab6f6b4aea05601af894ed169f0613c2
Merge: 8f8b274... cb4e783...
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Sep 15 23:33:05 2008 +0200

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

commit 8f8b2740a11feb4f90b43923f300799c86f7009e
Author: Sebastian Heinlein <devel at glatzor.de>
Date:   Mon Sep 15 11:23:29 2008 +0200

    Add support for running the Ubuntu dist upgrade tool. Currently we enforce the gtk frontend and desktop mode.

diff --git a/data/pk-upgrade-distro.sh b/data/pk-upgrade-distro.sh
index 670e781..b1e090a 100755
--- a/data/pk-upgrade-distro.sh
+++ b/data/pk-upgrade-distro.sh
@@ -11,6 +11,11 @@
 # the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 
+DISTRO=""
+if [ -e /usr/bin/lsb_release ]; then
+	DISTRO=$(/usr/bin/lsb_release -is)
+fi
+
 # Fedora uses preupgrade
 if [ -e /etc/fedora-release ]; then
 	if [ -e /usr/bin/preupgrade ]; then
@@ -18,6 +23,12 @@ if [ -e /etc/fedora-release ]; then
 	else
 		xdg-open http://fedoraproject.org/en/get-fedora
 	fi
+elif [ "$DISTRO" = "Ubuntu" ]; then
+	if [ -e /usr/bin/do-release-upgrade ]; then
+		gksu "/usr/bin/do-release-upgrade -m desktop -f gtk -p"
+	else
+		xdg-open http://www.ubuntu.com/getubuntu
+	fi
 else
 	# do not dep on zenity in build scripts
 	zenity --warning --title "System is not recognised" \


More information about the PackageKit-commit mailing list