Merge lp:~cyphermox/aptdaemon/rip-out-pkcompat into lp:aptdaemon

Proposed by Mathieu Trudel-Lapierre
Status: Needs review
Proposed branch: lp:~cyphermox/aptdaemon/rip-out-pkcompat
Merge into: lp:aptdaemon
Diff against target: 2055 lines (+2/-2032)
2 files modified
aptdaemon/core.py (+2/-10)
aptdaemon/pkcompat.py (+0/-2022)
To merge this branch: bzr merge lp:~cyphermox/aptdaemon/rip-out-pkcompat
Reviewer Review Type Date Requested Status
Aptdaemon Developers Pending
Review via email: mp+295783@code.launchpad.net

Description of the change

Rip out pkcompat. It's not used by aptdaemon anyway aside from checking that PackageKit is running, and we can actually rely on PackageKit being DBus-activated to install stuff.

To post a comment you must log in.

Unmerged revisions

987. By Mathieu Trudel-Lapierre

Drop pkcompat; just use PackageKit directly via the AptPackageKitWorker we already have.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'aptdaemon/core.py'
2--- aptdaemon/core.py 2015-06-18 12:46:21 +0000
3+++ aptdaemon/core.py 2016-05-26 01:42:29 +0000
4@@ -1445,22 +1445,14 @@
5 load_plugins = not options.disable_plugins
6 try:
7 from .worker.pkworker import AptPackageKitWorker
8- from . import pkcompat
9- except ImportError:
10- self.worker = AptWorker(options.chroot, load_plugins)
11- else:
12 self.worker = AptPackageKitWorker(options.chroot,
13 load_plugins)
14+ except:
15+ self.worker = AptWorker(options.chroot, load_plugins)
16 self.queue = TransactionQueue(self.worker)
17 self.queue.connect("queue-changed", self._on_queue_changed)
18 # keep state of the last information about reboot required
19 self._reboot_required = self.worker.is_reboot_required()
20- try:
21- self.packagekit = pkcompat.PackageKit(self.queue, connect, bus)
22- except dbus.exceptions.NameExistsException:
23- log.warning("PackageKit is already running")
24- except NameError:
25- pass
26 log.debug("Daemon was initialized")
27
28 def _on_queue_changed(self, queue):
29
30=== removed file 'aptdaemon/pkcompat.py'
31--- aptdaemon/pkcompat.py 2015-06-18 12:46:21 +0000
32+++ aptdaemon/pkcompat.py 1970-01-01 00:00:00 +0000
33@@ -1,2022 +0,0 @@
34-# !/usr/bin/env python
35-# -*- coding: utf-8 -*-
36-"""
37-Provides a limited compatibility layer to PackageKit
38-
39-Copyright (C) 2007 Ali Sabil <ali.sabil@gmail.com>
40-Copyright (C) 2007 Tom Parker <palfrey@tevp.net>
41-Copyright (C) 2008-2011 Sebastian Heinlein <glatzor@ubuntu.com>
42-
43-Licensed under the GNU General Public License Version 2
44-
45-This program is free software; you can redistribute it and/or modify
46-it under the terms of the GNU General Public License as published by
47-the Free Software Foundation; either version 2 of the License, or
48-(at your option) any later version.
49-"""
50-
51-__author__ = "Sebastian Heinlein <devel@glatzor.de>"
52-
53-import datetime
54-import glob
55-import gzip
56-import locale
57-import logging
58-import os
59-import platform
60-import re
61-import subprocess
62-import tempfile
63-import time
64-import uuid
65-
66-from defer import inline_callbacks, return_value
67-from defer.utils import dbus_deferred_method
68-import dbus
69-from gi.repository import GObject, GLib
70-from gi.repository import PackageKitGlib as pk
71-
72-# for optional plugin support
73-try:
74- import pkg_resources
75-except ImportError:
76- pkg_resources = None
77-
78-from . import policykit1
79-from . import core
80-from .core import APTDAEMON_TRANSACTION_DBUS_INTERFACE
81-from . import enums as aptd_enums
82-from .errors import TransactionFailed
83-from . import errors
84-from .progress import DaemonAcquireProgress
85-from . import worker
86-from . import networking
87-from .pkutils import (bitfield_summarize, bitfield_add, bitfield_remove,
88- bitfield_contains)
89-from .utils import split_package_id
90-
91-
92-pklog = logging.getLogger("AptDaemon.PackageKit")
93-
94-# Check if update-manager-core is installed to get aware of the
95-# latest distro releases
96-try:
97- from UpdateManager.Core.MetaRelease import MetaReleaseCore
98-except ImportError:
99- META_RELEASE_SUPPORT = False
100-else:
101- META_RELEASE_SUPPORT = True
102-
103-PACKAGEKIT_DBUS_INTERFACE = "org.freedesktop.PackageKit"
104-PACKAGEKIT_DBUS_SERVICE = "org.freedesktop.PackageKit"
105-PACKAGEKIT_DBUS_PATH = "/org/freedesktop/PackageKit"
106-
107-PACKAGEKIT_TRANS_DBUS_INTERFACE = "org.freedesktop.PackageKit.Transaction"
108-PACKAGEKIT_TRANS_DBUS_SERVICE = "org.freedesktop.PackageKit.Transaction"
109-
110-MAP_EXIT_ENUM = {
111- aptd_enums.EXIT_SUCCESS: pk.ExitEnum.SUCCESS,
112- aptd_enums.EXIT_CANCELLED: pk.ExitEnum.CANCELLED,
113- aptd_enums.EXIT_FAILED: pk.ExitEnum.FAILED,
114- aptd_enums.EXIT_FAILED: pk.ExitEnum.FAILED,
115- aptd_enums.EXIT_PREVIOUS_FAILED: pk.ExitEnum.FAILED}
116-
117-MAP_STATUS_ENUM = {
118- aptd_enums.STATUS_AUTHENTICATING: pk.StatusEnum.WAITING_FOR_AUTH,
119- aptd_enums.STATUS_SETTING_UP: pk.StatusEnum.SETUP,
120- aptd_enums.STATUS_QUERY: pk.StatusEnum.QUERY,
121- aptd_enums.STATUS_WAITING: pk.StatusEnum.WAIT,
122- aptd_enums.STATUS_RUNNING: pk.StatusEnum.RUNNING,
123- aptd_enums.STATUS_CANCELLING: pk.StatusEnum.CANCEL,
124- aptd_enums.STATUS_CLEANING_UP: pk.StatusEnum.CLEANUP,
125- aptd_enums.STATUS_COMMITTING: pk.StatusEnum.COMMIT,
126- aptd_enums.STATUS_DOWNLOADING: pk.StatusEnum.DOWNLOAD,
127- aptd_enums.STATUS_DOWNLOADING_REPO: pk.StatusEnum.DOWNLOAD_REPOSITORY,
128- aptd_enums.STATUS_FINISHED: pk.StatusEnum.FINISHED,
129- aptd_enums.STATUS_LOADING_CACHE: pk.StatusEnum.LOADING_CACHE,
130- aptd_enums.STATUS_RESOLVING_DEP: pk.StatusEnum.DEP_RESOLVE,
131- aptd_enums.STATUS_RUNNING: pk.StatusEnum.RUNNING,
132- aptd_enums.STATUS_WAITING_LOCK: pk.StatusEnum.WAITING_FOR_LOCK,
133- aptd_enums.STATUS_WAITING_MEDIUM: pk.StatusEnum.UNKNOWN,
134- aptd_enums.STATUS_WAITING_CONFIG_FILE_PROMPT: pk.StatusEnum.UNKNOWN}
135-
136-MAP_ERROR_ENUM = {
137- aptd_enums.ERROR_CACHE_BROKEN: pk.ErrorEnum.NO_CACHE,
138- aptd_enums.ERROR_DEP_RESOLUTION_FAILED: (
139- pk.ErrorEnum.DEP_RESOLUTION_FAILED),
140- aptd_enums.ERROR_INCOMPLETE_INSTALL: pk.ErrorEnum.NO_CACHE,
141- aptd_enums.ERROR_INVALID_PACKAGE_FILE: (
142- pk.ErrorEnum.PACKAGE_CORRUPT),
143- aptd_enums.ERROR_KEY_NOT_INSTALLED: pk.ErrorEnum.GPG_FAILURE,
144- aptd_enums.ERROR_KEY_NOT_REMOVED: pk.ErrorEnum.GPG_FAILURE,
145- aptd_enums.ERROR_NOT_REMOVE_ESSENTIAL_PACKAGE: (
146- pk.ErrorEnum.PACKAGE_FAILED_TO_REMOVE),
147- aptd_enums.ERROR_NO_CACHE: pk.ErrorEnum.NO_CACHE,
148- aptd_enums.ERROR_NO_LOCK: pk.ErrorEnum.CANNOT_GET_LOCK,
149- aptd_enums.ERROR_NO_PACKAGE: pk.ErrorEnum.PACKAGE_NOT_FOUND,
150- aptd_enums.ERROR_PACKAGE_ALREADY_INSTALLED: (
151- pk.ErrorEnum.PACKAGE_ALREADY_INSTALLED),
152- aptd_enums.ERROR_PACKAGE_DOWNLOAD_FAILED: (
153- pk.ErrorEnum.PACKAGE_DOWNLOAD_FAILED),
154- aptd_enums.ERROR_PACKAGE_MANAGER_FAILED: (
155- pk.ErrorEnum.TRANSACTION_ERROR),
156- aptd_enums.ERROR_PACKAGE_NOT_INSTALLED: (
157- pk.ErrorEnum.PACKAGE_NOT_INSTALLED),
158- aptd_enums.ERROR_PACKAGE_UNAUTHENTICATED: (
159- pk.ErrorEnum.BAD_GPG_SIGNATURE),
160- aptd_enums.ERROR_PACKAGE_UPTODATE: (
161- pk.ErrorEnum.NO_PACKAGES_TO_UPDATE),
162- aptd_enums.ERROR_REPO_DOWNLOAD_FAILED: (
163- pk.ErrorEnum.REPO_NOT_AVAILABLE),
164- aptd_enums.ERROR_UNREADABLE_PACKAGE_FILE: (
165- pk.ErrorEnum.INVALID_PACKAGE_FILE),
166- aptd_enums.ERROR_SYSTEM_ALREADY_UPTODATE: (
167- pk.ErrorEnum.NO_PACKAGES_TO_UPDATE),
168- aptd_enums.ERROR_NOT_AUTHORIZED: pk.ErrorEnum.NOT_AUTHORIZED,
169- aptd_enums.ERROR_AUTH_FAILED: pk.ErrorEnum.NOT_AUTHORIZED}
170-
171-MAP_PACKAGE_ENUM = {
172- aptd_enums.PKG_CONFIGURING: pk.InfoEnum.INSTALLING,
173- aptd_enums.PKG_DISAPPEARING: pk.InfoEnum.UNKNOWN,
174- aptd_enums.PKG_INSTALLED: pk.InfoEnum.FINISHED,
175- aptd_enums.PKG_INSTALLING: pk.InfoEnum.INSTALLING,
176- aptd_enums.PKG_PREPARING_INSTALL: pk.InfoEnum.PREPARING,
177- aptd_enums.PKG_PREPARING_PURGE: pk.InfoEnum.PREPARING,
178- aptd_enums.PKG_PREPARING_REMOVE: pk.InfoEnum.PREPARING,
179- aptd_enums.PKG_PURGED: pk.InfoEnum.FINISHED,
180- aptd_enums.PKG_PURGING: pk.InfoEnum.REMOVING,
181- aptd_enums.PKG_REMOVED: pk.InfoEnum.FINISHED,
182- aptd_enums.PKG_REMOVING: pk.InfoEnum.REMOVING,
183- aptd_enums.PKG_RUNNING_TRIGGER: pk.InfoEnum.CLEANUP,
184- aptd_enums.PKG_UNKNOWN: pk.InfoEnum.UNKNOWN,
185- aptd_enums.PKG_UNPACKING: pk.InfoEnum.DECOMPRESSING,
186- aptd_enums.PKG_UPGRADING: pk.InfoEnum.UPDATING}
187-
188-MAP_POLICY = {
189- "org.freedesktop.packagekit.cancel-foreign": (
190- policykit1.PK_ACTION_CANCEL_FOREIGN),
191- "org.freedesktop.packagekit.package-install": (
192- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
193- "org.freedesktop.packagekit.package-install-untrusted": (
194- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
195- "org.freedesktop.packagekit.system-trust-signing-key": (
196- policykit1.PK_ACTION_CHANGE_REPOSITORY),
197- "org.freedesktop.packagekit.package-eula-accept": (
198- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
199- "org.freedesktop.packagekit.package-remove": (
200- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
201- "org.freedesktop.packagekit.system-update": (
202- policykit1.PK_ACTION_UPGRADE_PACKAGES),
203- "org.freedesktop.packagekit.system-sources-configure": (
204- policykit1.PK_ACTION_CHANGE_REPOSITORY),
205- "org.freedesktop.packagekit.system-sources-refresh": (
206- policykit1.PK_ACTION_UPDATE_CACHE),
207- "org.freedesktop.packagekit.system-network-proxy-configure": (
208- policykit1.PK_ACTION_SET_PROXY),
209- "org.freedesktop.packagekit.device-rebind": (
210- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
211- "org.freedesktop.packagekit.upgrade-system": (
212- policykit1.PK_ACTION_UPGRADE_PACKAGES),
213- "org.freedesktop.packagekit.repair-system": (
214- policykit1.PK_ACTION_INSTALL_OR_REMOVE_PACKAGES),
215- "org.freedesktop.packagekit.trigger-offline-update": (
216- policykit1.PK_ACTION_UPGRADE_PACKAGES),
217- "org.freedesktop.packagekit.clear-offline-update": (
218- policykit1.PK_ACTION_UPGRADE_PACKAGES)}
219-
220-
221-class PackageKit(core.DBusObject):
222-
223- """Provides a limited set of the PackageKit system D-Bus API."""
224-
225- def __init__(self, queue, connect=True, bus=None):
226- """Initialize a new PackageKit compatibility layer.
227-
228- Keyword arguments:
229- connect -- if the daemon should connect to the D-Bus (default is True)
230- bus -- the D-Bus to connect to (defaults to the system bus)
231- """
232- pklog.info("Initializing PackageKit compat layer")
233- bus_name = None
234- bus_path = None
235- if connect is True:
236- if bus is None:
237- bus = dbus.SystemBus()
238- self.bus = bus
239- bus_path = PACKAGEKIT_DBUS_PATH
240- bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, self.bus)
241- core.DBusObject.__init__(self, bus_name, bus_path)
242- self._updates_changed_timeout_id = None
243- self._updates_changed = False
244- self.queue = queue
245- self.queue.worker.connect("transaction-done",
246- self._on_transaction_done)
247- self.queue.connect("queue-changed", self._on_queue_changed)
248- self._distro_id = None
249- self.netmon = networking.get_network_monitor()
250- self.netmon.connect("network-state-changed",
251- self._on_network_state_changed)
252- self._get_network_state()
253-
254- @inline_callbacks
255- def _get_network_state(self):
256- """Helper to defer the network state checking."""
257- yield self.netmon.get_network_state()
258-
259- # SIGNALS
260-
261- # pylint: disable-msg=C0103,C0322
262- @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
263- signature="")
264- def RestartSchedule(self):
265- """A system restart has been sceduled."""
266- pass
267-
268- # pylint: disable-msg=C0103,C0322
269- @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
270- signature="as")
271- def TransactionListChanged(self, transactions):
272- """The transaction list has changed, because either a transaction
273- has finished or a new transaction created.
274-
275- :param transactions: A list of transaction ID's.
276- :type transactions: as
277- """
278- pklog.debug("Emitting TransactionListChanged signal: %s", transactions)
279-
280- # pylint: disable-msg=C0103,C0322
281- @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
282- signature="")
283- def UpdatesChanged(self):
284- """This signal is emitted when the number of updates has changed."""
285- pklog.debug("Emitting UpdatesChanged signal")
286-
287- # pylint: disable-msg=C0103,C0322
288- @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
289- signature="")
290- def RepoListChanged(self):
291- """This signal is emitted when the repository list has changed."""
292- pass
293-
294- # pylint: disable-msg=C0103,C0322
295- @dbus.service.signal(dbus_interface=PACKAGEKIT_DBUS_INTERFACE,
296- signature="")
297- def Changed(self):
298- """This signal is emitted when a property on the interface changes."""
299- pklog.debug("Emitting PackageKit Changed()")
300-
301- # METHODS
302-
303- # pylint: disable-msg=C0103,C0322
304- @dbus_deferred_method(PACKAGEKIT_DBUS_INTERFACE,
305- in_signature="s", out_signature="u",
306- sender_keyword="sender")
307- def CanAuthorize(self, action_id, sender):
308- """Allows a client to find out if it would be allowed to authorize
309- an action.
310-
311- :param action_id: The action ID, e.g.
312- org.freedesktop.packagekit.system-network-proxy-configure
313- :returns: The result, either yes, no or interactive.
314- """
315- pklog.info("CanAuthorize() was called: %s", str(action_id))
316- return self._can_authorize(action_id, sender)
317-
318- @inline_callbacks
319- def _can_authorize(self, action_id, sender):
320- try:
321- action_id_aptd = MAP_POLICY[action_id]
322- except KeyError:
323- return_value(pk.AuthorizeEnum.UNKNOWN)
324- try:
325- policykit1.check_authorization_by_name(
326- self, action_id, flags=policykit1.CHECK_AUTH_NONE)
327- except policykit1.NotAuthorizedError:
328- return_value(pk.AuthorizeEnum.NO)
329- except policykit1.AuthorizationFailed:
330- # check_authorization_* behaves a little bit different if the
331- # flags are set to NONE instead of INTERACTIVE
332- return_value(pk.AuthorizeEnum.INTERACTIVE)
333- except:
334- return_value(pk.AuthorizeEnum.UNKNOWN)
335- return_value(pk.AuthorizeEnum.YES)
336-
337- # pylint: disable-msg=C0103,C0322
338- @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
339- in_signature="s", out_signature="")
340- def StateHasChanged(self, reason):
341- """This method suggests to PackageKit that the package backend state
342- may have changed. This allows plugins to the native package manager
343- to suggest that PackageKit drops it's caches.
344-
345- :param reason:
346- The reason of the state change. Valid reasons are resume or
347- posttrans. Resume is given a lower priority than posttrans.
348- """
349- pklog.info("StateHasChanged() was called: %s", str(reason))
350- self._updates_changed = True
351- if reason == "cache-update":
352- self._check_updates_changed(timeout=30)
353- elif reason == "resume":
354- self._check_updates_changed(timeout=180)
355-
356- # pylint: disable-msg=C0103,C0322
357- @dbus_deferred_method(PACKAGEKIT_DBUS_INTERFACE,
358- in_signature="", out_signature="o",
359- sender_keyword="sender")
360- def CreateTransaction(self, sender):
361- """Gets a new transaction ID from the daemon.
362-
363- :returns: The tid, e.g. 45_dafeca_checkpoint32
364- """
365- pklog.info("CreateTransaction() was called")
366- return self._create_transaction(sender)
367-
368- @inline_callbacks
369- def _create_transaction(self, sender):
370- pid, uid, gid, cmdline = yield policykit1.get_proc_info_from_dbus_name(
371- sender, self.bus)
372- pktrans = PackageKitTransaction(
373- pid, uid, gid, cmdline, self.queue, sender)
374- return_value(pktrans.tid)
375-
376- # pylint: disable-msg=C0103,C0322
377- @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
378- in_signature="", out_signature="s")
379- def GetDaemonState(self):
380- """Return the state of the currently running transactions."""
381- pklog.info("GetDaemonState() was called")
382- # FIXME: Add some useful data here
383- return "All is fine!"
384-
385- # pylint: disable-msg=C0103,C0322
386- @dbus.service.method(PACKAGEKIT_DBUS_INTERFACE,
387- in_signature="", out_signature="ao")
388- def GetTransactionList(self):
389- """Gets the transaction list of any transactions that are in
390- progress.
391-
392- :returns: A list of transaction ID's
393- """
394- pklog.info("GetTransactionList() was called")
395- return self._get_transaction_list()
396-
397- # HELPERS
398-
399- def _get_properties(self, iface):
400- """Helper to get the properties of a D-Bus interface."""
401- if iface == PACKAGEKIT_DBUS_INTERFACE:
402- return {
403- # Claim that we are a current version
404- "VersionMajor": dbus.UInt32(0),
405- "VersionMinor": dbus.UInt32(8),
406- "VersionMicro": dbus.UInt32(9),
407- "BackendName": dbus.String("aptdaemon"),
408- "BackendDescription": dbus.String("Compatibility layer"),
409- "BackendAuthor": dbus.String(__author__),
410- "Groups": dbus.UInt64(self.queue.worker.groups),
411- "Provides": dbus.UInt64(self.queue.worker.provides),
412- "Filters": dbus.UInt64(self.queue.worker.filters),
413- "Roles": dbus.UInt64(self.queue.worker.roles),
414- "MimeTypes": dbus.Array(self.queue.worker.mime_types,
415- signature="s"),
416- "Locked": dbus.Boolean(False),
417- "NetworkState": dbus.UInt32(self.netmon.state),
418- "DistroId": dbus.String(self._get_distro_id())}
419- else:
420- return {}
421-
422- def _get_distro_id(self):
423- """Return information about the distibution."""
424- if self._distro_id is None:
425- distro, version, _codename = platform.dist()
426- self._distro_id = "%s;%s;%s" % (distro or "unknown",
427- version or "unknown",
428- NATIVE_ARCH)
429- return self._distro_id
430-
431- def _on_network_state_changed(self, mon, state):
432- self.Changed()
433- self.PropertiesChanged(PACKAGEKIT_DBUS_INTERFACE,
434- {"NetworkState": dbus.UInt32(state)}, [])
435-
436- def _on_queue_changed(self, queue):
437- self.TransactionListChanged(self._get_transaction_list())
438- self._check_updates_changed()
439-
440- def _get_transaction_list(self):
441- pk_transactions = []
442- for trans in self.queue.items:
443- # We currently only emit PackageKit transaction
444- # FIXME: Should we use MergedTransaction for all transactions and
445- # ROLE_UNKOWN for aptdaemon only transactions?
446- try:
447- pk_transactions.append(trans.pktrans.tid)
448- except AttributeError:
449- pass
450- try:
451- pk_transactions.append(self.queue.worker.trans.pktrans.tid)
452- except AttributeError:
453- pass
454- return pk_transactions
455-
456- def _on_transaction_done(self, worker, trans):
457- # If a cache modifing transaction is completed schedule an
458- # UpdatesChanged signal
459- if trans.role in (aptd_enums.ROLE_INSTALL_FILE,
460- aptd_enums.ROLE_INSTALL_PACKAGES,
461- aptd_enums.ROLE_REMOVE_PACKAGES,
462- aptd_enums.ROLE_UPGRADE_PACKAGES,
463- aptd_enums.ROLE_COMMIT_PACKAGES,
464- aptd_enums.ROLE_UPGRADE_SYSTEM,
465- aptd_enums.ROLE_FIX_BROKEN_DEPENDS):
466- self._updates_changed = True
467- self._check_updates_changed()
468- elif trans.role == aptd_enums.ROLE_UPDATE_CACHE:
469- self._updates_changed = True
470- self._check_updates_changed(timeout=30)
471-
472- def _check_updates_changed(self, timeout=60):
473- """After the queue was processed schedule a delayed UpdatesChanged
474- signal if required.
475- """
476- if not self.queue.items and self._updates_changed:
477- if self._updates_changed_timeout_id:
478- # If we already have a scheduled UpdatesChanged signal
479- # delay it even further
480- pklog.debug("UpdatesChanged signal re-scheduled")
481- GLib.source_remove(self._updates_changed_timeout_id)
482- else:
483- pklog.debug("UpdatesChanged signal scheduled")
484- self._updates_changed_timeout_id = \
485- GLib.timeout_add_seconds(timeout,
486- self._delayed_updates_changed)
487-
488- def _delayed_updates_changed(self):
489- """Emit the UpdatesChanged signal and clear the timeout."""
490- self.UpdatesChanged()
491- self._updates_changed_timeout_id = None
492- self._updates_changed = False
493- return False
494-
495-
496-class MergedTransaction(core.Transaction):
497-
498- """Overlay of an Aptdaemon transaction which also provides the
499- PackageKit object and its interfaces.
500- """
501-
502- def __init__(self, pktrans, role, queue, connect=True,
503- bus=None, packages=None, kwargs=None):
504- core.Transaction.__init__(self, pktrans.tid[1:], role, queue,
505- pktrans.pid, pktrans.uid, pktrans.gid,
506- pktrans.cmdline, pktrans.sender,
507- connect, bus, packages, kwargs)
508- self.pktrans = pktrans
509- self.run_time = 0
510-
511- @inline_callbacks
512- def _run(self, sender):
513- """Run the transaction and convert exceptions to PackageKit ones."""
514- try:
515- yield core.Transaction._run(self, sender)
516- except (TransactionFailed, errors.NotAuthorizedError,
517- errors.AuthorizationFailed):
518- # It is sufficient for PackageKit if the exit state and error
519- # code of the transaction are set. So silently drop the execp
520- if self.error:
521- pass
522- except Exception as error:
523- raise error
524-
525- @inline_callbacks
526- def _check_auth(self):
527- """Override the auth method to allow simulates without any
528- authorization.
529- """
530- if bitfield_contains(self.pktrans.flags,
531- pk.TransactionFlagEnum.SIMULATE):
532- raise StopIteration
533- else:
534- yield core.Transaction._check_auth(self)
535-
536- @inline_callbacks
537- def _check_simulated(self):
538- """Skip simulate calls for simulated transactions."""
539- if bitfield_contains(self.pktrans.flags,
540- pk.TransactionFlagEnum.SIMULATE):
541- raise StopIteration
542- else:
543- yield core.Transaction._check_simulated(self)
544-
545- def _set_status(self, enum):
546- core.Transaction._set_status(self, enum)
547- self.pktrans.status = get_pk_status_enum(enum)
548-
549- status = property(core.Transaction._get_status, _set_status)
550-
551- def _set_progress(self, percent):
552- core.Transaction._set_progress(self, percent)
553- self.pktrans.percentage = self._progress
554-
555- progress = property(core.Transaction._get_progress, _set_progress)
556-
557- def _set_progress_details(self, details):
558- core.Transaction._set_progress_details(self, details)
559- self.pktrans.download_size_remaing = int(details[3]) - int(details[2])
560- self.pktrans.speed = int(details[4])
561- self.pktrans.remaining_time = int(details[5])
562- self.pktrans.elapsed_time = int(time.time() - self.pktrans.start_time)
563-
564- progress_details = property(core.Transaction._get_progress_details,
565- _set_progress_details)
566-
567- def _set_progress_package(self, progress):
568- core.Transaction._set_progress_package(self, progress)
569- pkg_name, enum = progress
570- # Ignore dpkg triggers
571- if enum == aptd_enums.PKG_RUNNING_TRIGGER or pkg_name == "dpkg-exec":
572- return
573- try:
574- id = self.pktrans.pkg_id_cache[pkg_name]
575- except KeyError:
576- id = get_pk_package_id(pkg_name)
577- self.emit_package(get_pk_package_enum(enum), id, "")
578-
579- progress_package = property(core.Transaction._get_progress_package,
580- _set_progress_package)
581-
582- def _set_progress_download(self, progress_download):
583- core.Transaction._set_progress_download(self, progress_download)
584- prog_enum = progress_download[1]
585- prog_name = progress_download[2]
586- total_size = progress_download[3]
587- partial_size = progress_download[4]
588-
589- try:
590- id = self.pktrans.pkg_id_cache[prog_name]
591- except KeyError:
592- return
593- self.pktrans.Package(pk.InfoEnum.DOWNLOADING, id, "")
594- if prog_enum == aptd_enums.DOWNLOAD_IDLE:
595- percentage = 0
596- elif prog_enum == aptd_enums.DOWNLOAD_FETCHING and total_size > 0:
597- percentage = partial_size * 100 / total_size
598- elif prog_enum == aptd_enums.DOWNLOAD_DONE:
599- percentage = 100
600- else:
601- # In the case of an error
602- percentage = 0
603- self.pktrans.ItemProgress(id, pk.InfoEnum.DOWNLOADING, percentage)
604-
605- progress_download = property(core.Transaction._get_progress_download,
606- _set_progress_download)
607-
608- def _set_exit(self, enum):
609- core.Transaction._set_exit(self, enum)
610- self.pktrans.exit = get_pk_exit_enum(enum)
611-
612- exit = property(core.Transaction._get_exit, _set_exit)
613-
614- def _set_error(self, excep):
615- core.Transaction._set_error(self, excep)
616- self.pktrans.ErrorCode(get_pk_error_enum(excep.code),
617- self._error_property[1])
618-
619- error = property(core.Transaction._get_error, _set_error)
620-
621- def _remove_from_connection_no_raise(self):
622- core.Transaction._remove_from_connection_no_raise(self)
623- self.pktrans.Destroy()
624- try:
625- self.pktrans.remove_from_connection()
626- except LookupError as error:
627- pklog.debug("remove_from_connection() raised LookupError: %s",
628- error)
629- finally:
630- self.pktrans.trans = None
631- self.pktrans = None
632- return False
633-
634- def emit_details(self, package_id, license, group, detail, url, size):
635- self.pktrans.Details(package_id, license, group, detail, url, size)
636-
637- def emit_files(self, id, file_list):
638- self.pktrans.Files(id, file_list)
639-
640- def emit_package(self, info, id, summary):
641- if id.startswith("dpkg-exec;"):
642- # PackageKit would show a non existing package
643- pklog.debug("Don't emit Package() signal for the dpkg trigger")
644- return
645- self.pktrans.Package(info, id, summary)
646- self.pktrans.last_package = id
647-
648- def emit_update_detail(self, package_id, updates, obsoletes, vendor_urls,
649- bugzilla_urls, cve_urls, restart, update_text,
650- changelog, state, issued, updated):
651- self.pktrans.UpdateDetail(package_id, updates, obsoletes, vendor_urls,
652- bugzilla_urls, cve_urls, restart,
653- update_text, changelog, state, issued,
654- updated)
655-
656-
657-class PackageKitTransaction(core.DBusObject):
658-
659- """Provides a PackageKit transaction object."""
660-
661- def __init__(self, pid, uid, gid, cmdline, queue, sender,
662- connect=True, bus=None):
663- pklog.info("Initializing PackageKit transaction")
664- bus_name = None
665- bus_path = None
666- self.tid = "/%s" % uuid.uuid4().hex
667- if connect is True:
668- if bus is None:
669- bus = dbus.SystemBus()
670- self.bus = bus
671- bus_path = self.tid
672- bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus)
673- core.DBusObject.__init__(self, bus_name, bus_path)
674- self.queue = queue
675- self.hints = {}
676- self.start_time = time.time()
677- self._elapsed_time = dbus.UInt32(0)
678- self._remaining_time = dbus.UInt32(0)
679- self._download_size_remaining = dbus.UInt64(0)
680- self._speed = dbus.UInt32(0)
681- self._caller_active = True
682- self._allow_cancel = False
683- self._percentage = dbus.UInt32(0)
684- self._status = pk.StatusEnum.SETUP
685- self._last_package = ""
686- self.uid = dbus.UInt32(uid)
687- self.gid = dbus.UInt32(gid)
688- self.pid = pid
689- self.cmdline = cmdline
690- self.role = pk.RoleEnum.UNKNOWN
691- self.sender = sender
692- self.trans = None
693- self.flags = pk.TransactionFlagEnum.NONE
694- self.pkg_id_cache = {}
695-
696- @property
697- def allow_cancel(self):
698- return self._allow_cancel
699-
700- @allow_cancel.setter
701- def allow_cancel(self, value):
702- self._allow_cancel = dbus.Boolean(value)
703- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
704- {"AllowCancel": self._allow_cancel}, [])
705- self.Changed()
706-
707- @property
708- def last_package(self):
709- return self._last_package
710-
711- @last_package.setter
712- def last_package(self, value):
713- self._last_package = dbus.String(value)
714- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
715- {"LastPackage": self._last_package}, [])
716- self.Changed()
717-
718- @property
719- def caller_active(self):
720- return self._caller_active
721-
722- @caller_active.setter
723- def caller_active(self, value):
724- self._caller_active = dbus.Boolean(value)
725- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
726- {"CallerActive": self._caller_active}, [])
727- self.Changed()
728-
729- @property
730- def percentage(self):
731- return self._percentage
732-
733- @percentage.setter
734- def percentage(self, progress):
735- self._percentage = dbus.UInt32(progress)
736- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
737- {"Percentage": self._percentage}, [])
738- self.Changed()
739-
740- @property
741- def status(self):
742- return self._status
743-
744- @status.setter
745- def status(self, enum):
746- self._status = dbus.UInt32(enum)
747- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
748- {"Status": self._status}, [])
749- self.Changed()
750-
751- @property
752- def elapsed_time(self):
753- return self._elapsed_time
754-
755- @elapsed_time.setter
756- def elapsed_time(self, ela):
757- self._elpased_time = dbus.UInt32(ela)
758- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
759- {"ElapsedTime": self._elapsed_time}, [])
760- self.Changed()
761-
762- @property
763- def remaining_time(self):
764- return self._remaining_time
765-
766- @remaining_time.setter
767- def remaining_time(self, value):
768- self._remaining_time = dbus.UInt32(value)
769- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
770- {"RemainingTime": self._remaining_time}, [])
771- self.Changed()
772-
773- @property
774- def download_size_remaining(self):
775- return self._download_size_remaining
776-
777- @download_size_remaining.setter
778- def download_size_remaining(self, value):
779- self._download_size_remaining = dbus.UInt64(value)
780- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
781- {"DownloadSizeRemaining":
782- self._download_size_remaining}, [])
783- self.Changed()
784-
785- @property
786- def speed(self):
787- return self._speed
788-
789- @speed.setter
790- def speed(self, speed):
791- self._speed = dbus.UInt32(speed)
792- self.PropertiesChanged(PACKAGEKIT_TRANS_DBUS_INTERFACE,
793- {"Speed": self._speed}, [])
794- self.Changed()
795-
796- @property
797- def exit(self):
798- return self._exit
799-
800- @exit.setter
801- def exit(self, enum):
802- self._exit = enum
803- self.run_time = int((time.time() - self.start_time) * 1000)
804- # The time could go backwards ...
805- if self.run_time < 0:
806- self.run_time = 0
807- if enum == pk.ExitEnum.CANCELLED:
808- self.ErrorCode(pk.ErrorEnum.TRANSACTION_CANCELLED, "")
809- self.status = pk.StatusEnum.FINISHED
810- self.Finished(enum, self.run_time)
811-
812- # SIGNALS
813-
814- # pylint: disable-msg=C0103,C0322
815- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
816- signature="osbuusus")
817- def Transaction(self, object_path, timespec, succeeded, role, duration,
818- data, uid, cmdline):
819- """This signal is sent when more details are required about a
820- specific transaction.
821-
822- :param object_path: The transaction ID of the old transaction.
823- :param timespec: The timespec of the old transaction in ISO8601 format.
824- :param succeeded: If the transaction succeeded.
825- :param role: The role enumerated type.
826- :param duration: The duration of the transaction in milliseconds.
827- :param data: Any data associated
828- :param uid: The user ID of the user that scheduled the action.
829- :param cmdline: The command line of the tool that scheduled the action,
830- e.g. /usr/bin/gpk-application.
831- """
832- pklog.debug("Emitting Transaction signal: %s, %s, %s, %s, %s, %s, "
833- "%s, %s", object_path, timespec, succeeded,
834- pk.role_enum_to_string(role), duration, data, uid,
835- cmdline)
836-
837- # pylint: disable-msg=C0103,C0322
838- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
839- signature="us")
840- def ErrorCode(self, code, details):
841- """This signal is used to report errors back to the session program.
842- Errors should only be send on fatal abort.
843-
844- :param code: Enumerated type, e.g. no-network.
845- :param details: Long description or error, e.g. "failed to connect"
846-
847- :type code: u
848- :type details: s
849- """
850- pklog.debug("Emitting ErrorCode signal: %s, %s",
851- pk.error_enum_to_string(code), details)
852-
853- # pylint: disable-msg=C0103,C0322
854- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
855- signature="")
856- def Changed(self):
857- """This signal is emitted when a property on the interface changes."""
858- pklog.debug("Emitting Changed signal")
859-
860- # pylint: disable-msg=C0103,C0322
861- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
862- signature="")
863- def Destroy(self):
864- """This signal is sent when the transaction has been destroyed
865- and is no longer available for use."""
866- pklog.debug("Emitting Destroy signal")
867-
868- # pylint: disable-msg=C0103,C0322
869- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
870- signature="uu")
871- def Finished(self, exit_enum, runtime):
872- """This signal is used to signal that the transaction has finished.
873- :param exit: The PkExitEnum describing the exit status of the
874- transaction.
875- :param runtime: The amount of time in milliseconds that the
876- transaction ran for.
877-
878- :type exit: s
879- :type runtime: u
880- """
881- pklog.debug("Emitting Finished signal: %s, %s",
882- pk.exit_enum_to_string(exit_enum), runtime)
883- pass
884-
885- # pylint: disable-msg=C0103,C0322
886- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
887- signature="ssusst")
888- def Details(self, package_id, license, group, detail, url, size):
889- """This signal allows the backend to convey more details about the
890- package.
891-
892- :param package_id: The package ID
893-
894- :param license:
895- The license string, e.g. GPLv2+ or BSD and (MPLv1.1 or GPLv2+).
896- Moredetails about the correct way to format licensing strings can
897- be found on the Fedora packaging wiki.
898- :param group:
899- The enumerated package group description
900- :param detail:
901- The multi-line package description. If formatting is required,
902- then markdown syntax should be used, e.g. This is **critically**
903- important
904- :param url:
905- The upstream project homepage
906- :param size:
907- The size of the package in bytes. This should be the size of the
908- entire package file, not the size of the files installed on the
909- system. If the package is not installed, and already downloaded
910- and present in the package manager cache, then this value should
911- be set to zero.
912- """
913- pklog.debug("Emitting Details signal for %s", package_id)
914-
915- # pylint: disable-msg=C0103,C0322
916- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
917- signature="us")
918- def Message(self, kind, details):
919- """This signal is sent when the backend wants to send a message to
920- the session.
921-
922- The message will be shown after the transaction has been completed.
923- """
924- pklog.debug("Emitting Message signal: %s, %s", kind, details)
925-
926- # pylint: disable-msg=C0103,C0322
927- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
928- signature="sas")
929- def Files(self, package_id, file_list):
930- """This signal is used to push file lists from the backend to the
931- session.
932-
933- :param package_id:
934- The Package ID that called the method.
935- :param file_list:
936- The file list
937- """
938- pklog.debug("Emitting Files signal: %s, %s", package_id, file_list)
939-
940- # pylint: disable-msg=C0103,C0322
941- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
942- signature="suu")
943- def ItemProgress(self, package_id, status, percentage):
944- """This signal allows the backend to send information about
945- package or repository progress when using Simultanous mode.
946-
947- :param package_id: The package ID
948- :param status:
949- The status enumerated value that is being completed
950- :param percentage:
951- The percentage of this action is completed
952- """
953- pklog.debug("Emitting ItemProgress signal for %s: %s, %s",
954- package_id, pk.info_enum_to_string(status), percentage)
955-
956- # pylint: disable-msg=C0103,C0322
957- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
958- signature="sasasasasasussuss")
959- def UpdateDetail(self, package_id, updates, obsoletes, vendor_urls,
960- bugzilla_urls, cve_urls, restart, update_text, changelog,
961- state, issued, updated):
962- """This signal is sent when more details are required about a
963- specific update.
964-
965- :param package_id: The package ID
966- :param updates:
967- A list of package_id's that are to be updated.
968- :param obsoletes:
969- A list of package_id's that are to be obsoleted.
970- :param vendor_urls:
971- A URL with more details on the update, e.g. a page with more
972- information on the update. The format of this command should
973- be http://www.foo.org/page.html?4567;Update to SELinux
974- :param bugzilla_urls:
975- A bugzilla URL with more details on the update. If no URL is
976- available then this field should be left empty.
977- :param cve_urls:
978- A CVE URL with more details on the security advisory.
979- :param restart:
980- A valid restart type, e.g. system.
981- :param update_text:
982- The update text describing the update. If formatting is required,
983- then markdown syntax should be used, e.g. This is **critically**
984- important.
985- :param changelog:
986- The ChangeLog text describing the changes since the last version.
987- :param state:
988- The state of the update, e.g. stable or testing.
989- :param issued:
990- The ISO8601 encoded date that the update was issued.
991- :param updated:
992- The ISO8601 encoded date that the update was updated.
993- """
994- pklog.debug("Emitting UpdateDetail signal for %s", package_id)
995-
996- # pylint: disable-msg=C0103,C0322
997- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
998- signature="uss")
999- def Package(self, info, package_id, summary):
1000- """This signal allows the backend to communicate packages to the
1001- session.
1002-
1003- If updating, as packages are updated then emit them to the screen.
1004- This allows a summary to be presented after the transaction.
1005- When returning results from a search always return installed
1006- before available for the same package name.
1007-
1008- :param info: A valid info enumerated type
1009- :param package_id: This identifier is of the form
1010- name;version;arch;data in a single string and is meant to
1011- represent a single package unique across all local and remote
1012- data stores. For a remote, not-installed package the data
1013- field should be set as the repository identifier or repository
1014- name. The data field for an installed package must be prefixed
1015- with installed as this is used to identify which packages are
1016- installable or installed in the client tools. As a special
1017- extension, if the package manager is able to track which
1018- repository a package was originally installed from, then the data
1019- field can be set to installed:REPO-NAME which allows the frontend
1020- client to advise the user of the package origin. The data field
1021- for a non-installed local package must be local as this signifies
1022- a repository name is not available and that package resides
1023- locally on the client system rather than in any specific
1024- repository.
1025- :param summary: The one line package summary, e.g. Clipart for
1026- OpenOffice
1027- """
1028- pklog.debug("Emitting Package signal: %s, %s, %s'",
1029- pk.info_enum_to_string(info), package_id, summary[:10])
1030-
1031- # pylint: disable-msg=C0103,C0322
1032- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
1033- signature="sss")
1034- def DistroUpgrade(self, distro_type, name, summary):
1035- """This signal allows the backend to communicate distribution upgrades
1036- to the session.
1037- :param type: A valid upgrade string enumerated type, e.g. stable
1038- or unstable
1039- :param name: The short name of the distribution, e.g. Fedora Core
1040- 10 RC1
1041- :param summary: The multi-line description of the release
1042- """
1043- pklog.debug("Emitting DistroUpgrade signal: %s, %s, %s",
1044- pk.distro_upgrade_enum_to_string(distro_type),
1045- name, summary)
1046-
1047- # pylint: disable-msg=C0103,C0322
1048- @dbus.service.signal(dbus_interface=PACKAGEKIT_TRANS_DBUS_INTERFACE,
1049- signature="us")
1050- def RequireRestart(self, restart_type, package_id):
1051- """This signal is sent when the session client should notify the user
1052- that a restart is required to get all changes into effect.
1053-
1054- :param package_id:
1055- The Package ID of the package tiggering the restart
1056- :param file_list:
1057- One of system, application or session
1058- """
1059- pklog.debug("Emitting RequireRestart signal: %s, %s",
1060- pk.restart_enum_to_string(restart_type), package_id)
1061-
1062- # METHODS
1063-
1064- # pylint: disable-msg=C0103,C0322
1065- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1066- in_signature="as", out_signature="")
1067- def SetHints(self, hints):
1068- """This method allows the calling session to set transaction hints
1069- for the package manager which can change as the transaction runs.
1070-
1071- This method can be sent before the transaction has been run or
1072- whilst it is running. There is no limit to the number of times
1073- this method can be sent, although some backends may only use the
1074- values that were set before the transaction was started.
1075-
1076- Each parameter value is optional.
1077-
1078- :param hints: The values as an array of strings, for example
1079- ['locale=en_GB.utf8','interactive=false','cache-age=3600']
1080- """
1081- pklog.info("SetHints() was called: %s", get_string_from_array(hints))
1082- for hint in hints:
1083- key, value = hint.split("=", 1)
1084- if key not in ["locale", "idle", "background", "interactive",
1085- "cache-age", "frontend-socket"]:
1086- raise Exception("Invalid option %s" % key)
1087- self.hints[key] = value
1088-
1089- # pylint: disable-msg=C0103,C0322
1090- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1091- in_signature="", out_signature="",
1092- sender_keyword="sender")
1093- def Cancel(self, sender):
1094- """This method cancels a transaction that is already running."""
1095- if self.trans:
1096- return self.trans._cancel(sender)
1097-
1098- # pylint: disable-msg=C0103,C0322
1099- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1100- in_signature="tasbb", out_signature="",
1101- sender_keyword="sender")
1102- def RemovePackages(self, flags, package_ids, allow_deps, autoremove,
1103- sender):
1104- """This method removes packages from the local system.
1105-
1106- This method typically emits Progress, Status and Error and Package.
1107-
1108- Package enumerated types should be downloading, updating,
1109- installing or removing.
1110-
1111- :param flags: If the transaction should be simulated or prepared
1112- :param package_ids: An array of package IDs.
1113- :param allow_deps:
1114- Either true or false. If true allow other packages to be removed
1115- with the package, but false should cause the script to abort if
1116- other packages are dependant on the package.
1117- :param autoremove:
1118- Either true or false. This option is only really interesting on
1119- embedded devices with a limited amount of flash storage. It
1120- suggests to the packagekit backend that dependencies installed at
1121- the same time as the package should also be removed if they are not
1122- required by anything else. For instance, if you install OpenOffice,
1123- it might download libneon as a dependency. When auto_remove is set
1124- to true, and you remove OpenOffice then libneon will also get
1125- removed automatically.
1126- """
1127- pklog.info("RemovePackages() was called: %s, %s",
1128- get_string_from_flags(flags),
1129- get_string_from_array(package_ids))
1130- return self._remove_packages(flags, package_ids, allow_deps,
1131- autoremove, sender)
1132-
1133- @inline_callbacks
1134- def _remove_packages(self, flags, package_ids, allow_deps, autoremove,
1135- sender):
1136- self.role = pk.RoleEnum.REMOVE_PACKAGES
1137- self.flags = flags
1138- self.trans = self._get_merged_trans(aptd_enums.ROLE_REMOVE_PACKAGES,
1139- pkg_ids=package_ids,
1140- pkg_type=aptd_enums.PKGS_REMOVE)
1141- yield self.trans._set_property(APTDAEMON_TRANSACTION_DBUS_INTERFACE,
1142- "RemoveObsoletedDepends", autoremove,
1143- sender)
1144- # FIXME: Implement allow_deps
1145- yield self.trans._run(sender)
1146-
1147- # pylint: disable-msg=C0103,C0322
1148- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1149- in_signature="tas", out_signature="",
1150- sender_keyword="sender")
1151- def UpdatePackages(self, flags, package_ids, sender):
1152- """This method updates existing packages on the local system.
1153-
1154- The installer should always update extra packages automatically
1155- to fulfil dependencies.
1156-
1157- This should allow an application to find out what package owns a
1158- file on the system.
1159-
1160- This method typically emits Progress, Status and Error and Package.
1161-
1162- :param flags:
1163- If the transaction is only allowed to install trusted packages.
1164- Unsigned packages should not be installed if the flags
1165- contains ONLY_TRUSED.
1166- If this method is can only install trusted packages, and
1167- the packages are unsigned, then the backend will send a
1168- ErrorCode(missing-gpg-signature). On recieving this error, the
1169- client may choose to retry with ONLY_TRUSTED set after
1170- gaining further authentication.
1171- : param package_ids: An array of package IDs.
1172- """
1173- pklog.info("UpdatePackages() was called: %s, %s",
1174- get_string_from_flags(flags),
1175- get_string_from_array(package_ids))
1176- return self._update_packages(flags, package_ids, sender)
1177-
1178- @inline_callbacks
1179- def _update_packages(self, flags, package_ids, sender):
1180- self.role = pk.RoleEnum.UPDATE_PACKAGES
1181- self.flags = flags
1182- self.trans = self._get_merged_trans(aptd_enums.ROLE_UPGRADE_PACKAGES,
1183- pkg_ids=package_ids,
1184- pkg_type=aptd_enums.PKGS_UPGRADE)
1185- yield self.trans._set_property(
1186- APTDAEMON_TRANSACTION_DBUS_INTERFACE,
1187- "AllowUnauthenticated",
1188- not bitfield_contains(flags,
1189- pk.TransactionFlagEnum.ONLY_TRUSTED),
1190- sender)
1191- yield self.trans._run(sender)
1192-
1193- # pylint: disable-msg=C0103,C0322
1194- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1195- in_signature="uas", out_signature="",
1196- sender_keyword="sender")
1197- def InstallPackages(self, flags, package_ids, sender):
1198- """This method installs new packages on the local system.
1199-
1200- The installer should always install extra packages automatically
1201- as the use could call GetDepends prior to the install if a
1202- confirmation is required in the UI.
1203-
1204- This method typically emits Progress, Status and Error and Package.
1205-
1206- Package enumerated types should be downloading, updating,
1207- installing or removing.
1208-
1209- :param flags:
1210- If the transaction is only allowed to install trusted packages.
1211- Unsigned packages should not be installed if the flags
1212- contains ONLY_TRUSED.
1213- If this method is can only install trusted packages, and
1214- the packages are unsigned, then the backend will send a
1215- ErrorCode(missing-gpg-signature). On recieving this error, the
1216- client may choose to retry with ONLY_TRUSTED set after
1217- gaining further authentication.
1218- : param package_ids: An array of package IDs.
1219- """
1220- pklog.info("InstallPackages() was called: %s, %s",
1221- get_string_from_flags(flags),
1222- get_string_from_array(package_ids))
1223- return self._install_packages(flags, package_ids, sender)
1224-
1225- @inline_callbacks
1226- def _install_packages(self, flags, package_ids, sender):
1227- self.role = pk.RoleEnum.INSTALL_PACKAGES
1228- self.flags = flags
1229- self.trans = self._get_merged_trans(aptd_enums.ROLE_INSTALL_PACKAGES,
1230- pkg_ids=package_ids,
1231- pkg_type=aptd_enums.PKGS_INSTALL)
1232- yield self.trans._set_property(
1233- APTDAEMON_TRANSACTION_DBUS_INTERFACE,
1234- "AllowUnauthenticated",
1235- not bitfield_contains(flags,
1236- pk.TransactionFlagEnum.ONLY_TRUSTED),
1237- sender)
1238- yield self.trans._run(sender)
1239-
1240- # pylint: disable-msg=C0103,C0322
1241- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1242- in_signature="su", out_signature="",
1243- sender_keyword="sender")
1244- def UpgradeSystem(self, distro_id, upgrade_kind, sender):
1245- """This method updates existing packages on the local system.
1246-
1247- The installer should always update extra packages automatically
1248- to fulfil dependencies.
1249-
1250- This should allow an application to find out what package owns a
1251- file on the system.
1252-
1253- This method typically emits Progress, Status and Error and Package.
1254-
1255- :param distro_id: The distribution id to upgrade to, e.g. saucy
1256- :param upgrade_kind:
1257- The type of upgrade e.g. minimal, default or complete.
1258- Minimal upgrades will download the smallest amount of data
1259- before launching a installer.
1260- The default is to download enough data to launch a full graphical
1261- installer, but a complete upgrade will be required if there is no
1262- internet access during install time.
1263- """
1264- pklog.info("UpgradeSystem() was called")
1265- GLib.idle_add(self._fail_not_implemented)
1266-
1267- # pylint: disable-msg=C0103,C0322
1268- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1269- in_signature="t", out_signature="",
1270- sender_keyword="sender")
1271- def RepairSystem(self, flags, sender):
1272- """This method recovers the package managment system from e.g.
1273- unsatisified dependencies of installed packages.
1274-
1275- :param flags:
1276- If the transaction is only allowed to install trusted packages.
1277- Unsigned packages should not be installed if the flags
1278- contains ONLY_TRUSED.
1279- If this method is can only install trusted packages, and
1280- the packages are unsigned, then the backend will send a
1281- ErrorCode(missing-gpg-signature). On recieving this error, the
1282- client may choose to retry with ONLY_TRUSTED set after
1283- gaining further authentication.
1284- """
1285- pklog.info("RepairSystem() was called")
1286- return self._repair_system(flags, sender)
1287-
1288- @inline_callbacks
1289- def _repair_system(self, flags, sender):
1290- self.role = pk.RoleEnum.REPAIR_SYSTEM
1291- self.flags = flags
1292- self.trans = self._get_merged_trans(aptd_enums.ROLE_FIX_BROKEN_DEPENDS)
1293- yield self.trans._set_property(
1294- APTDAEMON_TRANSACTION_DBUS_INTERFACE,
1295- "AllowUnauthenticated",
1296- not bitfield_contains(flags,
1297- pk.TransactionFlagEnum.ONLY_TRUSTED),
1298- sender)
1299- yield self.trans._run(sender)
1300-
1301- # pylint: disable-msg=C0103,C0322
1302- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1303- in_signature="b", out_signature="",
1304- sender_keyword="sender")
1305- def RefreshCache(self, force, sender):
1306- """This method should fetch updated meta-data for all enabled
1307- repositories.
1308-
1309- When fetching each software source, ensure to emit RepoDetail for
1310- the current source to give the user interface some extra details.
1311- Be sure to have the "enabled" field set to true, otherwise you
1312- wouldn't be fetching that source.
1313-
1314- This method typically emits Progress, Error and RepoDetail.
1315-
1316- :param force: If the caches should be cleaned and reloaded even if
1317- there is valid, up to date data.
1318- """
1319- pklog.info("RefreshCache() was called")
1320- self.role = pk.RoleEnum.REFRESH_CACHE
1321- return self._refresh_cache(force, sender)
1322-
1323- @inline_callbacks
1324- def _refresh_cache(self, force, sender):
1325- self.trans = self._get_merged_trans(aptd_enums.ROLE_UPDATE_CACHE,
1326- kwargs={"sources_list": None})
1327- yield self.trans._run(sender)
1328-
1329- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1330- in_signature="as", out_signature="",
1331- sender_keyword="sender")
1332- def GetUpdateDetail(self, package_ids, sender):
1333- """This method returns details about a specific update.
1334-
1335- This method typically emits UpdateDetail and Error
1336-
1337- :param package_ids: An array of package IDs.
1338- """
1339- pklog.info("GetUpdateDetail() was called")
1340- self.role = pk.RoleEnum.GET_UPDATE_DETAIL
1341- kwargs = {"package_ids": package_ids}
1342- return self._run_query(kwargs, sender)
1343-
1344- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1345- in_signature="t", out_signature="",
1346- sender_keyword="sender")
1347- def GetUpdates(self, filter, sender):
1348- """This method should return a list of packages that are installed
1349- and are upgradable. It should only return the newest update for
1350- each installed package.
1351-
1352- This method typically emits Progress, Error and Package.
1353-
1354- :param filter: A correct filter, e.g. none or installed;~devel
1355- """
1356- pklog.info("GetUpdates() was called")
1357- self.role = pk.RoleEnum.GET_UPDATES
1358- kwargs = {"filters": filter}
1359- return self._run_query(kwargs, sender)
1360-
1361- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1362- in_signature="", out_signature="",
1363- sender_keyword="sender")
1364- def GetDistroUpgrades(self, sender):
1365- """This method should return a list of distribution upgrades that are
1366- available. It should not return updates, only major upgrades.
1367-
1368- This method typically emits DistroUpgrade, Error
1369- """
1370- pklog.info("GetDistroUpgrades() was called")
1371- self.role = pk.RoleEnum.GET_DISTRO_UPGRADES
1372- self.status = pk.StatusEnum.RUNNING
1373- GLib.idle_add(defer_idle, self._get_distro_upgrades)
1374-
1375- def _get_distro_upgrades(self):
1376- # FIXME: Should go into the worker after the threading branch is merged
1377- # It allows to run a nested loop until the download is finished
1378- self.allow_cancel = False
1379- self.percentage = 101
1380- self.status = pk.StatusEnum.DOWNLOAD_UPDATEINFO
1381-
1382- if META_RELEASE_SUPPORT is False:
1383- self.ErrorCode(pk.ErrorEnum.INTERNAL_ERROR,
1384- "Please make sure that update-manager-core is"
1385- "correctly installed.")
1386- self.exit = pk.ExitEnum.FAILED
1387- return
1388-
1389- # FIXME Evil to start the download during init
1390- meta_release = GMetaRelease()
1391- meta_release.connect("download-done",
1392- self._on_distro_upgrade_download_done)
1393-
1394- def _on_distro_upgrade_download_done(self, meta_release):
1395- # FIXME: Add support for description
1396- if meta_release.new_dist is not None:
1397- self.DistroUpgrade("stable",
1398- "%s %s" % (meta_release.new_dist.name,
1399- meta_release.new_dist.version),
1400- "The latest stable release")
1401- self.exit = pk.ExitEnum.SUCCESS
1402-
1403- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1404- in_signature="tas", out_signature="",
1405- sender_keyword="sender")
1406- def Resolve(self, filter, packages, sender):
1407- """This method turns a single package name into a package_id suitable
1408- for the other methods.
1409-
1410- If the package is a fully formed package_id, then this should be
1411- treated as an exact package match. This is useful to find the summary
1412- or installed status of a package_id returned from other methods.
1413-
1414- This method typically emits Error and Package.
1415-
1416- Package enumerated types should be available or installed.
1417-
1418- :param filter: A correct filter, e.g. none or installed;~devel
1419- :param packages:
1420- An array of package names, e.g. scribus-clipart. The package
1421- names are case sensitive, so for instance: Resolve('Packagekit')
1422- would not match PackageKit. As a special case, if Resolve() is
1423- called with a name prefixed with @ then this should be treated as
1424- a category, for example: @web-development. In this instance, a
1425- meta-package should be emitted, for example:
1426- web-development;;;meta with the correct installed status and
1427- summary for the category.
1428- """
1429- pklog.info("Resolve() was called: %s", get_string_from_array(packages))
1430- self.role = pk.RoleEnum.RESOLVE
1431- kwargs = {"filters": filter, "packages": packages}
1432- return self._run_query(kwargs, sender)
1433-
1434- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1435- in_signature="t", out_signature="",
1436- sender_keyword="sender")
1437- def GetPackages(self, filter, sender):
1438- """This method returns all the packages without a search term.
1439-
1440- This method typically emits Progress, Error and Package.
1441-
1442- Package enumerated types should be available or installed.
1443-
1444- :param filter: A correct filter, e.g. none or installed;~devel
1445- """
1446- pklog.info("GetPackages() was called")
1447- self.role = pk.RoleEnum.GET_PACKAGES
1448- kwargs = {"filters": filter}
1449- return self._run_query(kwargs, sender)
1450-
1451- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1452- in_signature="as", out_signature="",
1453- sender_keyword="sender")
1454- def GetDetails(self, package_ids, sender):
1455- """This method should return all the details about a specific
1456- package_id.
1457-
1458- This method typically emits Progress, Status and Error and Details.
1459-
1460- :param package_ids: An array of package IDs.
1461- """
1462- pklog.info("GetDetails() was called")
1463- self.role = pk.RoleEnum.GET_DETAILS
1464- kwargs = {"package_ids": package_ids}
1465- return self._run_query(kwargs, sender)
1466-
1467- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1468- in_signature="as", out_signature="",
1469- sender_keyword="sender")
1470- def GetFiles(self, package_ids, sender):
1471- """This method should return the file list of the package_id.
1472-
1473- This method typically emits Progress, Status and Error and Files.
1474-
1475- :param package_ids: An array of package IDs.
1476- """
1477- pklog.info("GetFiles() was called")
1478- self.role = pk.RoleEnum.GET_FILES
1479- kwargs = {"package_ids": package_ids}
1480- return self._run_query(kwargs, sender)
1481-
1482- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1483- in_signature="tas", out_signature="",
1484- sender_keyword="sender")
1485- def SearchFiles(self, filter, values, sender):
1486- """This method searches for files on the local system and files in
1487- available packages.
1488-
1489- This should search for files. This should allow an application to
1490- find out what package owns a file on the system.
1491-
1492- This method typically emits Progress, Error and Package.
1493-
1494- Package enumerated types should be available or installed.
1495-
1496- :param filter: A correct filter, e.g. none or installed;~devel
1497- :param values:
1498- A filename or fully qualified path and filename on the system.
1499- If the search term begins with a / it will be assumed the entire
1500- path has been given and only packages that contain this exact
1501- path and filename will be returned. If the search term does not
1502- start with / then it should be treated as a single filename,
1503- which can be in any directory. The search is case sensitive,
1504- and should not be escaped or surrounded in quotes.
1505- """
1506- pklog.info("SearchFiles() was called")
1507- self.role = pk.RoleEnum.SEARCH_FILE
1508- kwargs = {"filters": filter,
1509- "values": values}
1510- return self._run_query(kwargs, sender)
1511-
1512- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1513- in_signature="tas", out_signature="",
1514- sender_keyword="sender")
1515- def SearchDetails(self, filter, values, sender):
1516- """This method allows deeper searching than SearchName().
1517-
1518- Do not refresh the package cache. This should be fast. This is very
1519- similar to search-name. This should search as much data as possible,
1520- including, if possible repo names, package summaries, descriptions,
1521- licenses and URLs.
1522-
1523- Try to emit installed before available packages first, as it allows
1524- the client program to perform the GUI filtering and matching whilst
1525- the daemon is running the transaction.
1526-
1527- If the backend includes installed and available versions of the same
1528- package when searching then the available version will have to be
1529- filtered in the backend.
1530-
1531- This method typically emits Progress, Error and Package.
1532-
1533- Package enumerated types should be available or installed.
1534-
1535- :param filter: A correct filter, e.g. none or installed;~devel
1536- :param values:
1537- A single word search term with no wildcard chars. The search term
1538- can contain many words separated by spaces. In this case, the
1539- search operator is AND. For example, search of gnome power should
1540- returns gnome-power-manager but not gnomesword or powertop.
1541- The search should not be treated as case sensitive.
1542- """
1543- pklog.info("SearchDetails() was called")
1544- self.role = pk.RoleEnum.SEARCH_DETAILS
1545- kwargs = {"filters": filter,
1546- "values": values}
1547- return self._run_query(kwargs, sender)
1548-
1549- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1550- in_signature="tas", out_signature="",
1551- sender_keyword="sender")
1552- def SearchGroups(self, filter, values, sender):
1553- """This method returns packages from a given group enumerated type.
1554-
1555- Do not refresh the package cache. This should be fast.
1556-
1557- Try to emit installed before available packages first, as it
1558- allows the client program to perform the GUI filtering and matching
1559- whilst the daemon is running the transaction.
1560-
1561- If the backend includes installed and available versions of the same
1562- package when searching then the available version will have to be
1563- filtered in the backend.
1564-
1565- This method typically emits Progress, Error and Package.
1566-
1567- Package enumerated types should be available or installed.
1568-
1569- :param filter: A correct filter, e.g. none or installed;~devel
1570- :param values:
1571- An enumerated group type, or unknown. The search cannot contain
1572- spaces. The following recommendations are made below: If the values
1573- strings are prefixed with category: then the request is treated
1574- as a 'category search', for example: category:web-development.
1575- repo: then the request is treated as a 'repository search', for
1576- example: repo:fedora-debuginfo. In this instance all packages that
1577- were either installed from, or can be installed from the
1578- fedora-debuginfo source would be returned.
1579- """
1580- pklog.info("SearchGroups() was called")
1581- self.role = pk.RoleEnum.SEARCH_GROUP
1582- kwargs = {"filters": filter,
1583- "values": values}
1584- return self._run_query(kwargs, sender)
1585-
1586- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1587- in_signature="tas", out_signature="",
1588- sender_keyword="sender")
1589- def SearchNames(self, filter, values, sender):
1590- """This method searches the package database by package name.
1591-
1592- Try to emit installed before available packages first, as it
1593- allows the client program to perform the GUI filtering and matching
1594- whilst the daemon is running the transaction.
1595-
1596- If the backend includes installed and available versions of the same
1597- package when searching then the available version will have to be
1598- filtered in the backend.
1599-
1600- The search methods should return all results in all repositories.
1601- This may mean that multiple versions of package are returned. If this
1602- is not what is wanted by the client program, then the newest filter
1603- should be used.
1604-
1605- This method typically emits Progress, Error and Package.
1606-
1607- Package enumerated types should be available or installed.
1608-
1609- :param filter: A correct filter, e.g. none or installed;~devel
1610- :param values:
1611- A single word search term with no wildcard chars. The search term
1612- can contain many words separated by spaces. In this case, the
1613- search operator is AND. For example, search of gnome power should
1614- returns gnome-power-manager but not gnomesword or powertop.
1615- The search should not be treated as case sensitive.
1616- """
1617- pklog.info("SearchNames() was called")
1618- self.role = pk.RoleEnum.SEARCH_NAME
1619- kwargs = {"filters": filter,
1620- "values": values}
1621- return self._run_query(kwargs, sender)
1622-
1623- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1624- in_signature="s", out_signature="",
1625- sender_keyword="sender")
1626- def AcceptEula(self, eula_id, sender):
1627- """This method allows the user to accept a end user licence agreement.
1628-
1629- :param eula_id: A valid EULA ID
1630- """
1631- self.role = pk.RoleEnum.ACCEPT_EULA
1632- GLib.idle_add(self._fail_not_implemented)
1633-
1634- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1635- in_signature="bas", out_signature="",
1636- sender_keyword="sender")
1637- def DownloadPackages(self, store_in_cache, package_ids, sender):
1638- """This method downloads packages into a temporary directory.
1639-
1640- This method should emit one Files signal for each package that
1641- is downloaded, with the file list set as the name of the complete
1642- downloaded file and directory, so for example:
1643-
1644- DownloadPackages('hal;0.1.2;i386;fedora',
1645- 'hal-info;2009-09-07;no-arch;updates') should send two signals,
1646- e.g. Files('hal;0.1.2;i386;fedora', '/tmp/hal-0.1.2.i386.rpm')
1647- and Files('hal-info;2009-09-07;no-arch;updates',
1648- '/tmp/hal-info-2009-09-07.noarch.rpm').
1649-
1650- :param store_in_cache:
1651- If the downloaded files should be stored in the system package
1652- cache rather than copied into a newly created directory. See the
1653- developer docs for more details on how this is supposed to work.
1654- :param package_ids: An array of package IDs.
1655- """
1656- pklog.info("DownloadPackages() was called: %s",
1657- get_string_from_array(package_ids))
1658- self.role = pk.RoleEnum.DOWNLOAD_PACKAGES
1659- kwargs = {"store_in_cache": store_in_cache,
1660- "package_ids": package_ids}
1661- return self._run_query(kwargs, sender)
1662-
1663- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1664- in_signature="u", out_signature="",
1665- sender_keyword="sender")
1666- def GetOldTransactions(self, number, sender):
1667- """This method allows a client to view details for old transactions.
1668-
1669- :param number:
1670- The number of past transactions, or 0 for all known transactions.
1671- """
1672- pklog.info("GetOldTransactions() was called: %s", str(number))
1673- self.role = pk.RoleEnum.GET_OLD_TRANSACTIONS
1674- GLib.idle_add(self._fail_not_implemented)
1675-
1676- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1677- in_signature="t", out_signature="",
1678- sender_keyword="sender")
1679- def GetRepoList(self, filter, sender):
1680- """This method returns the list of repositories used in the system.
1681-
1682- This method should emit RepoDetail.
1683-
1684- :param filter: A correct filter, e.g. none or installed;~devel
1685- """
1686- pklog.info("GetRepoList() was called")
1687- self.role = pk.RoleEnum.GET_REPO_LIST
1688- GLib.idle_add(self._fail_not_implemented)
1689-
1690- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1691- in_signature="tas", out_signature="",
1692- sender_keyword="sender")
1693- def InstallFiles(self, flags, full_paths, sender):
1694- """This method installs local package files onto the local system.
1695-
1696- The installer should always install extra dependant packages
1697- automatically.
1698-
1699- This method typically emits Progress, Status and Error and Package.
1700-
1701- Package enumerated types should be downloading, updating, installing
1702- or removing.
1703-
1704- :param flags:
1705- If the transaction is only allowed to install trusted packages.
1706- Unsigned packages should not be installed if the flags
1707- contains ONLY_TRUSED.
1708- If this method is can only install trusted packages, and
1709- the packages are unsigned, then the backend will send a
1710- ErrorCode(missing-gpg-signature). On recieving this error, the
1711- client may choose to retry with ONLY_TRUSTED set after
1712- gaining further authentication.
1713- :param full_paths: An array of full path and filenames to packages.
1714- """
1715- pklog.info("InstallFiles() was called: %s, %s",
1716- get_string_from_flags(flags),
1717- get_string_from_array(full_paths))
1718- return self._install_files(flags, full_paths, sender)
1719-
1720- @inline_callbacks
1721- def _install_files(self, flags, full_paths, sender):
1722- self.role = pk.RoleEnum.INSTALL_FILES
1723- self.flags = flags
1724- # Python-APT only supports installing one file
1725- if len(full_paths) != 1:
1726- self.ErrorCode(pk.ErrorEnum.NOT_SUPPORTED,
1727- "Only one package can be "
1728- "installed at the same time.")
1729- self.exit = pk.ExitEnum.FAILED
1730- raise StopIteration
1731- path = full_paths[0]
1732- if not os.path.abspath(path):
1733- self.ErrorCode(pk.ErrorEnum.NOT_SUPPORTED,
1734- "Path is not absolute: %s")
1735- self.exit = pk.ExitEnum.FAILED
1736- raise StopIteration
1737- if not os.path.isfile(path):
1738- self.ErrorCode(pk.ErrorEnum.INVALID_PACKAGE_FILE,
1739- "File doesn't exist: %s" % path)
1740- self.exit = pk.ExitEnum.FAILED
1741- raise StopIteration
1742-
1743- kwargs = {"path": path,
1744- "force": True}
1745- self.trans = self._get_merged_trans(aptd_enums.ROLE_INSTALL_FILE,
1746- kwargs=kwargs)
1747- yield self.trans._run(sender)
1748-
1749- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1750- in_signature="uss", out_signature="",
1751- sender_keyword="sender")
1752- def InstallSignature(self, sig_type, key_id, package_id, sender):
1753- """This method allows us to install new security keys.
1754-
1755- :param sig_type: A key type, e.g. gpg
1756- :param key_id: A key ID, e.g. BB7576AC
1757- :param package_id:
1758- A PackageID for the package that the user is trying to install
1759- (ignored)
1760- """
1761- pklog.info("InstallSignature() was called: %s", str(key_id))
1762- self.role = pk.RoleEnum.INSTALL_SIGNATURE
1763- kwargs = {"sig_type": sig_type,
1764- "key_id": key_id,
1765- "package_id": package_id}
1766- return self._run_query(kwargs, sender)
1767-
1768- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1769- in_signature="sss", out_signature="",
1770- sender_keyword="sender")
1771- def RepoSetData(self, repo_id, parameter, value, sender):
1772- """This method allows arbitary data to be passed to the repository
1773- handler.
1774-
1775- :param repo_id:
1776- A repository identifier, e.g. fedora-development-debuginfo
1777- :param parameter:
1778- The backend specific value, e.g. set-download-url.
1779- :param value:
1780- The backend specific value, e.g. http://foo.bar.org/baz.
1781- """
1782- pklog.info("RepoSetData() was called: %s, %s, %s",
1783- str(repo_id), str(parameter), str(value))
1784- self.role = pk.RoleEnum.REPO_SET_DATA
1785- GLib.idle_add(self._fail_not_implemented)
1786-
1787- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1788- in_signature="sb", out_signature="",
1789- sender_keyword="sender")
1790- def RepoEnable(self, repo_id, enabled, sender):
1791- """This method enables the repository specified.
1792-
1793- :param repo_id:
1794- A repository identifier, e.g. fedora-development-debuginfo or an
1795- apt source ("deb http://... unstable main")
1796- :param enabled: true if enabled, false if disabled.
1797- """
1798- pklog.info("RepoEnable() was called(): %s, %s",
1799- str(repo_id), str(enabled))
1800- self.role = pk.RoleEnum.REPO_ENABLE
1801- kwargs = {"repo_id": repo_id,
1802- "enabled": enabled}
1803- return self._run_query(kwargs, sender)
1804-
1805- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1806- in_signature="tsas", out_signature="",
1807- sender_keyword="sender")
1808- def WhatProvides(self, filter, type, values, sender):
1809- """This method returns packages that provide the supplied attributes.
1810- This method is useful for finding out what package(s) provide a
1811- modalias or GStreamer codec string.
1812-
1813- This method typically emits Progress, Status and Error and Package.
1814-
1815- Package enumerated types should be available or installed.
1816-
1817- :param filter:
1818- A correct filter, e.g. none or installed;~devel
1819- :param type:
1820- A PkProvideType, e.g. PK_PROVIDES_ENUM_CODEC.
1821- :param values:
1822- The data to send to the backend to get the packages. Note: This
1823- is backend specific.
1824- """
1825- pklog.info("WhatProvides() was called")
1826- self.role = pk.RoleEnum.WHAT_PROVIDES
1827- kwargs = {"filters": filter,
1828- "provides_type": type,
1829- "values": values}
1830- return self._run_query(kwargs, sender)
1831-
1832- @dbus.service.method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1833- in_signature="", out_signature="",
1834- sender_keyword="sender")
1835- def GetCategories(self, sender):
1836- pklog.info("GetCategories() was called")
1837- """This method return the collection categories"""
1838- self.role = pk.RoleEnum.GET_CATEGORIES
1839- GLib.idle_add(self._fail_not_implemented)
1840-
1841- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1842- in_signature="tasb", out_signature="",
1843- sender_keyword="sender")
1844- def GetRequires(self, filter, package_ids, recursive, sender):
1845- """This method returns packages that depend on this package. This is
1846- useful to know, as if package_id is being removed, we can warn the
1847- user what else would be removed.
1848-
1849- This method typically emits Progress, Status and Error and Package.
1850-
1851- Package enumerated types should be available or installed.
1852-
1853- :param filter: A correct filter, e.g. none or installed;~devel
1854- :param package_ids: An array of package IDs.
1855- :param recursive:
1856- Either true or false. If yes then the requirements should be
1857- returned for all packages returned. This means if
1858- gnome-power-manager depends on NetworkManager and NetworkManager
1859- depends on HAL, then GetRequires on HAL should return both
1860- gnome-power-manager and NetworkManager.
1861- """
1862- pklog.info("GetRequires() was called")
1863- self.role = pk.RoleEnum.GET_REQUIRES
1864- kwargs = {"filters": filter,
1865- "package_ids": package_ids,
1866- "recursive": recursive}
1867- return self._run_query(kwargs, sender)
1868-
1869- @dbus_deferred_method(PACKAGEKIT_TRANS_DBUS_INTERFACE,
1870- in_signature="tasb", out_signature="",
1871- sender_keyword="sender")
1872- def GetDepends(self, filter, package_ids, recursive, sender):
1873- """This method returns packages that this package depends on.
1874-
1875- This method typically emits Progress, Status and Error and Package.
1876-
1877- Package enumerated types should be available or installed.
1878-
1879- :param filter: A correct filter, e.g. none or installed;~devel
1880- :param package_ids: An array of package IDs.
1881- :param recursive:
1882- Either true or false. If yes then the requirements should be
1883- returned for all packages returned. This means if
1884- gnome-power-manager depends on NetworkManager and NetworkManager
1885- depends on HAL, then GetDepends on gnome-power-manager should
1886- return both HAL and NetworkManager.
1887- """
1888- pklog.info("GetDepends() was called")
1889- self.role = pk.RoleEnum.GET_DEPENDS
1890- kwargs = {"filters": filter,
1891- "package_ids": package_ids,
1892- "recursive": recursive}
1893- return self._run_query(kwargs, sender)
1894-
1895- # HELPERS
1896-
1897- def _fail_not_implemented(self):
1898- self.ErrorCode(pk.ErrorEnum.NOT_SUPPORTED, "Unimplemented method")
1899- self.exit = pk.ExitEnum.FAILED
1900- return False
1901-
1902- def _get_properties(self, iface):
1903- """Helper to get the properties of a D-Bus interface."""
1904- if iface == PACKAGEKIT_TRANS_DBUS_INTERFACE:
1905- return {"Role": dbus.UInt32(self.role),
1906- "Status": dbus.UInt32(self.status),
1907- "LastPackage": dbus.String(self.last_package),
1908- "Uid": dbus.UInt32(self.uid),
1909- "Percentage": dbus.UInt32(self.percentage),
1910- "AllowCancel": dbus.Boolean(self.allow_cancel),
1911- "CallerActive": dbus.Boolean(self.caller_active),
1912- "ElapsedTime": dbus.UInt32(self.elapsed_time),
1913- "RemainingTime": dbus.UInt32(self.remaining_time),
1914- "DownloadSizeRemaining": dbus.UInt64(
1915- self.download_size_remaining),
1916- "TransactionFlags": dbus.UInt64(self.flags),
1917- "Speed": dbus.UInt32(self.speed)
1918- }
1919- else:
1920- return {}
1921-
1922- @inline_callbacks
1923- def _run_query(self, kwargs, sender):
1924- self.trans = self._get_merged_trans(aptd_enums.ROLE_PK_QUERY,
1925- kwargs=kwargs)
1926- yield self.trans._run(sender)
1927-
1928- def _get_aptd_package_id(self, pk_id):
1929- """Convert a PackageKit Package ID to the apt syntax.
1930- e.g. xterm;235;i386;installed to xterm:i386=235
1931- """
1932- name, version, arch, data = pk_id.split(";")
1933- id = name
1934- if arch != self.queue.worker.NATIVE_ARCH and arch != "all":
1935- id += ":%s" % arch
1936- if version:
1937- id += "=%s" % version
1938- if data and data not in ["local", "installed"]:
1939- id += "/%s" % data
1940- return id
1941-
1942- def _get_merged_trans(self, role, pkg_ids=None, pkg_type=None,
1943- kwargs=None):
1944- if pkg_ids:
1945- packages = [[], [], [], [], [], []]
1946- packages[pkg_type] = [self._get_aptd_package_id(pkg)
1947- for pkg in pkg_ids]
1948- else:
1949- packages = None
1950- if self.trans:
1951- raise Exception("%s: Transaction may only run once." %
1952- pk.ErrorEnum.TRANSACTION_FAILED)
1953- trans = MergedTransaction(self, role, self.queue,
1954- packages=packages, kwargs=kwargs)
1955- try:
1956- trans._set_locale(self.hints["locale"])
1957- except (KeyError, ValueError):
1958- # If the locale isn't vaild or supported a ValueError
1959- # will be raised
1960- pass
1961- try:
1962- trans._set_debconf(self.hints["frontend-socket"])
1963- except KeyError:
1964- pass
1965- self.queue.limbo[trans.tid] = trans
1966- return trans
1967-
1968-
1969-if META_RELEASE_SUPPORT:
1970-
1971- class GMetaRelease(GObject.GObject, MetaReleaseCore):
1972-
1973- __gsignals__ = {"download-done": (GObject.SignalFlags.RUN_FIRST,
1974- None,
1975- ())}
1976-
1977- def __init__(self):
1978- GObject.GObject.__init__(self)
1979- MetaReleaseCore.__init__(self, False, False)
1980-
1981- def download(self):
1982- MetaReleaseCore.download(self)
1983- self.emit("download-done")
1984-
1985-
1986-def get_pk_exit_enum(enum):
1987- try:
1988- return MAP_EXIT_ENUM[enum]
1989- except KeyError:
1990- return pk.ExitEnum.UNKNOWN
1991-
1992-
1993-def get_pk_status_enum(enum):
1994- try:
1995- return MAP_STATUS_ENUM[enum]
1996- except KeyError:
1997- return pk.StatusEnum.UNKNOWN
1998-
1999-
2000-def get_pk_package_enum(enum):
2001- try:
2002- return MAP_PACKAGE_ENUM[enum]
2003- except KeyError:
2004- return pk.InfoEnum.UNKNOWN
2005-
2006-
2007-def get_pk_error_enum(enum):
2008- try:
2009- return MAP_ERROR_ENUM[enum]
2010- except KeyError:
2011- return pk.ErrorEnum.UNKNOWN
2012-
2013-
2014-def get_pk_package_id(pk_id, data=""):
2015- """Convert an AptDaemon package ID to the PackageKit syntax.
2016- e.g. xterm:i368=235; to xterm;235;i386;installed
2017- """
2018- # FIXME add arch support
2019- name, version, release = split_package_id(pk_id)
2020- try:
2021- name, arch = name.split(":", 1)
2022- except ValueError:
2023- arch = ""
2024- if version is None:
2025- version = ""
2026- if release is None:
2027- release = ""
2028- return "%s;%s;%s;%s" % (name, version, arch, data or release)
2029-
2030-
2031-def defer_idle(func, *args):
2032- func(*args)
2033- return False
2034-
2035-
2036-def get_string_from_flags(flags):
2037- """Return a human readable string of the applied transaction flags."""
2038- ret = ""
2039- if flags == pk.TransactionFlagEnum.NONE:
2040- return "simulate"
2041- if bitfield_contains(flags, pk.TransactionFlagEnum.SIMULATE):
2042- ret += " simulate"
2043- if bitfield_contains(flags, pk.TransactionFlagEnum.ONLY_DOWNLOAD):
2044- ret += " only-download"
2045- if bitfield_contains(flags, pk.TransactionFlagEnum.ONLY_TRUSTED):
2046- ret += " only-trusted"
2047- return ret.strip()
2048-
2049-
2050-def get_string_from_array(array):
2051- """Convert a DBus Array to a human readable format"""
2052- return [str(value) for value in array]
2053-
2054-
2055-# vim: ts=4 et sts=4

Subscribers

People subscribed via source and target branches

to status/vote changes: