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

Richard Hughes hughsient at kemper.freedesktop.org
Fri Jan 18 15:34:18 PST 2008


 NEWS                               |   48 +++
 configure.ac                       |    2 
 contrib/packagekit-bugreport.sh    |    2 
 docs/html/pk-download.html         |    1 
 docs/spec/pk-introduction.xml      |   13 
 libpackagekit/pk-enum.c            |    6 
 python/packagekit/backend.py       |    8 
 python/packagekit/daemonBackend.py |  566 +++++++++++++++++++++++++++++++++++++
 python/packagekit/frontend.py      |   72 ----
 python/packagekit/pkdbus.py        |   60 +++
 python/packagekit/pkexceptions.py  |   54 +++
 11 files changed, 755 insertions(+), 77 deletions(-)

New commits:
commit d67126561ee99268a87b65d8519a587f1145094b
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jan 18 23:29:50 2008 +0000

    post release bump

diff --git a/configure.ac b/configure.ac
index 999e61f..9fc28db 100755
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 AC_PREREQ(2.52)
 
-AC_INIT(PackageKit, 0.1.6)
+AC_INIT(PackageKit, 0.1.7)
 AC_CONFIG_SRCDIR(src)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 AM_CONFIG_HEADER(config.h)
commit b1cd2f1ea4c21a14fe30d2300a80b50fc75a81f1
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Jan 18 23:25:22 2008 +0000

    prepare for release

diff --git a/NEWS b/NEWS
index 2a8374e..0861b57 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,51 @@
+Version 0.1.6
+~~~~~~~~~~~~~
+Released: 2008-01-18
+
+* Backends:
+ - ipkg: use threads for refresh cache and get description functions (Thomas Wood)
+ - ipkg: Implement remove package function (Thomas Wood)
+ - ipkg: Implement install package (Thomas Wood)
+ - ipkg: implement initial get_updates function (Thomas Wood)
+ - ipkg: move get_depends function into a thread (Thomas Wood)
+ - ipkg: protect against NULL user input (Thomas Wood)
+ - ipkg: do not run init and destroy functions more times than required (Thomas Wood)
+ - ipkg: add backend_update_package function (Thomas Wood)
+ - ipkg: improve devel filter (Thomas Wood)
+ - ipkg: implement update system function (Thomas Wood)
+ - ipkg: Add Installed, Development and GUI filter support (Thomas Wood)
+ - yum: implemented vendor_url for urls not bugzilla or cve (Tim Lauridsen)
+ - yum: Implemented bugzilla_url, cve_url, vendor_url in GetUpdateDetails (Tim Lauridsen)
+ - yum: make the updates severity work and show all 3 types (Tim Lauridsen)
+ - yum: fix missing package signals when downloading packages with '-' in names (Tim Lauridsen)
+ - yum: fix percent not shown if the bump is < 1% (Tim Lauridsen)
+ - yum: make get-update-detail work better and dont brake on missing update metadata (Tim Lauridsen)
+ - yum: catch RepoError in get-updates and submit ERROR_NO_CACHE to frontend (Tim Lauridsen)
+ - yum: make Yum Traceback send the right values to the frontend (Tim Lauridsen)
+
+* New features:
+ - Add initial ipkg backend (Thomas Wood)
+ - Add the visible filter (Richard Hughes)
+ - Add some more info and group enums (Richard Hughes)
+ - Replace the UpdateDetail url parameter with vendor, bugzilla, cve (Richard Hughes)
+ - Add PK_STATUS_ENUM_FINISHED when we are just watching status (Richard Hughes)
+ - Add a pm-utils hook so we can drop caches and check for updates on resume (Richard Hughes)
+ - First stab at daemonizing the yum backend (Robin Norwood)
+
+* Bugfixes:
+ - Only do the 100 limit count on emitted packages, not on searched packages.
+   This bug becomes evident when using a couple of filters and searching a large number
+   of package_ids (Richard Hughes)
+ - An empty url list should be empty, not 'none' (Richard Hughes, Matthias Clasen)
+ - Use $(LIBTOOL) rather than hardcoding libtool filename to prevent problems
+   when cross compiling (Thomas Wood)
+ - Add details about what we are winging about in the daemon messages (Richard Hughes)
+ - Include pk-apt-search.h in the tarball to fix fd:13406 (Richard Hughes)
+ - Capture and show the Message() in pkmon (Richard Hughes)
+ - Only look for helpers and the config file in a local root if we have configured
+   with --enable-local to make people less uneasy with path globbing (Richard Hughes)
+ - Finish removing filelist from package description (James Bowes)
+
 Version 0.1.5
 ~~~~~~~~~~~~~
 Released: 2007-12-21
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 7c2769a..594d878 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -50,6 +50,7 @@ Released versions are found on
 <tr><td>0.1.3</td><td></td><td>2007-11-10</td></tr>
 <tr><td>0.1.4</td><td></td><td>2007-11-26</td></tr>
 <tr><td>0.1.5</td><td></td><td>2007-12-21</td></tr>
+<tr><td>0.1.6</td><td></td><td>2008-01-18</td></tr>
 </table>
 
 <h2>Dependencies</h2>
commit dd58b3bdda5b8f3909a5a931eed9c719b17625e3
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Fri Jan 18 15:25:26 2008 -0500

    First stab at daemonizing the yum backend.
    
    Provides a new class, daemonBackend.PackageKitBaseBackend which runs a gobject.Mainloop, and sends and receives signals over dbus.  Things left todo are:
    
    o Clean up naming of classes and methods.
    o Work out what all of the dbus signals will actually be called
      (temporary names are in place now)
    o Actually wire up yumBackend to use it
    
    Submitting the code as-is for comments.

diff --git a/python/packagekit/daemonBackend.py b/python/packagekit/daemonBackend.py
new file mode 100644
index 0000000..36d7d92
--- /dev/null
+++ b/python/packagekit/daemonBackend.py
@@ -0,0 +1,566 @@
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Copyright (C) 2007 Tim Lauridsen <timlau at fedoraproject.org>
+#                    Robin Norwood <rnorwood at redhat.com>                  
+
+#
+# This file contain the base classes to implement a PackageKit python backend
+#
+
+# imports
+import sys
+import traceback
+import types
+from enums import *
+import gobject
+import os
+
+# Classes
+
+class PackageKitBaseBackend:
+
+    def __init__(self,cmds):
+        self.daemonize()
+        PackageKitDbusInterface.__init__(self, 'org.freedesktop.PackageKit')
+        self.cmds = cmds
+        self._locked = False
+
+        self.loop = gobject.MainLoop()
+        self.loop.run()
+       
+    def daemonize(self):
+        """
+        forking code stolen from yum-updatesd
+        """
+        pid = os.fork()
+        if pid:
+            sys.exit()
+        os.chdir("/")
+        fd = os.open("/dev/null", os.O_RDWR)
+        os.dup2(fd, 0)
+        os.dup2(fd, 1)
+        os.dup2(fd, 2)
+        os.close(fd)
+     
+    def doLock(self):
+        ''' Generic locking, overide and extend in child class'''
+        self._locked = True
+
+    def unLock(self):
+        ''' Generic unlocking, overide and extend in child class'''
+        self._locked = False
+        self.tid = None
+
+    def isLocked(self):
+        return self._locked
+
+    def catchall_signal_handler(self,*args,**kwargs):
+        self.tid = args[0]
+
+        if kwargs['member'] == "quit":
+            self.loop.quit()
+            self.quit()
+        if kwargs['member'] == "search_name":
+            self.search_name(args[1],args[2])
+        if kwargs['member'] == "search_details":
+            self.search_details(args[1],args[2])
+        if kwargs['member'] == "search_group":
+            self.search_group(args[1],args[2])
+        if kwargs['member'] == "search_file":
+            self.search_file(args[1],args[2])
+        if kwargs['member'] == "get_update_detail":
+            self.get_update_detail(args[1])
+        if kwargs['member'] == "get_depends":
+            self.get_depends(args[1],args[2])
+        if kwargs['member'] == "get_requires":
+            self.get_requires(args[1],args[2])
+        if kwargs['member'] == "update_system":
+            self.update_system()
+        if kwargs['member'] == "refresh_cache":
+            self.refresh_cache()
+        if kwargs['member'] == "install":
+            self.install(args[1])
+        if kwargs['member'] == "install_file":
+            self.install_file(args[1])
+        if kwargs['member'] == "resolve":
+            self.resolve(args[1],args[2])
+        if kwargs['member'] == "remove":
+            self.remove(args[1],args[2])
+        if kwargs['member'] == "update":
+            self.update(args[1])
+        if kwargs['member'] == "get_description":
+            self.get_description(args[1])
+        if kwargs['member'] == "get_files":
+            self.get_files(args[1])
+        if kwargs['member'] == "get_updates":
+            self.get_updates()
+        if kwargs['member'] == "repo_enable":
+            self.repo_enable(args[1],args[2])
+        if kwargs['member'] == "repo_set_data":
+            self.repo_set_data(args[1],args[2],args[3])
+        if kwargs['member'] == "get_repo_list":
+            self.get_repo_list()
+        else:
+            print "Caught unhandled signal %s"% kwargs['member']
+            print "  args:"
+            for arg in args:
+                print "		" + str(arg)
+
+#
+# Signals ( backend -> engine -> client )
+#
+
+    def percentage(self,percent=None):
+        '''
+        Write progress percentage
+        @param percent: Progress percentage
+        '''
+        if percent != None:
+            self.pk_iface.percentage(self.tid,percent)
+        else:
+            self.pk_iface.no_percentage_updates(self.tid)
+
+    def sub_percentage(self,percent=None):
+        '''
+        send 'subpercentage' signal : subprogress percentage
+        @param percent: subprogress percentage
+        '''
+        self.pk_iface.subpercentage(self.tid,percent)
+
+    def error(self,err,description,exit=True):
+        '''
+        send 'error'
+        @param err: Error Type (ERROR_NO_NETWORK,ERROR_NOT_SUPPORTED,ERROR_INTERNAL_ERROR)
+        @param description: Error description
+        @param exit: exit application with rc=1, if true
+        '''
+        self.pk_iface.error(self.tid,err,description)
+        if exit:
+            self.quit()
+
+    def package(self,id,status,summary):
+        '''
+        send 'package' signal
+        @param info: the enumerated INFO_* string
+        @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+        @param summary: The package Summary
+        '''
+        self.pk_iface.package(self.tid,status,id,summary)
+
+    def status(self,state):
+        '''
+        send 'status' signal
+        @param state: STATUS_DOWNLOAD,STATUS_INSTALL,STATUS_UPDATE,STATUS_REMOVE,STATUS_WAIT
+        '''
+        self.pk_iface.status(self.tid,state)
+
+    def repo_detail(self,repoid,name,state):
+        '''
+        send 'repo-detail' signal
+        @param repoid: The repo id tag
+        @param state: false is repo is disabled else true.
+        '''
+        self.pk_iface.repo_detail(self.tid,repoid,name,state)
+
+    def data(self,data_out):
+        '''
+        send 'data' signal:
+        @param data_out:  The current worked on package
+        '''
+        self.pk_iface.data(self.tid,data_out)
+
+    def metadata(self,typ,fname):
+        '''
+        send 'metadata' signal:
+        @param type:   The type of metadata (repository,package,filelist,changelog,group,unknown)
+        @param fname:  The filename being downloaded
+        '''
+        self.pk_iface.metadata(self.tid,typ,fname)
+
+    def description(self,id,license,group,desc,url,bytes):
+        '''
+        Send 'description' signal
+        @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+        @param license: The license of the package
+        @param group: The enumerated group
+        @param desc: The multi line package description
+        @param url: The upstream project homepage
+        @param bytes: The size of the package, in bytes
+        '''
+        
+        self.pk_iface.description(self.tid,id,license,group,desc,url,bytes)
+
+    def files(self,id,file_list):
+        '''
+        Send 'files' signal
+        @param file_list: List of the files in the package, separated by ';'
+        '''
+        self.pk_iface.files(self.tid,id,file_list)
+
+    def update_detail(self,id,updates,obsoletes,vendor_url,bugzilla_url,cve_url,restart,update_text):
+        '''
+        Send 'updatedetail' signal
+        @param id: The package ID name, e.g. openoffice-clipart;2.6.22;ppc64;fedora
+        @param updates:
+        @param obsoletes:
+        @param vendor_url:
+        @param bugzilla_url:
+        @param cve_url:
+        @param restart:
+        @param update_text:
+        '''
+        self.pk_iface.update_detail(self.tid,id,updates,obsoletes,vendor_url,bugzilla_url,cve_url,restart,update_text)
+
+    def require_restart(self,restart_type,details):
+        '''
+        Send 'requirerestart' signal
+        @param restart_type: RESTART_SYSTEM,RESTART_APPLICATION,RESTART_SESSION
+        @param details: Optional details about the restart
+        '''
+        self.pk_iface.require_restart(self.tid,restart_type,details)
+
+    def allow_interrupt(self,allow):
+        '''
+        send 'allow-interrupt' signal:
+        @param allow:  Allow the current process to be aborted.
+        '''
+        if allow:
+            data = 'true'
+        else:
+            data = 'false'
+        self.pk_iface.allow_interrupt(self.tid,data)
+
+    def repo_signature_required(self,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,type):
+        '''
+        send 'repo-signature-required' signal:
+        @param repo_name:       Name of the repository
+        @param key_url:         URL which the user can use to verify the key
+        @param key_userid:      Key userid
+        @param key_id:          Key ID
+        @param key_fingerprint: Full key fingerprint
+        @param key_timestamp:   Key timestamp
+        @param type:            Key type (GPG)
+        '''
+        self.pk_iface.repo_signature_required(self.tid,repo_name,key_url,key_userid,key_id,key_fingerprint,key_timestamp,type)
+
+#
+# Actions ( client -> engine -> backend )
+#
+    def quit(self):
+        if self.isLocked():
+            self.unLock()
+
+        self.loop.quit()
+
+    def search_name(self,tid,filters,key):
+        '''
+        Implement the {backend}-search-name functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def search_details(self,tid,filters,key):
+        '''
+        Implement the {backend}-search-details functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def search_group(self,tid,filters,key):
+        '''
+        Implement the {backend}-search-group functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def search_file(self,tid,filters,key):
+        '''
+        Implement the {backend}-search-file functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_update_detail(self,tid,package):
+        '''
+        Implement the {backend}-get-update-detail functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_depends(self,tid,package,recursive):
+        '''
+        Implement the {backend}-get-depends functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_requires(self,tid,package,recursive):
+        '''
+        Implement the {backend}-get-requires functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def update_system(self,tid):
+        '''
+        Implement the {backend}-update-system functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def refresh_cache(self,tid):
+        '''
+        Implement the {backend}-refresh_cache functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def install(self,tid,package):
+        '''
+        Implement the {backend}-install functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def install_file (self,tid,inst_file):
+        '''
+        Implement the {backend}-install_file functionality
+        Install the package containing the inst_file file
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def resolve(self,tid,name):
+        '''
+        Implement the {backend}-resolve functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def remove(self,tid,allowdep,package):
+        '''
+        Implement the {backend}-remove functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def update(self,tid,package):
+        '''
+        Implement the {backend}-update functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_description(self,tid,package):
+        '''
+        Implement the {backend}-get-description functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_files(self,tid,package):
+        '''
+        Implement the {backend}-get-files functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_updates(self,tid,package):
+        '''
+        Implement the {backend}-get-updates functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def repo_enable(self,tid,repoid,enable):
+        '''
+        Implement the {backend}-repo-enable functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def repo_set_data(self,tid,repoid,parameter,value):
+        '''
+        Implement the {backend}-repo-set-data functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+    def get_repo_list(self,tid):
+        '''
+        Implement the {backend}-get-repo-list functionality
+        Needed to be implemented in a sub class
+        '''
+        self.error(ERROR_NOT_SUPPORTED,"This function is not implemented in this backend")
+
+#
+# Utility methods
+#
+
+    def get_package_id(self,name,version,arch,data):
+        return "%s;%s;%s;%s" % (name,version,arch,data)
+
+    def get_package_from_id(self,id):
+        ''' split up a package id name;ver;arch;data into a tuple
+            containing (name,ver,arch,data)
+        '''
+        return tuple(id.split(';',4))
+
+    def check_license_field(self,license_field):
+        '''
+        Check the string license_field for free licenses, indicated by
+        their short names as documented at
+        http://fedoraproject.org/wiki/Licensing
+
+        Licenses can be grouped by " or " to indicate that the package
+        can be redistributed under any of the licenses in the group.
+        For instance: GPLv2+ or Artistic or FooLicense.
+
+        Also, if a license ends with "+", the "+" is removed before
+        comparing it to the list of valid licenses.  So if license
+        "FooLicense" is free, then "FooLicense+" is considered free.
+
+        Groups of licenses can be grouped with " and " to indicate
+        that parts of the package are distributed under one group of
+        licenses, while other parts of the package are distributed
+        under another group.  Groups may be wrapped in parenthesis.
+        For instance:
+          (GPLv2+ or Artistic) and (GPL+ or Artistic) and FooLicense.
+
+        At least one license in each group must be free for the
+        package to be considered Free Software.  If the license_field
+        is empty, the package is considered non-free.
+        '''
+
+        groups = license_field.split(" and ")
+
+        if len(groups) == 0:
+            return False
+
+        one_free_group = False
+
+        for group in groups:
+            group = group.replace("(","")
+            group = group.replace(")","")
+            licenses = group.split(" or ")
+
+            group_is_free = False
+
+            for license in licenses:
+                license = license.strip()
+
+                if len(license) < 1:
+                    continue
+
+                if license[-1] == "+":
+                    license = license[0:-1]
+
+                if license in PackageKitEnum.free_licenses:
+                    one_free_group = True
+                    group_is_free = True
+                    break
+
+            if group_is_free == False:
+                return False
+
+        if one_free_group == False:
+            return False
+
+        return True
+
+class PackagekitProgress:
+    '''
+    Progress class there controls the total progress of a transaction
+    the transaction is divided in n milestones. the class contains a subpercentage
+    of the current step (milestone n -> n+1) and the percentage of the whole transaction
+
+    Usage:
+
+    from packagekit.backend import PackagekitProgress
+
+    steps = [10,30,50,70] # Milestones in %
+    progress = PackagekitProgress()
+    progress.set_steps(steps)
+    for milestone in range(len(steps)):
+        # do the action is this step
+        for i in range(100):
+            # do some action
+            progress.set_subpercent(i+1)
+            print "progress : %s " % progress.percent
+        progress.step() # step to next milestone
+
+    '''
+
+    #TODO: Add support for elapsed/remaining time
+
+    def __init__(self):
+        self.percent = 0
+        self.steps = []
+        self.current_step = 0
+        self.subpercent = 0
+
+    def set_steps(self,steps):
+        '''
+        Set the steps for the whole transaction
+        @param steps: list of int representing the percentage of each step in the transaction
+        '''
+        self.reset()
+        self.steps = steps
+        self.current_step = 0
+
+    def reset(self):
+        self.percent = 0
+        self.steps = []
+        self.current_step = 0
+        self.subpercent = 0
+
+    def step(self):
+        '''
+        Step to the next step in the transaction
+        '''
+        if self.current_step < len(self.steps)-1:
+            self.current_step += 1
+            self.percent = self.steps[self.current_step]
+            self.subpercent = 0
+        else:
+            self.percent = 100
+            self.subpercent = 0
+
+    def set_subpercent(self,pct):
+        '''
+        Set subpercentage and update percentage
+        '''
+        self.subpercent = pct
+        self._update_percent()
+
+    def _update_percent(self):
+        '''
+        Increment percentage based on current step and subpercentage
+        '''
+        if self.current_step == 0:
+            startpct = 0
+        else:
+            startpct = self.steps[self.current_step-1]
+        if self.current_step < len(self.steps)-1:
+            endpct = self.steps[self.current_step+1]
+        else:
+            endpct = 100
+        deltapct = endpct -startpct
+        f = float(self.subpercent)/100.0
+        incr = int(f*deltapct)
+        self.percent = startpct + incr
+
diff --git a/python/packagekit/frontend.py b/python/packagekit/frontend.py
index ddeccb6..26244c4 100644
--- a/python/packagekit/frontend.py
+++ b/python/packagekit/frontend.py
@@ -23,53 +23,17 @@ import dbus
 from dbus.mainloop.glib import DBusGMainLoop
 import gobject
 from enums import PackageKitEnum
+from pkdbus import PackageKitDbusInterface, dbusException
+from pkexceptions import PackageKitException, PackageKitNotStarted
+from pkexceptions import PackageKitAccessDenied, PackageKitTransactionFailure
+from pkexceptions import PackageKitBackendFailure
 
-class PackageKitException(Exception):
-	def __init__(self,e=None):
-		Exception.__init__(self)
-		if e == None:
-			self._pk_name = None
-			self._full_str = None
-		else:
-			if not isinstance(e,dbus.exceptions.DBusException):
-				raise Exception,"Can only handle DBusExceptions"
-			self._pk_name = str(e.get_dbus_name())
-			self._full_str = str(e)
-
-	def get_backend_name(self):
-		return self._pk_name
-
-	def __str__(self):
-		if self._full_str!=None:
-			return self._full_str
-		else:
-			return ""
-
-class PackageKitNotStarted(PackageKitException):
-	pass
-
-class PackageKitAccessDenied(PackageKitException):
-	pass
-
-class PackageKitTransactionFailure(PackageKitException):
-	pass
-
-class PackageKitBackendFailure(PackageKitException):
-	pass
+class PackageKit(PackageKitDbusInterface):
+	def __init__(self):
+		PackageKitDbusInterface.__init__(self, 'org.freedesktop.PackageKit')
 
-class PackageKit:
-	def dbusException(func):
-		def wrapper(*args,**kwargs):
-			try:
-				return func(*args,**kwargs)
-			except dbus.exceptions.DBusException,e:
-				if e.get_dbus_name() == "org.freedesktop.DBus.Error.AccessDenied":
-					raise PackageKitAccessDenied(e)
-				elif e.get_dbus_name() == "org.freedesktop.DBus.Error.NoReply":
-					raise PackageKitBackendFailure(e)
-				else:
-					raise PackageKitException(e)
-		return wrapper
+	def tid(self):
+		return self.pk_iface.GetTid()
 
 	def job_id(func):
 		def wrapper(*args,**kwargs):
@@ -80,24 +44,6 @@ class PackageKit:
 				return jid
 		return wrapper
 
-	def tid(self):
-		return self.pk_iface.GetTid()
-
-	def __init__(self):
-		DBusGMainLoop(set_as_default=True)
-		bus = dbus.SystemBus()
-		try:
-			pk = bus.get_object('org.freedesktop.PackageKit', '/org/freedesktop/PackageKit')
-			self.pk_iface = dbus.Interface(pk, dbus_interface='org.freedesktop.PackageKit')
-		except dbus.exceptions.DBusException,e:
-			if e.get_dbus_name() == "org.freedesktop.DBus.Error.ServiceUnknown":
-				raise PackageKitNotStarted
-			else:
-				raise PackageKitException(e)
-
-		#self.job = None
-		bus.add_signal_receiver(self.catchall_signal_handler, interface_keyword='dbus_interface', member_keyword='member',dbus_interface="org.freedesktop.PackageKit")
-
 	def run(self):
 		self.loop = gobject.MainLoop()
 		self.loop.run()
diff --git a/python/packagekit/pkdbus.py b/python/packagekit/pkdbus.py
new file mode 100644
index 0000000..00173e6
--- /dev/null
+++ b/python/packagekit/pkdbus.py
@@ -0,0 +1,60 @@
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Copyright (C) 2007
+#    Tim Lauridsen <timlau at fedoraproject.org>
+#    Tom Parker <palfrey at tevp.net>
+#    Robin Norwood <rnorwood at redhat.com>
+
+# Handle the dbus bits, which are almost the same in the frontend and backend.
+
+import dbus
+from dbus.mainloop.glib import DBusGMainLoop
+from pkexceptions import PackageKitException, PackageKitNotStarted
+from pkexceptions import PackageKitAccessDenied, PackageKitTransactionFailure
+from pkexceptions import PackageKitBackendFailure
+
+def dbusException(func):
+    def wrapper(*args,**kwargs):
+        try:
+            return func(*args,**kwargs)
+        except dbus.exceptions.DBusException,e:
+            if e.get_dbus_name() == "org.freedesktop.DBus.Error.AccessDenied":
+                raise PackageKitAccessDenied(e)
+            elif e.get_dbus_name() == "org.freedesktop.DBus.Error.NoReply":
+                raise PackageKitBackendFailure(e)
+            else:
+                raise PackageKitException(e)
+    return wrapper
+
+class PackageKitDbusInterface:
+
+	def __init__(self, interface_name):
+		DBusGMainLoop(set_as_default=True)
+		bus = dbus.SystemBus()
+		try:
+			pk = bus.get_object('org.freedesktop.PackageKit', '/org/freedesktop/PackageKit')
+			self.pk_iface = dbus.Interface(pk, dbus_interface=interface_name)
+		except dbus.exceptions.DBusException,e:
+			if e.get_dbus_name() == "org.freedesktop.DBus.Error.ServiceUnknown":
+				raise PackageKitNotStarted
+			else:
+				raise PackageKitException(e)
+
+		bus.add_signal_receiver(self.catchall_signal_handler, interface_keyword='dbus_interface', member_keyword='member',dbus_interface=interface_name)
+
+        def catchall_signal_handler(self, *args, **kwargs):
+            raise NotImplementedError()
diff --git a/python/packagekit/pkexceptions.py b/python/packagekit/pkexceptions.py
new file mode 100644
index 0000000..be19844
--- /dev/null
+++ b/python/packagekit/pkexceptions.py
@@ -0,0 +1,54 @@
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Copyright (C) 2007
+#    Tim Lauridsen <timlau at fedoraproject.org>
+#    Tom Parker <palfrey at tevp.net>
+#    Robin Norwood <rnorwood at redhat.com>
+
+class PackageKitException(Exception):
+	def __init__(self,e=None):
+		Exception.__init__(self)
+		if e == None:
+			self._pk_name = None
+			self._full_str = None
+		else:
+			if not isinstance(e,dbus.exceptions.DBusException):
+				raise Exception,"Can only handle DBusExceptions"
+			self._pk_name = str(e.get_dbus_name())
+			self._full_str = str(e)
+
+	def get_backend_name(self):
+		return self._pk_name
+
+	def __str__(self):
+		if self._full_str!=None:
+			return self._full_str
+		else:
+			return ""
+
+class PackageKitNotStarted(PackageKitException):
+	pass
+
+class PackageKitAccessDenied(PackageKitException):
+	pass
+
+class PackageKitTransactionFailure(PackageKitException):
+	pass
+
+class PackageKitBackendFailure(PackageKitException):
+	pass
+
commit 088aef232e845d23873bba0280b8a9cd3d326ddf
Merge: b571949... 7cf0e49...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Fri Jan 18 14:55:44 2008 -0500

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

diff --cc docs/spec/pk-introduction.xml
index 844a9d8,9d6a798..9a0a4a3
--- a/docs/spec/pk-introduction.xml
+++ b/docs/spec/pk-introduction.xml
@@@ -188,15 -188,20 +188,21 @@@
                <entry><literal>free</literal> or <literal>~free</literal></entry>
  
                <entry>
 -                Free software, where the definition of free is given
 -                by the Free Software Foundation.  See
 -                http://www.fsf.org/licensing/licenses/ for a list of
 -                free licenses.  If a license cannot be determined from
 -                the package metadata, or the status of the license is
 -                not known, the package will be marked as 'non-free'.
 +                Free software.  The package contains only software and
 +                other content that is available under a free license.
 +                See http://fedoraproject.org/wiki/Licensing for a list
 +                of licenses that are considered free.  If a license
 +                cannot be determined from the package metadata, or the
 +                status of the license is not known, the package will
 +                be marked as 'non-free'.
                </entry>
- 
+             </row>
+             <row>
+               <entry><literal>visible</literal> or <literal>~visible</literal></entry>
+               <entry>
+                 Repositories may want to specify if a package should be visible
+                 in an application chooser.
+               </entry>
              </row>
            </tbody>
          </tgroup>
commit b571949700ec9758a6eab70a3a937f9638ce7b27
Merge: d894049... 8af0c61...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Sat Jan 12 10:34:47 2008 -0500

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

commit d894049f8e9b3493a13eebbe56f919807dc9fc9d
Merge: fb84202... 45751d7...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Wed Jan 9 12:42:31 2008 -0500

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

commit fb842025b68f8296e998937cfb33b3a48e4f4b4e
Merge: b386762... 8115371...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Wed Jan 9 12:26:50 2008 -0500

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

commit b386762d753c02cd5f48a1dece93b05a9b2af25e
Merge: ce6933e... 851f736...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue Jan 8 12:22:23 2008 -0500

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

commit ce6933eac0edc851c4b2cea1ee226fa0a34650c2
Merge: c53b4ba... 15faec6...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue Jan 8 12:06:43 2008 -0500

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

commit c53b4ba59e667754fc3883b1023114d0d10eecd3
Merge: d6fe59a... ed285d7...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Fri Jan 4 14:33:50 2008 -0500

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

commit d6fe59a0b075fc13806db9adc177e47661b29e66
Merge: c321b95... 71e9d18...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Tue Jan 1 16:20:26 2008 -0500

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

commit c321b95b68e714db57f9f566ded7bbb322b42ef7
Merge: f306f39... 19fed75...
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Sun Dec 30 14:34:38 2007 -0500

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

commit f306f39889dc8d4692bdeb71be466d778b133523
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Sat Dec 22 00:55:12 2007 -0500

    Remove 'FSF' terminology, since not all of the free licenses are FSF approved.

diff --git a/docs/spec/pk-introduction.xml b/docs/spec/pk-introduction.xml
index b02c072..6a3d1e9 100644
--- a/docs/spec/pk-introduction.xml
+++ b/docs/spec/pk-introduction.xml
@@ -188,12 +188,13 @@
               <entry><literal>free</literal> or <literal>~free</literal></entry>
 
               <entry>
-                Free software, where the definition of free is given
-                by the Free Software Foundation.  See
-                http://www.fsf.org/licensing/licenses/ for a list of
-                free licenses.  If a license cannot be determined from
-                the package metadata, or the status of the license is
-                not known, the package will be marked as 'non-free'.
+                Free software.  The package contains only software and
+                other content that is available under a free license.
+                See http://fedoraproject.org/wiki/Licensing for a list
+                of licenses that are considered free.  If a license
+                cannot be determined from the package metadata, or the
+                status of the license is not known, the package will
+                be marked as 'non-free'.
               </entry>
 
             </row>
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 7e941f6..032f403 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -223,7 +223,7 @@ static PkEnumMatch enum_sig_type[] = {
 	{0, NULL},
 };
 
-static PkEnumMatch enum_fsf_free_licenses[] = {
+static PkEnumMatch enum_free_licenses[] = {
 	{PK_LICENSE_ENUM_UNKNOWN,              "unknown"},	/* fall though value */
 	{PK_LICENSE_ENUM_GLIDE,                "Glide"},
 	{PK_LICENSE_ENUM_AFL,                  "AFL"},
@@ -627,7 +627,7 @@ pk_filter_enum_to_text (PkFilterEnum filter)
 PkLicenseEnum
 pk_license_enum_from_text (const gchar *license)
 {
-	return pk_enum_find_value (enum_fsf_free_licenses, license);
+	return pk_enum_find_value (enum_free_licenses, license);
 }
 
 /**
@@ -636,7 +636,7 @@ pk_license_enum_from_text (const gchar *license)
 const gchar *
 pk_license_enum_to_text (PkLicenseEnum license)
 {
-	return pk_enum_find_string (enum_fsf_free_licenses, license);
+	return pk_enum_find_string (enum_free_licenses, license);
 }
 
 /***************************************************************************
diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index 170d9cc..7c09276 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -185,9 +185,9 @@ class PackageKitBaseBackend:
 
     def check_license_field(self,license_field):
         '''
-        Check the string license_field for free licenses, as defined
-        by the FSF, indicated by their short names as documented at
-        http://fedoraproject.org/wiki/Licensing#SoftwareLicenses
+        Check the string license_field for free licenses, indicated by
+        their short names as documented at
+        http://fedoraproject.org/wiki/Licensing
 
         Licenses can be grouped by " or " to indicate that the package
         can be redistributed under any of the licenses in the group.
@@ -232,7 +232,7 @@ class PackageKitBaseBackend:
                 if license[-1] == "+":
                     license = license[0:-1]
 
-                if license in PackageKitEnum.fsf_free_licenses:
+                if license in PackageKitEnum.free_licenses:
                     one_free_group = True
                     group_is_free = True
                     break
commit f94886dbaa0cdb9d5eb54745d8d221365a8191ab
Author: Robin Norwood <rnorwood at redhat.com>
Date:   Fri Dec 21 13:48:40 2007 -0500

    Script needs a shebang line

diff --git a/contrib/packagekit-bugreport.sh b/contrib/packagekit-bugreport.sh
index ae7693b..6fbe602 100755
--- a/contrib/packagekit-bugreport.sh
+++ b/contrib/packagekit-bugreport.sh
@@ -1,3 +1,5 @@
+#!/bin/sh
+#
 # Copyright (C) 2007 Richard Hughes <richard at hughsie.com>
 #
 # Licensed under the GNU General Public License Version 2



More information about the PackageKit mailing list