attachment:client.py of InstallingSoftware


Attachment 'client.py'

Download

Toggle line numbers
   1 #!/usr/bin/python
   2 """
   3 The module provides a client to the PackageKit DBus interface. It allows to
   4 perform basic package manipulation tasks in a cross distribution way, e.g.
   5 to search for packages, install packages or codecs.
   6 """
   7 # Copyright (C) 2008 Canonical Ltd.
   8 # Copyright (C) 2008 Aidan Skinner <aidan@skinner.me.uk>
   9 # Copyright (C) 2008 Martin Pitt <martin.pitt@ubuntu.com>
  10 # Copyright (C) 2008 Tim Lauridsen <timlau@fedoraproject.org>
  11 # Copyright (C) 2008-2009 Sebastian Heinlein <devel@glatzor.de>
  12 #
  13 # Licensed under the GNU General Public License Version 2
  14 #
  15 # This program is free software; you can redistribute it and/or modify
  16 # it under the terms of the GNU General Public License as published by
  17 # the Free Software Foundation; either version 2 of the License, or
  18 # (at your option) any later version.
  19 #
  20 # This program is distributed in the hope that it will be useful,
  21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 # GNU General Public License for more details.
  24 #
  25 # You should have received a copy of the GNU General Public License
  26 # along with this program; if not, write to the Free Software
  27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  28 
  29 import locale
  30 import os.path
  31 import shutil
  32 import weakref
  33 
  34 import dbus
  35 import dbus.glib
  36 import dbus.mainloop.glib
  37 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
  38 import gobject
  39 
  40 import enums
  41 import debconf
  42 import defer
  43 from defer.utils import deferable
  44 from errors import convert_dbus_exception, TransactionFailed
  45 
  46 __all__ = ("AptTransaction", "AptClient", "get_transaction", "get_aptdaemon")
  47 
  48 
  49 class MemoizedTransaction(type):
  50 
  51     """Metaclass to cache transactions."""
  52 
  53     cache = weakref.WeakValueDictionary()
  54 
  55     def __call__(mcs, *args):
  56         tid = args[0]
  57         try:
  58             return mcs.cache[tid]
  59         except KeyError:
  60             mcs.cache[tid] = value = \
  61                     super(MemoizedTransaction, mcs).__call__(*args)
  62             return value
  63 
  64 
  65 class MemoizedMixIn(MemoizedTransaction, gobject.GObjectMeta):
  66 
  67     """Helper meta class for merging"""
  68 
  69 
  70 class AptTransaction(gobject.GObject):
  71 
  72     """Represents an aptdaemon transaction.
  73 
  74     .. note:: This class cannot be inherited since it makes use of
  75               a metaclass.
  76 
  77     .. signal:: allow-unauthenticated -> allow
  78 
  79         The signal is emitted when :attr:`allow_unauthenticated` changed.
  80 
  81         :param allow: If unauthenticated packages are allowed to be installed.
  82 
  83     .. signal:: cancellable-changed -> cancellable
  84 
  85         The signal is emitted when :attr:`cancellable` changed.
  86 
  87         :param cancellable: If the transaction can be cancelled now.
  88 
  89     .. signal:: config-file-conflict -> cur, new
  90 
  91         The signal is emitted when :attr:`config_file_conflict` changed.
  92 
  93         :param cur: The path to the current configuration file.
  94         :param new: The path to the new configuration file.
  95 
  96     .. signal:: debconf-socket-changed -> path
  97 
  98         The signal is emitted when :attr:`debconf_socket` changed.
  99 
 100         :param path: The path to the socket which will be used to forward
 101             debconf communication to the user session.
 102 
 103     .. signal:: dependencies-changed -> installs, re-installs, removals, \
 104                                         purges, upgrades, downgrades, kepts
 105 
 106         The signal is emitted when :attr:`dependencies` changed.
 107 
 108         Most likely after :meth:`simulate()` was called.
 109 
 110         :param installs: List of package which will be installed.
 111         :param reinstalls: List of package which will be re-installed.
 112         :param removals: List of package which will be removed,
 113         :param purges: List of package which will be removed including
 114             configuration files.
 115         :param upgrades: List of package which will be upgraded.
 116         :param downgrades: List of package which will be downgraded to an older
 117             version.
 118         :param kepts: List of package which will be skipped from upgrading.
 119 
 120     .. signal:: download-changed -> download
 121 
 122         The signal is emitted when :attr:`download` changed.
 123 
 124         :param download: Download size integer in Bytes.
 125 
 126     .. signal:: error -> error_code, error_details
 127 
 128         The signal is emitted when an error occured.
 129 
 130         :param error_code: The error code enumeration, e.g.
 131              :data:`aptdaemon.enums.ERROR_NO_CACHE`.
 132         :param error_details: The error description string.
 133 
 134     .. signal:: finished -> exit_state
 135 
 136         The signal is emitted when the transaction is completed or has
 137         failed.
 138 
 139         :param exit_state: The exit status enumeration string.
 140 
 141     .. signal:: http-proxy-changed -> uri
 142 
 143         The signal is emitted when :attr:`http_proxy` changed.
 144 
 145         :param uri: The URI of the proxy server, e.g. "http://proxy:8080".
 146 
 147     .. signal:: locale-changed -> locale
 148 
 149         The signal is emitted when :attr:`locale` changed.
 150 
 151         :param locale: The language which should be used for messages,
 152             eg. "de_DE".
 153 
 154     .. signal:: meta-data-changed -> meta_data
 155 
 156         The signal is emitted when :attr:`meta_data` changed.
 157 
 158         :param meta_data: The latest meta data dictionary.
 159 
 160     .. signal:: medium-required -> name, device
 161 
 162         The signal is emitted when :attr:`required_medium` changed.
 163 
 164         :param name: The name of the volume.
 165         :param device: The path of the device in which the volume should
 166             be inserted.
 167 
 168     .. signal:: remove-obsoleted-depends-changed -> remove
 169 
 170         The signal is emitted when :attr:`remove_obsoleted_depends` changed.
 171 
 172         :param remove: If obsolete dependencies should also be removed.
 173 
 174     .. signal:: role-changed -> role
 175 
 176         The signal is emitted when :attr:`role` changed.
 177 
 178         :param role: The new role enum, e.g.
 179             :data:`~aptdaemon.enums.ROLE_UPDATE_CACHE`.
 180 
 181     .. signal:: space-changed -> space
 182 
 183         The signal is emitted when :attr:`space` changed.
 184         Most likely after :meth:`simulate()` was called.
 185 
 186         :param space: Required disk space integer in Bytes. Can be negative
 187             if disk space will be freed.
 188 
 189     .. signal:: packages-changed -> installs, re-installs, removals, \
 190                                     purges, upgrades, downgrades
 191 
 192         The signal is emitted when :attr:`packages` changed.
 193 
 194         :param installs: List of package which will be installed.
 195         :param reinstalls: List of package which will be re-installed.
 196         :param removals: List of package which will be removed,
 197         :param purges: List of package which will be removed including
 198             configuration files.
 199         :param upgrades: List of package which will be upgraded.
 200         :param downgrades: List of package which will be downgraded to an older
 201             version.
 202 
 203     .. signal:: paused
 204 
 205         The signal is emitted when the transaction was paused.
 206         See :attr:`paused` and :sig:`resumed`.
 207 
 208     .. signal:: progress-changed -> progress
 209 
 210         The signal is emitted when :attr:`progress` changed.
 211 
 212         :param progress: The progress integer.
 213 
 214     .. signal:: progress-details-changed -> current_items, total_items, \
 215                                             currenty_bytes, total_bytes, \
 216                                             current_cps, eta
 217 
 218         The signal is emitted when detailed information of the progress
 219         is available.
 220 
 221         :param current_items: The number of already processed items.
 222         :param total_items: The number of all items.
 223         :param current_bytes: The number of already downloaded byte.
 224         :param total_bytes: The number of bytes which have to be downloaded
 225             totally.
 226         :param current_cps: The current download speed in bytes per second.
 227         :param eta: The elapsed time in seconds to accomplish the task.
 228 
 229     .. signal:: progress-download-changed -> uri, short_desc, total_size, \
 230                                              current_size, msg
 231 
 232         The signal is emitted when progress information about a single
 233         download is available.
 234 
 235         :param uri: The URI of the file which is downloaded.
 236         :param status: The status of the downloade, e.g.
 237             :data:`~aptdaemon.enums.DOWNLOAD_AUTH_FAILED`.
 238         :param short_desc: A short description of the file.
 239         :param total_size: The size of the file in Bytes.
 240         :param current_size: How much of the file in Bytes has already be
 241             downloaded.
 242         :param msg: The status or error description.
 243 
 244     .. signal:: resumed
 245 
 246         The signal is emitted when a paused transaction was resumed.
 247         See :attr:`paused` and :sig:`paused`.
 248 
 249     .. signal:: terminal-changed -> path
 250 
 251         The signal is emitted when :attr:`terminal` changed.
 252 
 253         :param path: The path to the slave end of the controlling terminal
 254             for the underlying dpkg call.
 255 
 256     .. signal:: terminal-attached-changed -> attached
 257 
 258         The signal is emitted when :attr:`term_attached` changed.
 259 
 260         :param attached: If the controlling terminal can be used.
 261 
 262     .. signal:: unauthenticated-changed -> unauthenticated
 263 
 264         The signal is emitted when :attr:`unauthenticated` changed.
 265 
 266         :param unauthenticated: List of unauthenticated packages.
 267 
 268     .. attribute:: cancellable
 269 
 270         If the transaction can be currently cancelled.
 271 
 272     .. attribute:: config_file_conflict
 273 
 274         If there is a conflict in the configuration file handling during
 275         an installation this attribute contains a tuple of the path to the
 276         current and the new temporary configuration file.
 277 
 278         The :meth:`resolve_config_file_conflict()` can be used to
 279         resolve the conflict and continue the processing of the
 280         transaction.
 281 
 282     .. attribute:: dependencies
 283 
 284         List of dependencies lists in the following order: packages to
 285         install, to re-install, to remove, to purge, to upgrade,
 286         to downgrade and to keep.
 287 
 288         You have to call :meth:`simulate()` to calculate the
 289         dependencies before the transaction will be executed.
 290 
 291     .. attribute:: download
 292 
 293         The number of Bytes which have to be downloaed.
 294 
 295         You have to call :meth:`simulate()` to calculate the
 296         download size before the transaction will be executed.
 297 
 298     .. attribute:: error
 299 
 300         In the case of a failed transaction this attribute holds the
 301         corresponding :exc:`errors.TransactionFailed` instance.
 302 
 303     .. attribute:: error_code
 304 
 305         In the case of a failed transaction this attribute is set to the
 306         underlying error code, e.g.
 307         :data:`enums.ERROR_PACKAGE_DOWNLOAD_FAILED`.
 308 
 309     .. attribute:: error_details
 310 
 311         In the case of a failed transaction this attribute contains a
 312         detailed error message in the language of the transaction.
 313 
 314     .. attribute:: exit
 315 
 316         Contains the exit status enum if the transaction has been completed,
 317         e.g. :data:`enums.EXIT_SUCCESS` or :data:`enums.EXIT_FAILED`.
 318 
 319     .. attribute:: http_proxy
 320 
 321         The URI to the http proxy server which should be used only for this
 322         transaction, e.g. "http://proxy:8080". It is recommended to set
 323         the system wide proxy server instead of setting this attribute
 324         for every transaction.
 325 
 326         See :meth:`set_http_proxy()`.
 327 
 328     .. attribute:: meta_data
 329 
 330         Dictionary of optional meta data which can be set by client
 331         applications. See :meth:`set_meta_date()`.
 332 
 333     .. attribute:: packages
 334 
 335        List of package lists which will be explicitly changed in the
 336        following order: packages to install, to re-install, to remove,
 337        to purge, to upgrade, to downgrade.
 338 
 339     .. attribute:: paused
 340 
 341         If the transaction is currently paused, e.g. it is required to
 342         insert a medium to install from.
 343 
 344     .. attribute:: progress
 345 
 346         An integer ranging from 0 to 101 to describe the progress of the
 347         transaction.
 348 
 349         .. note:: A value of 101 indicates that there cannot be made any
 350                   assumptions on the progress of the transaction.
 351 
 352     .. attribute:: remove_obsoleted_depends
 353 
 354         If dependencies which have been required by a removed package only
 355         should be removed, too.
 356 
 357     .. attribute:: required_medium
 358 
 359         If a medium should be inserted to continue the fetch phase of a
 360         transaction, this attribute contains a tuple of the device path of
 361         of the drive which should be used and secondly of the name of the
 362         medium.
 363 
 364         The :func:`provide_medium()` method should be used to notify aptdaemon
 365         about an inserted medium and to continue processing the transaction.
 366 
 367     .. attribute:: role
 368 
 369         The kind of action which is performed by the transaction, e.g.
 370         :data:`enums.ROLE_UPGRADE_SYSTEM`.
 371 
 372     .. attribute:: space
 373 
 374         The required disk space in Bytes. Will be negative if space is
 375         freed.
 376 
 377         You have to call :meth:`simulate()` to calculate the
 378         download size before the transaction will be executed.
 379 
 380     .. attribute:: status
 381 
 382         The enum of the current status, e.g.
 383         :data:`enums.STATUS_DOWNLOADING`.
 384 
 385     .. attribute:: status_details
 386 
 387         A string describing the current status of the transaction.
 388 
 389     .. attribute:: tid
 390 
 391         The unique identifier of the transaction. It is also the D-Bus path
 392         of the corresponding transaction object.
 393 
 394     .. attribute:: term_attached
 395 
 396         If the the package manager can be controlled using the controlling
 397         terminal specified by :func:`set_terminal()`.
 398 
 399     .. attribute:: unauthenticated
 400 
 401         List of packages which are going to be installed but are not
 402         downloaded from an authenticated repository.
 403 
 404         You have to call :meth:`simulate()` to calculate the
 405         dependencies before the transaction will be executed.
 406     """
 407 
 408     __metaclass__ = MemoizedMixIn
 409 
 410     __gsignals__ = {"finished": (gobject.SIGNAL_RUN_FIRST,
 411                                  gobject.TYPE_NONE,
 412                                  (gobject.TYPE_STRING,)),
 413                     "dependencies-changed": (gobject.SIGNAL_RUN_FIRST,
 414                                              gobject.TYPE_NONE,
 415                                              (gobject.TYPE_PYOBJECT,
 416                                               gobject.TYPE_PYOBJECT,
 417                                               gobject.TYPE_PYOBJECT,
 418                                               gobject.TYPE_PYOBJECT,
 419                                               gobject.TYPE_PYOBJECT,
 420                                               gobject.TYPE_PYOBJECT,
 421                                               gobject.TYPE_PYOBJECT)),
 422                     "download-changed": (gobject.SIGNAL_RUN_FIRST,
 423                                          gobject.TYPE_NONE,
 424                                          (gobject.TYPE_INT,)),
 425                     "space-changed": (gobject.SIGNAL_RUN_FIRST,
 426                                       gobject.TYPE_NONE,
 427                                       (gobject.TYPE_INT,)),
 428                     "error": (gobject.SIGNAL_RUN_FIRST,
 429                               gobject.TYPE_NONE,
 430                               (gobject.TYPE_STRING, gobject.TYPE_STRING)),
 431                     "role-changed": (gobject.SIGNAL_RUN_FIRST,
 432                                      gobject.TYPE_NONE,
 433                                      (gobject.TYPE_STRING,)),
 434                     "terminal-attached-changed": (gobject.SIGNAL_RUN_FIRST,
 435                                                     gobject.TYPE_NONE,
 436                                                     (gobject.TYPE_BOOLEAN,)),
 437                     "cancellable-changed": (gobject.SIGNAL_RUN_FIRST,
 438                                             gobject.TYPE_NONE,
 439                                             (gobject.TYPE_BOOLEAN,)),
 440                     "meta-data-changed": (gobject.SIGNAL_RUN_FIRST,
 441                                           gobject.TYPE_NONE,
 442                                           (gobject.TYPE_PYOBJECT,)),
 443                     "status-changed": (gobject.SIGNAL_RUN_FIRST,
 444                                        gobject.TYPE_NONE,
 445                                        (gobject.TYPE_STRING,)),
 446                     "status-details-changed": (gobject.SIGNAL_RUN_FIRST,
 447                                                gobject.TYPE_NONE,
 448                                                (gobject.TYPE_STRING,)),
 449                     "progress-changed": (gobject.SIGNAL_RUN_FIRST,
 450                                  gobject.TYPE_NONE,
 451                                  (gobject.TYPE_INT,)),
 452                     "progress-details-changed": (gobject.SIGNAL_RUN_FIRST,
 453                                          gobject.TYPE_NONE,
 454                                          (gobject.TYPE_INT, gobject.TYPE_INT,
 455                                           gobject.TYPE_INT, gobject.TYPE_INT,
 456                                           gobject.TYPE_INT, gobject.TYPE_INT)),
 457                     "progress-download-changed": (gobject.SIGNAL_RUN_FIRST,
 458                                          gobject.TYPE_NONE,
 459                                          (gobject.TYPE_STRING,
 460                                           gobject.TYPE_STRING,
 461                                           gobject.TYPE_STRING,
 462                                           gobject.TYPE_INT,
 463                                           gobject.TYPE_INT,
 464                                           gobject.TYPE_STRING)),
 465                     "packages-changed": (gobject.SIGNAL_RUN_FIRST,
 466                                          gobject.TYPE_NONE,
 467                                          (gobject.TYPE_PYOBJECT,
 468                                           gobject.TYPE_PYOBJECT,
 469                                           gobject.TYPE_PYOBJECT,
 470                                           gobject.TYPE_PYOBJECT,
 471                                           gobject.TYPE_PYOBJECT,
 472                                           gobject.TYPE_PYOBJECT)),
 473                     "unauthenticated-changed": (gobject.SIGNAL_RUN_FIRST,
 474                                                 gobject.TYPE_NONE,
 475                                                 (gobject.TYPE_PYOBJECT,
 476                                                  )),
 477                     "paused": (gobject.SIGNAL_RUN_FIRST,
 478                                gobject.TYPE_NONE,
 479                                ()),
 480                     "resumed": (gobject.SIGNAL_RUN_FIRST,
 481                                 gobject.TYPE_NONE,
 482                                 ()),
 483                     "allow-unauthenticated-changed": (gobject.SIGNAL_RUN_FIRST,
 484                                                       gobject.TYPE_NONE,
 485                                                       (gobject.TYPE_BOOLEAN,)),
 486                     "remove-obsoleted-depends-changed": (gobject.SIGNAL_RUN_FIRST,
 487                                                  gobject.TYPE_NONE,
 488                                                  (gobject.TYPE_BOOLEAN,)),
 489                     "locale-changed": (gobject.SIGNAL_RUN_FIRST,
 490                                        gobject.TYPE_NONE,
 491                                        (gobject.TYPE_STRING,)),
 492                     "terminal-changed": (gobject.SIGNAL_RUN_FIRST,
 493                                          gobject.TYPE_NONE,
 494                                          (gobject.TYPE_STRING,)),
 495                     "debconf-socket-changed": (gobject.SIGNAL_RUN_FIRST,
 496                                                gobject.TYPE_NONE,
 497                                                (gobject.TYPE_STRING,)),
 498                     "http-proxy-changed": (gobject.SIGNAL_RUN_FIRST,
 499                                            gobject.TYPE_NONE,
 500                                            (gobject.TYPE_STRING,)),
 501                     "medium-required": (gobject.SIGNAL_RUN_FIRST,
 502                                         gobject.TYPE_NONE,
 503                                         (gobject.TYPE_STRING,
 504                                          gobject.TYPE_STRING)),
 505                     "config-file-conflict": (gobject.SIGNAL_RUN_FIRST,
 506                                              gobject.TYPE_NONE,
 507                                              (gobject.TYPE_STRING,
 508                                               gobject.TYPE_STRING)),
 509                     }
 510 
 511 
 512     def __init__(self, tid, bus=None):
 513         gobject.GObject.__init__(self)
 514         self.tid = tid
 515         self.role = enums.ROLE_UNSET
 516         self.error = None
 517         self.error_code = None
 518         self.error_details = None
 519         self.exit = enums.EXIT_UNFINISHED
 520         self.cancellable = False
 521         self.term_attached = False
 522         self.required_medium = None
 523         self.config_file_conflict = None
 524         self.status = None
 525         self.status_details = ""
 526         self.progress = 0
 527         self.paused = False
 528         self.http_proxy = None
 529         self.dependencies = [[], [], [], [], [], [], []]
 530         self.packages = [[], [], [], [], []]
 531         self.unauthenticated = []
 532         self.meta_data = {}
 533         self.remove_obsoleted_depends = False
 534         self.download = 0
 535         self.downloads = {}
 536         self.space = 0
 537         self.locale = ""
 538         self._method = None
 539         self._args = []
 540         self._debconf_helper = None
 541         # Connect the signal handlers to the DBus iface
 542         if not bus:
 543             bus = dbus.SystemBus()
 544         self._proxy = bus.get_object("org.debian.apt", tid)
 545         self._iface = dbus.Interface(self._proxy, "org.debian.apt.transaction")
 546         # Watch for a crashed daemon which orphaned the dbus object
 547         self._owner_watcher = bus.watch_name_owner("org.debian.apt",
 548                                                    self._on_name_owner_changed)
 549         # main signals
 550         self._signal_matcher = \
 551             self._iface.connect_to_signal("PropertyChanged",
 552                                           self._on_property_changed,
 553                                           utf8_strings=True)
 554 
 555     def _on_name_owner_changed(self, connection):
 556         """Fail the transaction if the daemon died."""
 557         if connection == "" and self.exit == enums.EXIT_UNFINISHED:
 558             self._on_property_changed("Error", (enums.ERROR_DAEMON_DIED,
 559                                                 "It seems that the daemon "
 560                                                 "died."))
 561             self._on_property_changed("Cancellable", False)
 562             self._on_property_changed("TerminalAttached", False)
 563             self._on_property_changed("ExitState", enums.EXIT_FAILED)
 564 
 565     def _on_property_changed(self, property_name, value):
 566         """Callback for the PropertyChanged signal."""
 567         if property_name == "TerminalAttached":
 568             self.term_attached = value
 569             self.emit("terminal-attached-changed", value)
 570         elif property_name == "Cancellable":
 571             self.cancellable = value
 572             self.emit("cancellable-changed", value)
 573         elif property_name == "DebconfSocket":
 574             self.emit("debconf-socket-changed", value)
 575         elif property_name == "RemoveObsoletedDepends":
 576             self.emit("remove-obsoleted-depends-changed", value)
 577             self.remove_obsoleted_depends = value
 578         elif property_name == "AllowUnauthenticated":
 579             self.emit("allow-unauthenticated-changed", value)
 580         elif property_name == "Terminal":
 581             self.emit("terminal-changed", value)
 582         elif property_name == "Dependencies":
 583             self.dependencies = value
 584             self.emit("dependencies-changed", *value)
 585         elif property_name == "Packages":
 586             self.packages = value
 587             self.emit("packages-changed", *value)
 588         elif property_name == "Unauthenticated":
 589             self.unauthenticated = value
 590             self.emit("unauthenticated-changed", value)
 591         elif property_name == "Locale":
 592             self.locale = value
 593             self.emit("locale-changed", value)
 594         elif property_name == "Role":
 595             self.role = value
 596             self.emit("role-changed", value)
 597         elif property_name == "Status":
 598             self.status = value
 599             self.emit("status-changed", value)
 600         elif property_name == "StatusDetails":
 601             self.status_details = value
 602             self.emit("status-details-changed", value)
 603         elif property_name == "ProgressDownload":
 604             uri, status, desc, size, download, msg = value
 605             if uri:
 606                 self.downloads[uri] = (status, desc, size, download, msg)
 607                 self.emit("progress-download-changed", *value)
 608         elif property_name == "Progress":
 609             self.progress = value
 610             self.emit("progress-changed", value)
 611         elif property_name == "ConfigFileConflict":
 612             self.config_file_conflict = value
 613             if value != ("", ""):
 614                 self.emit("config-file-conflict", *value)
 615         elif property_name == "MetaData":
 616             self.meta_data = value
 617             self.emit("meta-data-changed", value)
 618         elif property_name == "Paused":
 619             self.paused = value
 620             if value:
 621                 self.emit("paused")
 622             else:
 623                 self.emit("resumed")
 624         elif property_name == "RequiredMedium":
 625             self.required_medium = value
 626             if value != ("", ""):
 627                 self.emit("medium-required", *value)
 628         elif property_name == "ProgressDetails":
 629             self.emit("progress-details-changed", *value)
 630         elif property_name == "Download":
 631             self.download = value
 632             self.emit("download-changed", value)
 633         elif property_name == "Space":
 634             self.space = value
 635             self.emit("space-changed", value)
 636         elif property_name == "HttpProxy":
 637             self.http_proxy = value
 638             self.emit("http-proxy-changed", value)
 639         elif property_name == "Error":
 640             self.error_code, self.error_details = value
 641             if self.error_code != "":
 642                 self.error = TransactionFailed(self.error_code,
 643                                                self.error_details)
 644                 self.emit("error", *value)
 645         elif property_name == "ExitState":
 646             self.exit = value
 647             if value != enums.EXIT_UNFINISHED:
 648                 self.emit("finished", value)
 649                 self._owner_watcher.cancel()
 650                 if self._debconf_helper:
 651                     self._debconf_helper.stop()
 652                 self.disconnect()
 653 
 654     @deferable
 655     @convert_dbus_exception
 656     def sync(self, reply_handler=None, error_handler=None):
 657         """Sync the properties of the transaction with the daemon.
 658 
 659         This method is called automatically on the creation of the
 660         AptTransaction instance.
 661 
 662         :param reply_handler: Callback function. If specified in combination
 663             with error_handler the method will be called asynchrounsouly.
 664         :param error_handler: Errback function. In case of an error the given
 665             callback gets the corresponding exception instance.
 666         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 667             This options is only available as an keyword.
 668 
 669         :raises: dbus.DBusException
 670         """
 671         def sync_properties(prop_dict):
 672             for property_name, value in prop_dict.iteritems():
 673                 self._on_property_changed(property_name, value)
 674             if reply_handler:
 675                 reply_handler(self)
 676         if reply_handler and error_handler:
 677             self._proxy.GetAll("org.debian.apt.transaction",
 678                                dbus_interface=dbus.PROPERTIES_IFACE,
 679                                reply_handler=sync_properties,
 680                                error_handler=error_handler)
 681         else:
 682             properties = self._proxy.GetAll("org.debian.apt.transaction",
 683                                            dbus_interface=dbus.PROPERTIES_IFACE)
 684             sync_properties(properties)
 685 
 686     @deferable
 687     @convert_dbus_exception
 688     def run_after(self, transaction, reply_handler=None, error_handler=None):
 689         """Chain this transaction after the given one. The transaction will
 690         fail if the previous one fails.
 691 
 692         To start processing of the chain you have to call :meth:`run()`
 693         of the first transaction. The others will be queued after it
 694         automatically.
 695 
 696         :param transaction: An AptTransaction on which this one depends.
 697         :param reply_handler: Callback function. If specified in combination
 698             with error_handler the method will be called asynchrounsouly.
 699         :param error_handler: Errback function. In case of an error the given
 700             callback gets the corresponding exception instance.
 701         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 702             This options is only available as an keyword.
 703 
 704         :raises: dbus.DBusException
 705          """
 706         try:
 707             return self._iface.RunAfter(transaction.tid,
 708                                         error_handler=error_handler,
 709                                         reply_handler=reply_handler)
 710         except Exception, error:
 711             if error_handler:
 712                 error_handler(error)
 713             else:
 714                 raise
 715 
 716     @deferable
 717     @convert_dbus_exception
 718     def run(self, reply_handler=None, error_handler=None):
 719         """Queue the transaction for processing.
 720 
 721         :param reply_handler: Callback function. If specified in combination
 722             with error_handler the method will be called asynchrounsouly.
 723         :param error_handler: Errback function. In case of an error the given
 724             callback gets the corresponding exception instance.
 725         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 726             This options is only available as an keyword.
 727 
 728         :raises: aptdaemon.errors.TransactionFailed, dbus.DBusException
 729         """
 730         try:
 731             return self._iface.Run(error_handler=error_handler,
 732                                    reply_handler=reply_handler)
 733         except Exception, error:
 734             if error_handler:
 735                 error_handler(error)
 736             else:
 737                 raise
 738 
 739     @deferable
 740     @convert_dbus_exception
 741     def simulate(self, reply_handler=None, error_handler=None):
 742         """Simulate the transaction to calculate the dependencies, the
 743         required download size and the required disk space.
 744 
 745         The corresponding properties of the AptTransaction will be updated.
 746 
 747         :param reply_handler: Callback function. If specified in combination
 748             with error_handler the method will be called asynchrounsouly.
 749         :param error_handler: Errback function. In case of an error the given
 750             callback gets the corresponding exception instance.
 751         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 752             This options is only available as an keyword.
 753 
 754         :raises: aptdaemon.errors.TransactionFailed, dbus.DBusException
 755         """
 756         self._iface.Simulate(reply_handler=reply_handler,
 757                              error_handler=error_handler)
 758 
 759     @deferable
 760     @convert_dbus_exception
 761     def cancel(self, reply_handler=None, error_handler=None):
 762         """Cancel the running transaction.
 763 
 764         :param reply_handler: Callback function. If specified in combination
 765             with error_handler the method will be called asynchrounsouly.
 766         :param error_handler: Errback function. In case of an error the given
 767             callback gets the corresponding exception instance.
 768         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 769             This options is only available as an keyword.
 770 
 771         :raises: aptdaemon.errors.NotAuthorizedError, dbus.DBusException
 772         """
 773         self._iface.Cancel(reply_handler=reply_handler,
 774                            error_handler=error_handler)
 775 
 776     @deferable
 777     @convert_dbus_exception
 778     def set_http_proxy(self, proxy, reply_handler=None, error_handler=None):
 779         """Use the given http proxy for downloading packages in this
 780         transaction.
 781 
 782         :param proxy: The URL of the proxy server, e.g. "http://proxy:8080"
 783         :param reply_handler: Callback function. If specified in combination
 784             with error_handler the method will be called asynchrounsouly.
 785         :param error_handler: Errback function. In case of an error the given
 786             callback gets the corresponding exception instance.
 787         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 788             This options is only available as an keyword.
 789 
 790         :raises: aptdaemon.errors.NotAuthorizedError, dbus.DBusException
 791             aptdaemon.errors.ForeignTransaction,
 792         """
 793         if reply_handler:
 794             _reply_handler = lambda: reply_handler(self)
 795         else:
 796             _reply_handler = None
 797         self._proxy.Set("org.debian.apt.transaction", "HttpProxy", proxy,
 798                         dbus_interface=dbus.PROPERTIES_IFACE,
 799                         reply_handler=_reply_handler,
 800                         error_handler=error_handler)
 801 
 802     @deferable
 803     @convert_dbus_exception
 804     def set_remove_obsoleted_depends(self, remove_obsoleted_depends,
 805                                      reply_handler=None, error_handler=None):
 806         """Include no longer required dependencies which have been installed
 807         automatically when removing packages.
 808 
 809         :param remove_obsoleted_depends: If obsolete dependencies should be
 810             also removed.
 811         :param reply_handler: Callback function. If specified in combination
 812             with error_handler the method will be called asynchrounsouly.
 813         :param error_handler: Errback function. In case of an error the given
 814             callback gets the corresponding exception instance.
 815         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 816             This options is only available as an keyword.
 817 
 818         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 819         """
 820         if reply_handler:
 821             _reply_handler = lambda: reply_handler(self)
 822         else:
 823             _reply_handler = None
 824         self._proxy.Set("org.debian.apt.transaction", 
 825                         "RemoveObsoletedDepends", remove_obsoleted_depends,
 826                         dbus_interface=dbus.PROPERTIES_IFACE,
 827                         reply_handler=_reply_handler,
 828                         error_handler=error_handler)
 829 
 830     @deferable
 831     @convert_dbus_exception
 832     def set_allow_unauthenticated(self, allow_unauthenticated,
 833                                   reply_handler=None, error_handler=None):
 834         """Allow to install unauthenticated packages.
 835 
 836         Unauthenticated packages are from the repository of a vendor whose
 837         key hasn't been installed. By default this is not allowed.
 838 
 839         :param allow_unauthenticated: If unauthenticated packages can be
 840             installed.
 841         :param reply_handler: Callback function. If specified in combination
 842             with error_handler the method will be called asynchrounsouly.
 843         :param error_handler: Errback function. In case of an error the given
 844             callback gets the corresponding exception instance.
 845         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 846             This options is only available as an keyword.
 847 
 848         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 849         """
 850         if reply_handler:
 851             _reply_handler = lambda: reply_handler(self)
 852         else:
 853             _reply_handler = None
 854         self._proxy.Set("org.debian.apt.transaction", 
 855                         "AllowUnauthenticated", allow_unauthenticated,
 856                         dbus_interface=dbus.PROPERTIES_IFACE,
 857                         reply_handler=_reply_handler,
 858                         error_handler=error_handler)
 859 
 860     @deferable
 861     @convert_dbus_exception
 862     def set_debconf_frontend(self, frontend, reply_handler=None,
 863                              error_handler=None):
 864         """Setup a debconf frontend to answer questions of the maintainer
 865         scripts.
 866 
 867         Debian allows packages to interact with the user during installation,
 868         configuration and removal phase via debconf. Aptdaemon forwards the
 869         communication to a debconf instance running as the user of the
 870         client application.
 871 
 872         :param frontend: The name of the debconf frontend which should be
 873             launched, e.g. gnome or kde. Defaults to gnome.
 874         :param reply_handler: Callback function. If specified in combination
 875             with error_handler the method will be called asynchrounsouly.
 876         :param error_handler: Errback function. In case of an error the given
 877             callback gets the corresponding exception instance.
 878         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 879             This options is only available as an keyword.
 880 
 881         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 882          """
 883         if reply_handler:
 884             _reply_handler = lambda: reply_handler(self)
 885         else:
 886             _reply_handler = None
 887         self._debconf_helper = debconf.DebconfProxy(frontend)
 888         self._proxy.Set("org.debian.apt.transaction", "DebconfSocket",
 889                         self._debconf_helper.socket_path,
 890                         dbus_interface=dbus.PROPERTIES_IFACE,
 891                         reply_handler=_reply_handler,
 892                         error_handler=error_handler)
 893         self._debconf_helper.start()
 894 
 895     @deferable
 896     @convert_dbus_exception
 897     def set_meta_data(self, **kwargs):
 898         """Store additional meta information of the transaction in the
 899         MetaData property of the transaction.
 900 
 901         The method accepts key=value pairs. The key has to be prefixed with
 902         an underscore separated identifier of the client application.
 903 
 904         In the following example Software-Center sets an application name
 905         and icon:
 906 
 907         >>> Transaction.set_meta_data(sc_icon="shiny", sc_app="xterm")
 908 
 909         :param reply_handler: Callback function. If specified in combination
 910             with error_handler the method will be called asynchrounsouly.
 911         :param error_handler: Errback function. In case of an error the given
 912             callback gets the corresponding exception instance.
 913         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 914             This options is only available as an keyword.
 915 
 916         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 917         """
 918         reply_handler = kwargs.pop("reply_handler", None)
 919         error_handler = kwargs.pop("error_handler", None)
 920         if reply_handler:
 921             _reply_handler = lambda: reply_handler(self)
 922         else:
 923             _reply_handler = None
 924         self._proxy.Set("org.debian.apt.transaction", "MetaData", kwargs,
 925                         dbus_interface=dbus.PROPERTIES_IFACE,
 926                         reply_handler=_reply_handler,
 927                         error_handler=error_handler)
 928 
 929     @deferable
 930     @convert_dbus_exception
 931     def set_terminal(self, ttyname, reply_handler=None, error_handler=None):
 932         """Allow to set a controlling terminal for the underlying dpkg call.
 933 
 934         See the source code of gtkwidgets.AptTerminal or console.ConsoleClient
 935         as example.
 936 
 937         >>> master, slave = pty.openpty()
 938         >>> transaction.set_terminal(os.ttyname(slave))
 939 
 940         :param terminal: The slave end of a tty.
 941         :param reply_handler: Callback function. If specified in combination
 942             with error_handler the method will be called asynchrounsouly.
 943         :param error_handler: Errback function. In case of an error the given
 944             callback gets the corresponding exception instance.
 945         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 946             This options is only available as an keyword.
 947 
 948         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 949         """
 950         if reply_handler:
 951             _reply_handler = lambda: reply_handler(self)
 952         else:
 953             _reply_handler = None
 954         self._proxy.Set("org.debian.apt.transaction", "Terminal", ttyname,
 955                         dbus_interface=dbus.PROPERTIES_IFACE,
 956                         reply_handler=_reply_handler,
 957                         error_handler=error_handler)
 958 
 959     def disconnect(self):
 960         """Stop monitoring the progress of the transaction."""
 961         if hasattr(self, "_signal_matcher"):
 962             self._signal_matcher.remove()
 963             del self._signal_matcher
 964 
 965     @deferable
 966     @convert_dbus_exception
 967     def set_locale(self, locale_name, reply_handler=None, error_handler=None):
 968         """Set the language for status and error messages.
 969 
 970         :param locale: The locale name, e.g. de_DE@UTF-8.
 971         :param reply_handler: Callback function. If specified in combination
 972             with error_handler the method will be called asynchrounsouly.
 973         :param error_handler: Errback function. In case of an error the given
 974             callback gets the corresponding exception instance.
 975         :param defer: Run the method asynchrounsly and return a defer.Deferred.
 976             This options is only available as an keyword.
 977 
 978         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
 979         """
 980         if reply_handler:
 981             _reply_handler = lambda: reply_handler(self)
 982         else:
 983             _reply_handler = None
 984         self._proxy.Set("org.debian.apt.transaction", "Locale", locale_name,
 985                         dbus_interface=dbus.PROPERTIES_IFACE,
 986                         reply_handler=_reply_handler,
 987                         error_handler=error_handler)
 988 
 989     @deferable
 990     @convert_dbus_exception
 991     def provide_medium(self, medium, reply_handler=None, error_handler=None):
 992         """Continue a paused transaction which waits for a medium to install
 993         from.
 994 
 995         :param medium: The name of the provided medium.
 996         :param reply_handler: Callback function. If specified in combination
 997             with error_handler the method will be called asynchrounsouly.
 998         :param error_handler: Errback function. In case of an error the given
 999             callback gets the corresponding exception instance.
1000         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1001             This options is only available as an keyword.
1002 
1003         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
1004          """
1005         self._iface.ProvideMedium(medium, reply_handler=reply_handler,
1006                                   error_handler=error_handler)
1007 
1008     @deferable
1009     @convert_dbus_exception
1010     def resolve_config_file_conflict(self, config, answer, reply_handler=None,
1011                                      error_handler=None):
1012         """Continue a paused transaction which waits for the resolution of a
1013         configuration file conflict.
1014 
1015         :param config: The path to the current version of the configuration
1016             file.
1017         :param answer: Can be either "keep" or "replace".
1018         :param reply_handler: Callback function. If specified in combination
1019             with error_handler the method will be called asynchrounsouly.
1020         :param error_handler: Errback function. In case of an error the given
1021             callback gets the corresponding exception instance.
1022         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1023             This options is only available as an keyword.
1024 
1025         :raises: aptdaemon.errors.ForeignTransaction, dbus.DBusException
1026          """
1027         self._iface.ResolveConfigFileConflict(config, answer,
1028                                               reply_handler=reply_handler,
1029                                               error_handler=error_handler)
1030 
1031 
1032 class AptClient(object):
1033 
1034     """Provides a complete client for aptdaemon."""
1035 
1036     def __init__(self, bus=None):
1037         """Return a new AptClient instance."""
1038         if bus:
1039             self.bus = bus
1040         else:
1041             self.bus = dbus.SystemBus()
1042         # Catch an invalid locale
1043         try:
1044             self._locale = "%s.%s" % locale.getdefaultlocale()
1045         except ValueError:
1046             self._locale = None
1047         self.terminal = None
1048 
1049     @convert_dbus_exception
1050     def get_trusted_vendor_keys(self, reply_handler=None, error_handler=None):
1051         """Get the list of the installed vendor keys which are used to
1052         authenticate packages.
1053 
1054         :param reply_handler: Callback function. If specified in combination
1055             with error_handler the method will be called asynchrounsouly.
1056         :param error_handler: Errback function. In case of an error the given
1057             callback gets the corresponding exception instance.
1058         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1059             This options is only available as an keyword.
1060 
1061         :raises: dbus.DBusException
1062 
1063         :returns: Fingerprints of all installed vendor keys.
1064         """
1065         daemon = get_aptdaemon(self.bus)
1066         keys = daemon.GetTrustedVendorKeys(reply_handler=reply_handler,
1067                                            error_handler=error_handler)
1068         return keys
1069 
1070     @deferable
1071     @convert_dbus_exception
1072     def upgrade_system(self, safe_mode=True, wait=False, reply_handler=None,
1073                        error_handler=None):
1074         """Create a new transaction to apply all avaibale upgrades.
1075 
1076         :param safe_mode: If True only already installed packages will be
1077             updated. Updates which require to remove installed packages or to
1078             install additional packages will be skipped.
1079 
1080         :param wait: if True run the transaction immediately and return its exit
1081             state instead of the transaction itself.
1082         :param reply_handler: Callback function. If specified in combination
1083             with error_handler the method will be called asynchrounsouly.
1084         :param error_handler: Errback function. In case of an error the given
1085             callback gets the corresponding exception instance.
1086         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1087             This options is only available as an keyword.
1088 
1089         :raises: dbus.DBusException
1090 
1091         :returns: An AptTransaction instance.
1092         """
1093         return self._run_transaction("UpgradeSystem", [safe_mode],
1094                                      wait, reply_handler, error_handler)
1095 
1096     @deferable
1097     @convert_dbus_exception
1098     def install_packages(self, package_names, wait=False, reply_handler=None,
1099                          error_handler=None):
1100         """Create a new transaction to install the given packages from the
1101         reporitories.
1102 
1103         The version number and target release of the packages can be specified
1104         using the traditional apt-get syntax, e.g. "xterm=281.1" to force
1105         installing the version 281.1 of xterm or "xterm/experimental" to
1106         force installing xterm from the experimental release.
1107 
1108         :param package_names: List of names of the packages which should be
1109             installed.
1110 
1111         :param wait: if True run the transaction immediately and return its exit
1112             state instead of the transaction itself.
1113         :param reply_handler: Callback function. If specified in combination
1114             with error_handler the method will be called asynchrounsouly.
1115         :param error_handler: Errback function. In case of an error the given
1116             callback gets the corresponding exception instance.
1117         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1118             This options is only available as an keyword.
1119 
1120         :raises: dbus.DBusException
1121 
1122         :returns: An AptTransaction instance.
1123         """
1124         return self._run_transaction("InstallPackages", [package_names],
1125                                      wait, reply_handler, error_handler)
1126 
1127     @deferable
1128     @convert_dbus_exception
1129     def add_repository(self, src_type, uri, dist, comps=None, comment="",
1130                        sourcesfile="", wait=False, reply_handler=None,
1131                        error_handler=None):
1132         """Create a new transaction to enable a repository.
1133 
1134         :param src_type: The type of the repository (deb, deb-src).
1135         :param uri: The main repository URI 
1136            (e.g. http://archive.ubuntu.com/ubuntu)
1137         :param dist: The distribution to use (e.g. stable or lenny-backports).
1138         :param comps: List of components (e.g. main, restricted).
1139         :param comment: A comment which should be added to the sources.list.
1140         :param sourcesfile: (Optoinal) filename in sources.list.d.
1141 
1142         :param wait: if True run the transaction immediately and return its exit
1143             state instead of the transaction itself.
1144         :param reply_handler: Callback function. If specified in combination
1145             with error_handler the method will be called asynchrounsouly.
1146         :param error_handler: Errback function. In case of an error the given
1147             callback gets the corresponding exception instance.
1148         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1149             This options is only available as an keyword.
1150 
1151         :raises: dbus.DBusException
1152 
1153         :returns: An AptTransaction instance.
1154         """
1155         # dbus can not deal with empty lists and will error
1156         if not comps:
1157             comps = [""]
1158         return self._run_transaction("AddRepository",
1159                                      [src_type, uri, dist, comps, comment,
1160                                       sourcesfile],
1161                                      wait, reply_handler, error_handler)
1162 
1163     @deferable
1164     @convert_dbus_exception
1165     def add_vendor_key_from_keyserver(self, keyid, keyserver, wait=False, 
1166                                       reply_handler=None, error_handler=None):
1167         """Create a new transaction to download and install the key of a
1168         software vendor. The key is used to authenticate packages of the 
1169         vendor.
1170 
1171         :param keyid: The id of the GnuPG key (e.g. 0x0EB12F05)
1172         :param keyserver: The server to get the key from (e.g.
1173             keyserver.ubuntu.com)
1174 
1175         :param wait: if True run the transaction immediately and return its exit
1176             state instead of the transaction itself.
1177         :param reply_handler: Callback function. If specified in combination
1178             with error_handler the method will be called asynchrounsouly.
1179         :param error_handler: Errback function. In case of an error the given
1180             callback gets the corresponding exception instance.
1181         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1182             This options is only available as an keyword.
1183 
1184         :raises: dbus.DBusException
1185 
1186         :returns: An AptTransaction instance.
1187         """
1188         return self._run_transaction("AddVendorKeyFromKeyserver", 
1189                                      [keyid,keyserver],
1190                                      wait, reply_handler, error_handler)
1191 
1192     @deferable
1193     @convert_dbus_exception
1194     def add_vendor_key_from_file(self, path, wait=False, reply_handler=None,
1195                                  error_handler=None):
1196         """Create a new transaction to install the key file of a software
1197         vendor. The key is used to authenticate packages of the vendor.
1198 
1199         :param path: The absolute path to the key file.
1200 
1201         :param wait: if True run the transaction immediately and return its exit
1202             state instead of the transaction itself.
1203         :param reply_handler: Callback function. If specified in combination
1204             with error_handler the method will be called asynchrounsouly.
1205         :param error_handler: Errback function. In case of an error the given
1206             callback gets the corresponding exception instance.
1207         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1208             This options is only available as an keyword.
1209 
1210         :raises: dbus.DBusException
1211 
1212         :returns: An AptTransaction instance.
1213         """
1214         return self._run_transaction("AddVendorKeyFromFile", [path],
1215                                      wait, reply_handler, error_handler)
1216 
1217     @deferable
1218     @convert_dbus_exception
1219     def remove_vendor_key(self, fingerprint, wait=False, reply_handler=None,
1220                           error_handler=None):
1221         """Create a new transaction to remove the key of a software vendor
1222         from the list of trusted ones.
1223 
1224         The key is used to authenticate the origin of packages.
1225 
1226         :param fingerprint: The fingerprint of the key.
1227 
1228         :param wait: if True run the transaction immediately and return its exit
1229             state instead of the transaction itself.
1230         :param reply_handler: Callback function. If specified in combination
1231             with error_handler the method will be called asynchrounsouly.
1232         :param error_handler: Errback function. In case of an error the given
1233             callback gets the corresponding exception instance.
1234         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1235             This options is only available as an keyword.
1236 
1237         :raises: dbus.DBusException
1238 
1239         :returns: An AptTransaction instance.
1240         """
1241         return self._run_transaction("RemoveVendorKey", [fingerprint],
1242                                      wait, reply_handler, error_handler)
1243 
1244     @deferable
1245     @convert_dbus_exception
1246     def install_file(self, path, force=False, wait=False, reply_handler=None,
1247                      error_handler=None):
1248         """Create a new transaction to install a local package file.
1249 
1250         :param path: The absolute path to the .deb-file.
1251         :param force: Force the installation of a .deb-file even if it
1252             violates the quality standard defined in the packaging policy.
1253 
1254         :param wait: if True run the transaction immediately and return its exit
1255             state instead of the transaction itself.
1256         :param reply_handler: Callback function. If specified in combination
1257             with error_handler the method will be called asynchrounsouly.
1258         :param error_handler: Errback function. In case of an error the given
1259             callback gets the corresponding exception instance.
1260         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1261             This options is only available as an keyword.
1262 
1263         :raises: dbus.DBusException
1264 
1265         :returns: An AptTransaction instance.
1266         """
1267         # Root is not allowed to access FUSE file systems. So copy files
1268         # to the local system.
1269         #FIXME: the locally cached one should be removed afterwards
1270         home = os.getenv("HOME", None)
1271         if home and path.startswith(os.path.join(home, ".gvfs")):
1272             shutil.copy(path, "/tmp")
1273             path = os.path.join("/tmp", os.path.basename(path))
1274         return self._run_transaction("InstallFile", [path, force],
1275                                      wait, reply_handler, error_handler)
1276 
1277     @deferable
1278     @convert_dbus_exception
1279     def upgrade_packages(self, package_names, wait=False, reply_handler=None,
1280                          error_handler=None):
1281         """Create a new transaction to upgrade installed packages.
1282 
1283         The version number and target release of the packages can be specified
1284         using the traditional apt-get syntax, e.g. "xterm=281.1" to force
1285         installing the version 281.1 of xterm or "xterm/experimental" to
1286         force installing xterm from the experimental release.
1287 
1288         :param package_names: The list of package which should be upgraded.
1289 
1290         :param wait: if True run the transaction immediately and return its exit
1291             state instead of the transaction itself.
1292         :param reply_handler: Callback function. If specified in combination
1293             with error_handler the method will be called asynchrounsouly.
1294         :param error_handler: Errback function. In case of an error the given
1295             callback gets the corresponding exception instance.
1296         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1297             This options is only available as an keyword.
1298 
1299         :raises: dbus.DBusException
1300 
1301         :returns: An AptTransaction instance.
1302         """
1303         return self._run_transaction("UpgradePackages", [package_names],
1304                                      wait, reply_handler, error_handler)
1305 
1306     @deferable
1307     @convert_dbus_exception
1308     def remove_packages(self, package_names, wait=False,
1309                         reply_handler=None, error_handler=None):
1310         """Create a new transaction to remove installed packages.
1311 
1312         :param package_names: The list of packages which should be removed.
1313 
1314         :param wait: if True run the transaction immediately and return its exit
1315             state instead of the transaction itself.
1316         :param reply_handler: Callback function. If specified in combination
1317             with error_handler the method will be called asynchrounsouly.
1318         :param error_handler: Errback function. In case of an error the given
1319             callback gets the corresponding exception instance.
1320         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1321             This options is only available as an keyword.
1322 
1323         :raises: dbus.DBusException
1324 
1325         :returns: An AptTransaction instance.
1326         """
1327         return self._run_transaction("RemovePackages", [package_names],
1328                                      wait, reply_handler, error_handler)
1329 
1330     @deferable
1331     @convert_dbus_exception
1332     def commit_packages(self, install, reinstall, remove, purge, upgrade,
1333                         downgrade, wait=False, reply_handler=None,
1334                         error_handler=None):
1335         """Create a new transaction to perform a complex package management
1336         task which allows to install, remove, upgrade or downgrade several
1337         packages at the same time.
1338 
1339         The version number and target release of the packages can be specified
1340         using the traditional apt-get syntax, e.g. "xterm=281.1" to force
1341         installing the version 281.1 of xterm or "xterm/experimental" to
1342         force installing xterm from the experimental release.
1343 
1344         :param install: List of packages to install.
1345         :param reinstall: List of packages to re-install.
1346         :param remove: List of packages to remove.
1347         :param purge: List of packages to purge.
1348         :param upgrade: List of packages to upgrade.
1349         :param downgrade: List of packages to downgrade. The version of the
1350             package has to be appended to the name separated by a "=", e.g.
1351             "xterm=272-1".
1352 
1353         :param wait: if True run the transaction immediately and return its exit
1354             state instead of the transaction itself.
1355         :param reply_handler: Callback function. If specified in combination
1356             with error_handler the method will be called asynchrounsouly.
1357         :param error_handler: Errback function. In case of an error the given
1358             callback gets the corresponding exception instance.
1359         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1360             This options is only available as an keyword.
1361 
1362         :raises: dbus.DBusException
1363 
1364         :returns: An AptTransaction instance.
1365         """
1366         def check_empty_list(lst):
1367             if not lst:
1368                 return [""]
1369             else:
1370                 return lst
1371         pkgs = [check_empty_list(lst) for lst in [install, reinstall, remove,
1372                                                   purge, upgrade, downgrade]]
1373         return self._run_transaction("CommitPackages", pkgs,
1374                                      wait, reply_handler, error_handler)
1375 
1376     @deferable
1377     @convert_dbus_exception
1378     def fix_broken_depends(self, wait=False, reply_handler=None,
1379                            error_handler=None):
1380         """Create a new transaction to fix unsatisfied dependencies of
1381         already installed packages.
1382 
1383         Corresponds to the ``apt-get -f install`` call.
1384 
1385         :param wait: if True run the transaction immediately and return its exit
1386             state instead of the transaction itself.
1387         :param reply_handler: Callback function. If specified in combination
1388             with error_handler the method will be called asynchrounsouly.
1389         :param error_handler: Errback function. In case of an error the given
1390             callback gets the corresponding exception instance.
1391         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1392             This options is only available as an keyword.
1393 
1394         :raises: dbus.DBusException
1395 
1396         :returns: An AptTransaction instance.
1397         """
1398         return self._run_transaction("FixBrokenDepends", [],
1399                                      wait, reply_handler, error_handler)
1400 
1401     @deferable
1402     @convert_dbus_exception
1403     def reconfigure(self, packages, priority="default",
1404                     wait=False, reply_handler=None, error_handler=None):
1405         """Create a new transaction to reconfigure already installed packages.
1406 
1407         Corresponds to the ``dpkg-reconfigure`` call.
1408 
1409         :param packages: List of package names which should be reconfigured.
1410         :param priority: The minimum priority of question that will be
1411             displayed.
1412 
1413         :param wait: if True run the transaction immediately and return its exit
1414             state instead of the transaction itself.
1415         :param reply_handler: Callback function. If specified in combination
1416             with error_handler the method will be called asynchrounsouly.
1417         :param error_handler: Errback function. In case of an error the given
1418             callback gets the corresponding exception instance.
1419         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1420             This options is only available as an keyword.
1421 
1422         :raises: dbus.DBusException
1423 
1424         :returns: An AptTransaction instance.
1425         """
1426         return self._run_transaction("Reconfigure", [packages, priority], wait,
1427                                      reply_handler, error_handler)
1428 
1429 
1430     @deferable
1431     @convert_dbus_exception
1432     def fix_incomplete_install(self, wait=False, reply_handler=None,
1433                                error_handler=None):
1434         """Create a new transaction to complete a previous interrupted
1435         installation.
1436 
1437         Corresponds to the ``dpkg --confgiure -a`` call.
1438 
1439         :param wait: if True run the transaction immediately and return its exit
1440             state instead of the transaction itself.
1441         :param reply_handler: Callback function. If specified in combination
1442             with error_handler the method will be called asynchrounsouly.
1443         :param error_handler: Errback function. In case of an error the given
1444             callback gets the corresponding exception instance.
1445         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1446             This options is only available as an keyword.
1447 
1448         :raises: dbus.DBusException
1449 
1450         :returns: An AptTransaction instance.
1451         """
1452         return self._run_transaction("FixIncompleteInstall", [], wait,
1453                                      reply_handler, error_handler)
1454 
1455     @deferable
1456     @convert_dbus_exception
1457     def update_cache(self, sources_list=None, wait=False,
1458                      reply_handler=None, error_handler=None):
1459         """Create a new transaction to update the package cache.
1460 
1461         The repositories will be queried for installable packages.
1462 
1463         :param sources_list: Path to a sources.list which contains repositories
1464             that should be updated only. The other repositories will
1465             be ignored in this case. Can be either the file name of a snippet
1466             in /etc/apt/sources.list.d or an absolute path.
1467  
1468         :param wait: if True run the transaction immediately and return its exit
1469             state instead of the transaction itself.
1470         :param reply_handler: Callback function. If specified in combination
1471             with error_handler the method will be called asynchrounsouly.
1472         :param error_handler: Errback function. In case of an error the given
1473             callback gets the corresponding exception instance.
1474         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1475             This options is only available as an keyword.
1476 
1477         :raises: dbus.DBusException
1478 
1479         :returns: An AptTransaction instance.
1480         """
1481         if sources_list:
1482             return self._run_transaction("UpdateCachePartially", [sources_list],
1483                                          wait, reply_handler, error_handler)
1484         else:
1485             return self._run_transaction("UpdateCache", [], wait, reply_handler,
1486                                          error_handler)
1487 
1488     @deferable
1489     @convert_dbus_exception
1490     def enable_distro_component(self, component, wait=False, reply_handler=None,
1491                                 error_handler=None):
1492         """Create a new transaction to enable the component of the
1493         distribution repository.
1494 
1495         :param component: The name of the component, e.g. main or universe.
1496 
1497         :param wait: if True run the transaction immediately and return its exit
1498             state instead of the transaction itself.
1499         :param reply_handler: Callback function. If specified in combination
1500             with error_handler the method will be called asynchrounsouly.
1501         :param error_handler: Errback function. In case of an error the given
1502             callback gets the corresponding exception instance.
1503         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1504             This options is only available as an keyword.
1505 
1506         :raises: dbus.DBusException
1507 
1508         :returns: An AptTransaction instance.
1509         """
1510         return self._run_transaction("EnableDistroComponent", [component],
1511                                      wait, reply_handler, error_handler)
1512 
1513     @deferable
1514     @convert_dbus_exception
1515     def clean(self, wait=False, reply_handler=None, error_handler=None):
1516         """Remove all downloaded files.
1517 
1518         :param wait: if True run the transaction immediately and return its exit
1519             state instead of the transaction itself.
1520         :param reply_handler: Callback function. If specified in combination
1521             with error_handler the method will be called asynchrounsouly.
1522         :param error_handler: Errback function. In case of an error the given
1523             callback gets the corresponding exception instance.
1524         :param defer: Run the method asynchrounsly and return a defer.Deferred.
1525             This options is only available as an keyword.
1526 
1527         :raises: dbus.DBusException
1528 
1529         :returns: An AptTransaction instance.
1530         """
1531         return self._run_transaction("Clean", [], wait, reply_handler,
1532                                      error_handler)
1533 
1534 
1535     def _run_transaction(self, method_name, args, wait, reply_handler,
1536                          error_handler):
1537         async = reply_handler and error_handler
1538         try:
1539             deferred = self._run_transaction_helper(method_name, args, wait,
1540                                                     async)
1541         except Exception, error:
1542             if async:
1543                 error_handler(error)
1544                 return
1545             else:
1546                 raise
1547         if async:
1548             def on_error(error):
1549                 """Convert the DeferredException to a normal exception."""
1550                 try:
1551                     error.raise_exception()
1552                 except Exception, error:
1553                     error_handler(error)
1554             deferred.add_callbacks(reply_handler)
1555             deferred.add_errback(on_error)
1556             return deferred
1557         else:
1558             # Iterate on the main loop - we cannot use a sub loop here,
1559             # since the D-Bus python bindings only work on the main loop
1560             context = gobject.main_context_default()
1561             while not hasattr(deferred, "result"):
1562                 context.iteration(True)
1563            # If there has been an error in the helper raise it
1564             if isinstance(deferred.result, defer.DeferredException):
1565                 deferred.result.raise_exception()
1566             trans = deferred.result
1567             if trans.error:
1568                 raise trans.error
1569             if wait:
1570                 # Wait until the transaction is complete and the properties
1571                 # of the transaction have been updated
1572                 while trans.exit == enums.EXIT_UNFINISHED:
1573                     context.iteration(True)
1574                 return trans.exit
1575             else:
1576                 return trans
1577 
1578     @defer.inline_callbacks
1579     def _run_transaction_helper(self, method_name, args, wait, async):
1580         daemon = get_aptdaemon(self.bus)
1581         dbus_method = daemon.get_dbus_method(method_name)
1582         if async:
1583             deferred = defer.Deferred()
1584             dbus_method(reply_handler=deferred.callback,
1585                         error_handler=deferred.errback, *args, timeout=86400)
1586             tid = yield deferred
1587         else:
1588             tid = dbus_method(*args, timeout=86400)
1589         trans = AptTransaction(tid, self.bus)
1590         if self._locale:
1591             yield trans.set_locale(self._locale)
1592         if self.terminal:
1593             yield trans.set_terminal(self.terminal)
1594         yield trans.sync()
1595         if wait and async:
1596             deferred_wait = defer.Deferred()
1597             sig = trans.connect("finished",
1598                                 lambda trans, exit: \
1599                                     (exit != enums.EXIT_UNFINISHED and
1600                                      deferred_wait.callback(exit)))
1601             yield trans.run()
1602             yield deferred_wait
1603             gobject.source_remove(sig)
1604             defer.return_value(trans.exit)
1605         elif wait:
1606             yield trans.run()
1607         defer.return_value(trans)
1608 
1609 
1610 @deferable
1611 @convert_dbus_exception
1612 def get_transaction(tid, bus=None, reply_handler=None, error_handler=None):
1613     """Get an existing transaction by its identifier.
1614 
1615     :param tid: The identifer and D-Bus path of the transaction
1616         e.g. /org/debian/apt/transaction/78904e5f9fa34098879e768032789109
1617     :param bus: Optionally the D-Bus on which aptdaemon listens. Defaults
1618         to the system bus.
1619 
1620     :param reply_handler: Callback function. If specified in combination
1621         with error_handler the method will be called asynchrounsouly.
1622     :param error_handler: Errback function. In case of an error the given
1623         callback gets the corresponding exception instance.
1624     :param defer: Run the method asynchrounsly and return a defer.Deferred.
1625         This options is only available as an keyword.
1626 
1627     :raises: dbus.DBusException
1628 
1629     :returns: An AptTransaction instance.
1630     """
1631     if not bus:
1632         bus = dbus.SystemBus()
1633     trans = AptTransaction(tid, bus)
1634     if error_handler and reply_handler:
1635         trans.sync(reply_handler=reply_handler, error_handler=error_handler)
1636     else:
1637         trans.sync()
1638         return trans
1639 
1640 def get_aptdaemon(bus=None):
1641     """Get the daemon D-Bus interface.
1642 
1643     :param bus: Optionally the D-Bus on which aptdaemon listens. Defaults
1644         to the system bus.
1645 
1646     :raises: dbus.DBusException
1647 
1648     :returns: An dbus.Interface instance.
1649     """
1650     if not bus:
1651         bus = dbus.SystemBus()
1652     return dbus.Interface(bus.get_object("org.debian.apt",
1653                                          "/org/debian/apt",
1654                                          False),
1655                           "org.debian.apt")
1656 
1657 # vim:ts=4:sw=4:et

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2007-03-25 23:30:35, 86.6 KB) [[attachment:AddRemoveProgs.png]]
  • [get | view] (2007-03-25 23:40:40, 14.5 KB) [[attachment:Aptitude.png]]
  • [get | view] (2007-03-25 23:37:02, 181.9 KB) [[attachment:adept.png]]
  • [get | view] (2013-07-31 01:14:31, 70.4 KB) [[attachment:client.py]]
  • [get | view] (2006-04-27 16:01:24, 3.4 KB) [[attachment:deb_package.png]]
  • [get | view] (2007-03-17 21:39:03, 9.6 KB) [[attachment:scrn-synaptic-dependencies.jpg]]
  • [get | view] (2006-07-10 08:15:58, 11.0 KB) [[attachment:update-notification.png]]
  • [get | view] (2006-07-10 08:12:27, 11.0 KB) [[attachment:updates.png]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.