rpms/system-config-printer/devel system-config-printer-git.patch, NONE, 1.1 system-config-printer.spec, 1.210, 1.211 system-config-printer-forbidden.patch, 1.1, NONE

Tim Waugh (twaugh) fedora-extras-commits at redhat.com
Thu Aug 14 15:27:02 UTC 2008


Author: twaugh

Update of /cvs/pkgs/rpms/system-config-printer/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv30820

Modified Files:
	system-config-printer.spec 
Added Files:
	system-config-printer-git.patch 
Removed Files:
	system-config-printer-forbidden.patch 
Log Message:
* Thu Aug 14 2008 Tim Waugh <twaugh at redhat.com> 1.0.5-3
- Include other fixes from upstream including:
  - OpenPrinting API change (trac #74).
  - libnotify API change for 'closed' signal.
  - Notification for job authentication (trac #91).
  - Glade delete-event fixes (trac #88).
  - Pre-fill username in job authentication dialog (trac #87).


system-config-printer-git.patch:

--- NEW FILE system-config-printer-git.patch ---
diff -up system-config-printer-1.0.5/authconn.py.git system-config-printer-1.0.5/authconn.py
--- system-config-printer-1.0.5/authconn.py.git	2008-08-11 14:33:09.000000000 +0100
+++ system-config-printer-1.0.5/authconn.py	2008-08-14 16:23:49.000000000 +0100
@@ -130,7 +130,13 @@ class Connection:
 
     def _authloop (self, fname, fn, *args, **kwds):
         self._passes = 0
+        c = self._connection
         while self._perform_authentication () != 0:
+            if c != self._connection:
+                # We have reconnected.
+                fn = getattr (self._connection, fname)
+                c = self._connection
+
             try:
                 result = fn.__call__ (*args, **kwds)
 
@@ -146,15 +152,17 @@ class Connection:
                 else:
                     raise
             except cups.HTTPError, (s,):
-                if not self._cancel and s == cups.HTTP_UNAUTHORIZED:
-                    self._failed ()
+                if not self._cancel and (s == cups.HTTP_UNAUTHORIZED or
+                                         s == cups.HTTP_FORBIDDEN):
+                    self._failed (s == cups.HTTP_FORBIDDEN)
                 else:
                     raise
 
         return result
 
-    def _failed (self):
+    def _failed (self, forbidden=False):
         self._has_failed = True
+        self._forbidden = forbidden
 
     def _password_callback (self, prompt):
         debugprint ("Got password callback")
@@ -173,6 +181,7 @@ class Connection:
             # Haven't yet tried the operation.  Set the password
             # callback and return > 0 so we try it for the first time.
             self._has_failed = False
+            self._forbidden = False
             self._auth_called = False
             self._cancel = False
             cups.setPasswordCB (self._password_callback)
@@ -192,16 +201,17 @@ class Connection:
             # Tried the operation without a password and it failed.
             if (self._try_as_root and
                 self._user != 'root' and
-                self._server[0] == '/'):
+                (self._server[0] == '/' or self._forbidden)):
                 # This is a UNIX domain socket connection so we should
-                # not have needed a password, and so the operation must
-                # not be something that the current user is authorised to
-                # do.  They need to try as root, and supply the password.
-                # However, to get the right prompt, we need to try as
-                # root but with no password first.
+                # not have needed a password (or it is not a UDS but
+                # we got an HTTP_FORBIDDEN response), and so the
+                # operation must not be something that the current
+                # user is authorised to do.  They need to try as root,
+                # and supply the password.  However, to get the right
+                # prompt, we need to try as root but with no password
+                # first.
                 debugprint ("Authentication: Try as root")
                 self._use_user = 'root'
-                cups.setUser (self._use_user)
                 self._auth_called = False
                 self._connect ()
                 return 1
diff -U0 system-config-printer-1.0.5/ChangeLog.git system-config-printer-1.0.5/ChangeLog
--- system-config-printer-1.0.5/ChangeLog.git	2008-08-11 14:51:07.000000000 +0100
+++ system-config-printer-1.0.5/ChangeLog	2008-08-14 16:23:49.000000000 +0100
@@ -0,0 +1,67 @@
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* cupshelpers/openprinting.py
+	(OpenPrinting.listDrivers.parse_result): OpenPrinting API change:
+	freesoftware -> nonfreesoftware (trac #74).
+	* system-config-printer.py
+	(NewPrinterGUI.on_tvNPDownloadableDrivers_cursor_changed):
+	Likewise.
+
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.on_new_printer_notification_closed):
+	Optional reason parameter to handle newer libnotify signal
+	interface.
+	(JobViewer.on_state_reason_notification_closed): Likewise.
+	(JobViewer.on_auth_notification_closed): Likewise.
+
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.update_job): Display a notification when
+	a job requires authentication (trac #91).
+	(JobViewer.on_auth_notification_authenticate): New method.
+	Display an authentication dialog when the notification's
+	authenticate action is triggered.
+	(JobViewer.on_auth_notification_closed): New method.  Handle an
+	auth notification being closed.
+
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.update_job): Moved code for displaying
+	authentication dialog...
+	(JobViewer.display_auth_info_dialog): ...here.  New method.
+
+2008-08-14  Rui Tiago Cação Matos  <tiagomatos at gmail.com>
+
+	* system-config-printer.py (GUI.__init__):
+	* system-config-printer.py (NewPrinterGUI.__init__): Since some
+	dialogs are reused we can't let the delete-event's default handler
+	destroy them.
+	* system-config-printer.py (on_delete_just_hide): This method is
+	connected to those dialog's delete-event (trac #88).
+
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.update_job): When a job is held for
+	authentication, say so in the status column.
+
+2008-08-14  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.update_job): Show authentication dialog
+	in the middle of the screen (trac #90).
+
+2008-08-13  Tim Waugh  <twaugh at redhat.com>
+
+	* authconn.py (Connection._authloop): Re-bind to the named method
+	on reconnection.  Handle HTTP_FORBIDDEN (trac #89).
+	(Connection._failed): New optional parameter forbidden.  Remember
+	whether we saw HTTP_FORBIDDEN.
+	(Connection._perform_authentication): Initialise self._forbidden.
+	Use it to decide whether to try as root.  Don't call setUser()
+	here; _connect() will do that.
+
+2008-08-12  Tim Waugh  <twaugh at redhat.com>
+
+	* jobviewer.py (JobViewer.update_job): Pre-fill the username field
+	when asking for authentication for the job (trac #87).
+
diff -up system-config-printer-1.0.5/cupshelpers/openprinting.py.git system-config-printer-1.0.5/cupshelpers/openprinting.py
--- system-config-printer-1.0.5/cupshelpers/openprinting.py.git	2008-08-11 10:05:02.000000000 +0100
+++ system-config-printer-1.0.5/cupshelpers/openprinting.py	2008-08-14 16:23:49.000000000 +0100
@@ -217,7 +217,7 @@ class OpenPrinting:
                 #     'supplier': supplier,
                 #     'license': short license string e.g. GPLv2,
                 #     'licensetext': license text (HTML),
-                #     'freesoftware': Boolean,
+                #     'nonfreesoftware': Boolean,
                 #     'patents': Boolean,
                 #     'shortdescription': short description,
                 #     'recommended': Boolean,
@@ -260,10 +260,15 @@ class OpenPrinting:
                     if element != None:
                         dict['licensetext'] = element.text
 
-                    for boolean in ['freesoftware', 'recommended',
+                    for boolean in ['nonfreesoftware', 'recommended',
                                     'patents']:
                         dict[boolean] = driver.find (boolean) != None
 
+                    # Make a 'freesoftware' tag for compatibility with
+                    # how the OpenPrinting API used to work (see trac
+                    # #74).
+                    dict['freesoftware'] = not dict['nonfreesoftware']
+
                     if not dict.has_key ('name') or not dict.has_key ('url'):
                         continue
 
diff -up system-config-printer-1.0.5/jobviewer.py.git system-config-printer-1.0.5/jobviewer.py
--- system-config-printer-1.0.5/jobviewer.py.git	2008-08-11 14:51:07.000000000 +0100
+++ system-config-printer-1.0.5/jobviewer.py	2008-08-14 16:23:49.000000000 +0100
@@ -31,6 +31,7 @@ import gtk.glade
 import monitor
 import os
 import pango
+import pwd
 import sys
 import time
 
@@ -160,6 +161,7 @@ class JobViewer (monitor.Watcher):
         self.num_jobs_when_hidden = 0
         self.connecting_to_device = {} # dict of printer->time first seen
         self.state_reason_notifications = {}
+        self.auth_notifications = {}
         self.job_creation_times_timer = None
         self.special_status_icon = False
         self.new_printer_notifications = {}
@@ -320,7 +322,7 @@ class JobViewer (monitor.Watcher):
         notification.attach_to_status_icon (self.statusicon)
         notification.show ()
 
-    def on_new_printer_notification_closed (self, notification):
+    def on_new_printer_notification_closed (self, notification, reason=None):
         printer = notification.get_data ('printer-name')
         del self.new_printer_notifications[printer]
         self.set_statusicon_visibility ()
@@ -471,17 +473,24 @@ class JobViewer (monitor.Watcher):
         store.set_value (iter, 4, size)
 
         state = None
+        job_requires_auth = False
         if data.has_key ('job-state'):
             try:
                 jstate = data['job-state']
                 s = int (jstate)
-                state = { cups.IPP_JOB_PENDING: _("Pending"),
-                          cups.IPP_JOB_HELD: _("Held"),
-                          cups.IPP_JOB_PROCESSING: _("Processing"),
-                          cups.IPP_JOB_STOPPED: _("Stopped"),
-                          cups.IPP_JOB_CANCELED: _("Canceled"),
-                          cups.IPP_JOB_ABORTED: _("Aborted"),
-                          cups.IPP_JOB_COMPLETED: _("Completed") }[s]
+                job_requires_auth = (jstate == cups.IPP_JOB_HELD and
+                                     data.get ('job-hold-until', 'none') ==
+                                     'auth-info-required')
+                if job_requires_auth:
+                    state = _("Held for authentication")
+                else:
+                    state = { cups.IPP_JOB_PENDING: _("Pending"),
+                              cups.IPP_JOB_HELD: _("Held"),
+                              cups.IPP_JOB_PROCESSING: _("Processing"),
+                              cups.IPP_JOB_STOPPED: _("Stopped"),
+                              cups.IPP_JOB_CANCELED: _("Canceled"),
+                              cups.IPP_JOB_ABORTED: _("Aborted"),
+                              cups.IPP_JOB_COMPLETED: _("Completed") }[s]
             except ValueError:
                 pass
             except IndexError:
@@ -492,64 +501,115 @@ class JobViewer (monitor.Watcher):
         store.set_value (iter, 6, state)
 
         # Check whether authentication is required.
-        if (self.trayicon and
-            data['job-state'] == cups.IPP_JOB_HELD and
-            data.get ('job-hold-until', 'none') == 'auth-info-required' and
-            not self.auth_info_dialog):
+        if self.trayicon:
+            if (job_requires_auth and
+                not self.auth_notifications.has_key (job) and
+                not self.auth_info_dialog):
+                try:
+                    cups.require ("1.9.37")
+                except:
+                    debugprint ("Authentication required but "
+                                "authenticateJob() not available")
+                    return
+
+                title = _("Authentication Required")
+                text = _("Job requires authentication to proceed.")
+                notification = pynotify.Notification (title, text, 'printer')
+                notification.set_data ('job-id', job)
+                notification.set_urgency (pynotify.URGENCY_NORMAL)
+                notification.set_timeout (pynotify.EXPIRES_NEVER)
+                notification.connect ('closed',
+                                      self.on_auth_notification_closed)
+                self.set_statusicon_visibility ()
+                notification.attach_to_status_icon (self.statusicon)
+                notification.add_action ("authenticate", _("Authenticate"),
+                                         self.on_auth_notification_authenticate)
+                notification.show ()
+                self.auth_notifications[job] = notification
+            elif (not job_requires_auth and
+                  self.auth_notifications.has_key (job)):
+                self.auth_notifications[job].close ()
+
+    def on_auth_notification_closed (self, notification, reason=None):
+        job = notification.get_data ('job-id')
+        debugprint ("auth notification closed for job %s" % job)
+        del self.auth_notifications[job]
+
+    def on_auth_notification_authenticate (self, notification, action):
+        job = notification.get_data ('job-id')
+        debugprint ("auth notification authenticate for job %s" % job)
+        self.display_auth_info_dialog (job)
+
+    def display_auth_info_dialog (self, job):
+        data = self.jobs[job]
+        # Find out which auth-info is required.
+        try:
+            c = authconn.Connection (self.MainWindow)
             try:
-                cups.require ("1.9.37")
-            except:
-                debugprint ("Authentication required but "
-                            "authenticateJob() not available")
-                return
+                uri = data['job-printer-uri']
+                attributes = c.getPrinterAttributes (uri = uri)
+            except TypeError: # uri keyword introduced in pycups-1.9.32
+                debugprint ("Fetching printer attributes by name")
+                attributes = c.getPrinterAttributes (printer)
+        except cups.IPPError, (e, m):
+            self.show_IPP_Error (e, m)
+            return
+        except RuntimeError:
+            debugprint ("Failed to connect when fetching printer attrs")
+            return
 
-            # Find out which auth-info is required.
+        try:
+            auth_info_required = attributes['auth-info-required']
+        except KeyError:
+            debugprint ("No auth-info-required attribute; guessing instead")
+            auth_info_required = ['username', 'password']
+
+        if not isinstance (auth_info_required, list):
+            auth_info_required = [auth_info_required]
+
+        if auth_info_required == ['negotiate']:
+            # Try Kerberos authentication.
             try:
-                c = authconn.Connection (self.MainWindow)
-                try:
-                    uri = data['job-printer-uri']
-                    attributes = c.getPrinterAttributes (uri = uri)
-                except TypeError: # uri keyword introduced in pycups-1.9.32
-                    debugprint ("Fetching printer attributes by name")
-                    attributes = c.getPrinterAttributes (printer)
+                debugprint ("Trying Kerberos auth for job %d" % jobid)
+                c.authenticateJob (jobid)
+            except TypeError:
+                # Requires pycups-1.9.39 for optional auth parameter.
+                # Treat this as a normal job error.
+                debugprint ("... need newer pycups for that")
+                return
             except cups.IPPError, (e, m):
                 self.show_IPP_Error (e, m)
                 return
-            except RuntimeError:
-                debugprint ("Failed to connect when fetching printer attrs")
-                return
 
-            try:
-                auth_info_required = attributes['auth-info-required']
-            except KeyError:
-                debugprint ("No auth-info-required attribute; guessing instead")
-                auth_info_required = ['username', 'password']
-
-            if not isinstance (auth_info_required, list):
-                auth_info_required = [auth_info_required]
+        dialog = authconn.AuthDialog (auth_info_required=auth_info_required)
+        dialog.set_position (gtk.WIN_POS_CENTER)
 
-            if auth_info_required == ['negotiate']:
-                # Try Kerberos authentication.
-                try:
-                    debugprint ("Trying Kerberos auth for job %d" % jobid)
-                    c.authenticateJob (jobid)
-                except TypeError:
-                    # Requires pycups-1.9.39 for optional auth parameter.
-                    # Treat this as a normal job error.
-                    debugprint ("... need newer pycups for that")
-                    return
-                except cups.IPPError, (e, m):
-                    self.show_IPP_Error (e, m)
-                    return
+        # Pre-fill 'username' field.
+        if 'username' in auth_info_required:
+            try:
+                auth_info = map (lambda x: '', auth_info_required)
+                username = pwd.getpwuid (os.getuid ())[0]
+                ind = auth_info_required.index ('username')
+                auth_info[ind] = username
+                dialog.set_auth_info (auth_info)
+
+                index = 0
+                for field in auth_info_required:
+                    if auth_info[index] == '':
+                        # Focus on the first empty field.
+                        dialog.field_grab_focus (field)
+                        break
+                    index += 1
+            except:
+                nonfatalException ()
 
-            dialog = authconn.AuthDialog (auth_info_required=auth_info_required)
-            dialog.set_prompt (_("Authentication required for "
-                                 "printing document `%s' (job %d)") %
-                               (data.get('job-name', _("Unknown")), job))
-            self.auth_info_dialog = dialog
-            dialog.connect ('response', self.auth_info_dialog_response)
-            dialog.set_data ('job-id', job)
-            dialog.show_all ()
+        dialog.set_prompt (_("Authentication required for "
+                             "printing document `%s' (job %d)") %
+                           (data.get('job-name', _("Unknown")), job))
+        self.auth_info_dialog = dialog
+        dialog.connect ('response', self.auth_info_dialog_response)
+        dialog.set_data ('job-id', job)
+        dialog.show_all ()
 
     def auth_info_dialog_response (self, dialog, response):
         dialog.hide ()
@@ -862,7 +922,7 @@ class JobViewer (monitor.Watcher):
         notification.attach_to_status_icon (self.statusicon)
         notification.show ()
 
-    def on_state_reason_notification_closed (self, notification):
+    def on_state_reason_notification_closed (self, notification, reason=None):
         debugprint ("Notification %s closed" % repr (notification))
         reason = notification.get_data ('printer-state-reason')
         tuple = reason.get_tuple ()
diff -up system-config-printer-1.0.5/system-config-printer.py.git system-config-printer-1.0.5/system-config-printer.py
--- system-config-printer-1.0.5/system-config-printer.py.git	2008-08-11 14:51:07.000000000 +0100
+++ system-config-printer-1.0.5/system-config-printer.py	2008-08-14 16:23:49.000000000 +0100
@@ -152,6 +152,10 @@ class GtkGUI:
         result.sort()
         return result
 
+def on_delete_just_hide (widget, event):
+    widget.hide ()
+    return True # stop other handlers
+
 class GUI(GtkGUI, monitor.Watcher):
 
     printer_states = { cups.IPP_PRINTER_IDLE: _("Idle"),
@@ -271,6 +275,14 @@ class GUI(GtkGUI, monitor.Watcher):
                         "AboutDialog",
                         "WaitWindow", "lblWait",
                         )
+
+        # Since some dialogs are reused we can't let the delete-event's
+        # default handler destroy them
+        for dialog in [self.PrinterPropertiesDialog,
+                       self.ServerSettingsDialog,
+                       self.ConnectingDialog]:
+            dialog.connect ("delete-event", on_delete_just_hide)
+
         self.tooltips = gtk.Tooltips()
         self.tooltips.enable()
         gtk.window_set_default_icon_name ('printer')
@@ -2597,6 +2609,13 @@ class NewPrinterGUI(GtkGUI):
                         "rbtnNPDownloadLicenseNo",
                         "NewPrinterName", "entCopyName", "btnCopyOk",
                         "InstallDialog", "lblInstall")
+
+        # Since some dialogs are reused we can't let the delete-event's
+        # default handler destroy them
+        for dialog in [self.IPPBrowseDialog,
+                       self.SMBBrowseDialog]:
+            dialog.connect ("delete-event", on_delete_just_hide)
+
         # share with mainapp
         self.WaitWindow = mainapp.WaitWindow
         self.lblWait = mainapp.lblWait
@@ -4722,7 +4741,7 @@ class NewPrinterGUI(GtkGUI):
         self.lblNPDownloadableDriverLicense.set_text (license)
         description = driver.get('shortdescription', _("None"))
         self.lblNPDownloadableDriverDescription.set_text (description)
-        if driver['freesoftware'] and not driver['patents']:
+        if not driver['nonfreesoftware'] and not driver['patents']:
             self.rbtnNPDownloadLicenseYes.set_active (True)
             self.frmNPDownloadableDriverLicenseTerms.hide ()
         else:


Index: system-config-printer.spec
===================================================================
RCS file: /cvs/pkgs/rpms/system-config-printer/devel/system-config-printer.spec,v
retrieving revision 1.210
retrieving revision 1.211
diff -u -r1.210 -r1.211
--- system-config-printer.spec	13 Aug 2008 21:23:17 -0000	1.210
+++ system-config-printer.spec	14 Aug 2008 15:26:32 -0000	1.211
@@ -7,7 +7,7 @@
 Summary: A printer administration tool
 Name: system-config-printer
 Version: 1.0.5
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: GPLv2+
 URL: http://cyberelk.net/tim/software/system-config-printer/
 Group: System Environment/Base
@@ -15,7 +15,7 @@
 Source1: http://cyberelk.net/tim/data/pycups/pycups-%{pycups_version}.tar.bz2
 Source2: http://cyberelk.net/tim/data/pysmbc/pysmbc-%{pysmbc_version}.tar.bz2
 
-Patch0: system-config-printer-forbidden.patch
+Patch0: system-config-printer-git.patch
 Patch1: pysmbc-debug.patch
 
 BuildRequires: cups-devel >= 1.2
@@ -64,7 +64,7 @@
 %prep
 %setup -q -a 1 -a 2
 
-%patch0 -p1 -b .forbidden
+%patch0 -p1 -b .git
 
 pushd pysmbc-%{pysmbc_version}
 %patch1 -p1 -b .debug
@@ -157,6 +157,14 @@
 exit 0
 
 %changelog
+* Thu Aug 14 2008 Tim Waugh <twaugh at redhat.com> 1.0.5-3
+- Include other fixes from upstream including:
+  - OpenPrinting API change (trac #74).
+  - libnotify API change for 'closed' signal.
+  - Notification for job authentication (trac #91).
+  - Glade delete-event fixes (trac #88).
+  - Pre-fill username in job authentication dialog (trac #87).
+
 * Wed Aug 13 2008 Tim Waugh <twaugh at redhat.com> 1.0.5-2
 - Handle HTTP_FORBIDDEN.
 


--- system-config-printer-forbidden.patch DELETED ---




More information about the fedora-extras-commits mailing list