PackageKit has a “WhatProvides” API for mapping distribution independent concepts to particular package names. For example, you could ask “which packages provide a decoder for AC3 audio files?
$ pkcon what-provides "gstreamer0.10(decoder-audio/ac3)" [...] Installed gstreamer0.10-plugins-good-0.10.30.2-2ubuntu2.amd64 GStreamer plugins from the "good" set Available gstreamer0.10-plugins-ugly-0.10.18-3ubuntu4.amd64 GStreamer plugins from the "ugly" set
This is the kind of question your video player would ask the system if it encounters a video it cannot play. In reality they of course use the D-BUS or the library API, but it’s easier to demonstrate with the PackageKit command line client.
PackageKit provides a fair number of those concepts; I recently added LANGUAGE_SUPPORT for packages which provide dictionaries, spell checkers, and other language support for a given language or locale code.
However, PackageKit’s apt backend does not actually implement a lot of these (only CODEC and MODALIAS), and aptdaemons’s PackageKit compatibility API does not implement any. That might be because their upstreams do not know enough how to do the mapping for a particular distro/backend, because doing so involves distro specific code which should not go into upstreams, or simply because of the usual chicken-egg problem of app developers rather doing their own thing instead of using generic APIs.
So this got discussed between Sebastian Heinlein and me, and voila, there it is: it is now very easy to provide Python plugins for “what-provides” to implement any of the existing types. For example, language-selector now ships a plugin which implements LANGUAGE_SUPPORT, so you can ask “which packages do I need for Chinese in China” (i. e. simplified Chinese)?
$ pkcon what-provides "locale(zh_CN)" [...] Available firefox-locale-zh-hans-10.0+build1-0ubuntu1.all Simplified Chinese language pack for Firefox Available ibus-sunpinyin-2.0.3-2.amd64 sunpinyin engine for ibus Available language-pack-gnome-zh-hans-1:12.04+20120130.all GNOME translation updates for language Simplified Chinese Available ttf-arphic-ukai-0.2.20080216.1-1.all "AR PL UKai" Chinese Unicode TrueType font collection Kaiti style [...]
In Ubuntu we usually do not use PackageKit itself, but aptdaemon and its PackageKit API compatibility shim
python-aptdaemon.pkcompat. So I ported that plugin support for aptdaemon-pkcompat as well, so plugins work with either now. Ubuntu Precise got the new aptdaemon (0.43+bzr769-0ubuntu1) and language-selector (0.63) versions today, so you can start playing around with this now.
So how can you write your own plugins? This is a trivial, although rather nonsense example:
from packagekit import enums def my_what_provides(apt_cache, provides_type, search): if provides_type in (enums.PROVIDES_CODEC, enums.PROVIDES_ANY): return [apt_cache["gstreamer-moo"]] else: raise NotImplementedError('cannot handle type ' + str(provides_type))
The function gets an
apt.Cache object, one of
enums.PROVIDES_* and the actual search type as described in the documentation (above dummy example does not actually use it). It then decides whether it can handle the request and return a list of
apt.package.Package objects (i. e. values in an
apt.Cache map), or raise a
You register the plugin through Python pkg-resources in your setup.py (this needs setuptools):
setup( [....] entry_points="""[packagekit.apt.plugins] what_provides=my_plugin_module_name:my_what_provides """, [...])
You can register arbitrarily many plugins, they will be all called and their resulting package lists joined.
All this will hopefully help a bit to push distro specifics to the lowest possible levels, and use upstream friendly and distribution agnostic APIs in your applications.Read more