Back to index

system-config-printer  1.3.9+20120706
CheckPPDSanity.py
Go to the documentation of this file.
00001 #!/usr/bin/python
00002 
00003 ## Printing troubleshooter
00004 
00005 ## Copyright (C) 2008, 2009, 2010 Red Hat, Inc.
00006 ## Authors:
00007 ##  Tim Waugh <twaugh@redhat.com>
00008 
00009 ## This program is free software; you can redistribute it and/or modify
00010 ## it under the terms of the GNU General Public License as published by
00011 ## the Free Software Foundation; either version 2 of the License, or
00012 ## (at your option) any later version.
00013 
00014 ## This program is distributed in the hope that it will be useful,
00015 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 ## GNU General Public License for more details.
00018 
00019 ## You should have received a copy of the GNU General Public License
00020 ## along with this program; if not, write to the Free Software
00021 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00022 
00023 import cups
00024 import cupshelpers
00025 import installpackage
00026 import os
00027 import subprocess
00028 from timedops import TimedOperation, TimedSubprocess
00029 from base import *
00030 
00031 class CheckPPDSanity(Question):
00032     def __init__ (self, troubleshooter):
00033         Question.__init__ (self, troubleshooter, "Check PPD sanity")
00034         vbox = gtk.VBox ()
00035         vbox.set_border_width (12)
00036         vbox.set_spacing (12)
00037         self.label = gtk.Label ()
00038         self.label.set_line_wrap (True)
00039         self.label.set_use_markup (True)
00040         self.label.set_alignment (0, 0)
00041         vbox.pack_start (self.label, False, False, 0)
00042 
00043         box = gtk.HButtonBox ()
00044         box.set_layout (gtk.BUTTONBOX_START)
00045         self.install_button = gtk.Button (_("Install"))
00046         box.add (self.install_button)
00047         # Although we want this hidden initially,
00048         # troubleshooter.new_page will call show_all() on the widget
00049         # we give it.  We'll need to hide this button in the display()
00050         # callback instead.
00051         vbox.pack_start (box, False, False, 0)
00052 
00053         troubleshooter.new_page (vbox, self)
00054 
00055     def display (self):
00056         self.answers = {}
00057 
00058         answers = self.troubleshooter.answers
00059         if not answers['cups_queue_listed']:
00060             return False
00061 
00062         parent = self.troubleshooter.get_window ()
00063         name = answers['cups_queue']
00064         tmpf = None
00065         try:
00066             cups.setServer ('')
00067             self.op = TimedOperation (cups.Connection, parent=parent)
00068             c = self.op.run ()
00069             self.op = TimedOperation (c.getPPD, args=(name,), parent=parent)
00070             tmpf = self.op.run ()
00071         except RuntimeError:
00072             return False
00073         except cups.IPPError:
00074             return False
00075 
00076         self.install_button.hide ()
00077         title = None
00078         text = None
00079         try:
00080             ppd = cups.PPD (tmpf)
00081             self.answers['cups_printer_ppd_valid'] = True
00082 
00083             def options (options_list):
00084                 o = {}
00085                 for option in options_list:
00086                     o[option.keyword] = option.defchoice
00087                 return o
00088 
00089             defaults = {}
00090             for group in ppd.optionGroups:
00091                 g = options (group.options)
00092                 for subgroup in group.subgroups:
00093                     g[subgroup.name] = options (subgroup.options)
00094                 defaults[group.name] = g
00095             self.answers['cups_printer_ppd_defaults'] = defaults
00096         except RuntimeError:
00097             title = _("Invalid PPD File")
00098             self.answers['cups_printer_ppd_valid'] = False
00099             try:
00100                 self.op = TimedSubprocess (parent=parent,
00101                                            args=['cupstestppd', '-rvv', tmpf],
00102                                            close_fds=True,
00103                                            stdin=file("/dev/null"),
00104                                            stdout=subprocess.PIPE,
00105                                            stderr=subprocess.PIPE)
00106                 result = self.op.run ()
00107                 self.answers['cupstestppd_output'] = result
00108                 text = _("The PPD file for printer '%s' does not conform "
00109                          "to the specification.  "
00110                          "Possible reason follows:") % name
00111                 text += '\n' + reduce (lambda x, y: x + '\n' + y, result[0])
00112             except OSError:
00113                 # Perhaps cupstestppd is not in the path.
00114                 text = _("There is a problem with the PPD file for "
00115                          "printer '%s'.") % name
00116 
00117         if tmpf:
00118             os.unlink (tmpf)
00119 
00120         if title == None and not answers['cups_printer_remote']:
00121             (pkgs, exes) = cupshelpers.missingPackagesAndExecutables (ppd)
00122             self.answers['missing_pkgs_and_exes'] = (pkgs, exes)
00123             if len (pkgs) > 0 or len (exes) > 0:
00124                 title = _("Missing Printer Driver")
00125                 if len (pkgs) > 0:
00126                     try:
00127                         self.packagekit = installpackage.PackageKit ()
00128                     except:
00129                         pkgs = []
00130 
00131                 if len (pkgs) > 0:
00132                     self.package = pkgs[0]
00133                     text = _("Printer '%s' requires the %s package but it "
00134                              "is not currently installed.") % (name,
00135                                                                self.package)
00136                     self.install_button.show ()
00137                 else:
00138                     text = _("Printer '%s' requires the '%s' program but it "
00139                              "is not currently installed.") % (name,
00140                                                                (exes + pkgs)[0])
00141 
00142         if title != None:
00143             self.label.set_markup ('<span weight="bold" size="larger">' +
00144                                    title + '</span>\n\n' + text)
00145 
00146         return title != None
00147 
00148     def connect_signals (self, handle):
00149         self.button_sigid = self.install_button.connect ("clicked",
00150                                                          self.install_clicked)
00151 
00152     def disconnect_signals (self):
00153         self.install_button.disconnect (self.button_sigid)
00154 
00155     def collect_answer (self):
00156         return self.answers
00157 
00158     def cancel_operation (self):
00159         self.op.cancel ()
00160 
00161     def install_clicked (self, button):
00162         pkgs = self.answers.get('packages_installed', [])
00163         pkgs.append (self.package)
00164         self.answers['packages_installed'] = pkgs
00165         try:
00166             self.packagekit.InstallPackageName (0, 0, self.package)
00167         except:
00168             pass