2 # -*- coding: utf-8 -*-
4 # (c) Copyright 2011-2014 Hewlett-Packard Development Company, L.P.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # Author: Amarnath Chitumalla
24 __title__ = 'AutoConfig Utility to check queues configuration'
25 __mod__ = 'hp-daignose-queues'
26 __doc__ = """Auto config utility for HPLIP supported multifunction Devices to diagnose queues configuration."""
37 from base import utils, tui, models
39 from installer import core_install
47 DEVICE_URI_PATTERN = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*)|zc=(\S+))(?:&port=(\d))?""", re.I)
48 NICKNAME_PATTERN = re.compile(r'''\*NickName:\s*\"(.*)"''', re.MULTILINE)
49 NET_PATTERN = re.compile(r"""(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})""")
50 NET_ZC_PATTERN = re.compile(r'''zc=(.*)''',re.IGNORECASE)
51 NET_OTHER_PATTERN = re.compile(r'''(.*)://(.*)''',re.IGNORECASE)
52 USB_PATTERN = re.compile(r'''serial=(.*)''',re.IGNORECASE)
53 LPSTAT_PATTERN = re.compile(r"""(\S*): (.*)""", re.IGNORECASE)
54 #BACK_END_PATTERN = re.compile(r'''(.*):(.*)''',re.IGNORECASE)
58 def usage(typ='text'):
60 utils.log_title(__title__, __version__)
61 utils.format_text(USAGE, typ, __title__, __mod__, __version__)
65 # Checks 'lp' group is added o not
66 def check_user_groups():
68 sts,output = utils.run('groups')
70 log.error("Failed to get groups")
72 output = output.rstrip('\r\n')
73 log.debug("groups =%s "%output)
74 grp_list= output.split(' ')
76 while cnt < len(grp_list) :
77 if grp_list[cnt] == 'lp':
84 # This function adds the groups ('lp') to user
87 add_user_to_group = core.get_distro_ver_data('add_user_to_group', '')
89 usermod = os.path.join(utils.which("usermod"), "usermod") + " %s %s" % (add_user_to_group, prop.username)
91 usermod = os.path.join(utils.which("usermod"), "usermod") + " %s %s" % ("-Glp", prop.username)
93 su_sudo = utils.su_sudo()
96 name,version,is_su = utils.os_release()
97 log.debug("name = %s version = %s is_su = %s" %(name,version,is_su))
98 if ( name == 'Fedora' and version >= '14' and is_su == True):
99 #using su opening GUI apps fail in Fedora 14.
100 #To run GUI apps as root, you need a root login shell (su -) in Fedora 14
101 su_sudo = 'su - -c "%s"'
103 su_sudo = 'su -c "%s"'
105 password_f = "get_password_ui"
106 # password_f = utils.get_password
107 cmd =su_sudo % usermod
108 log.info("cmd = %s" %cmd)
109 # sts, output = utils.run(cmd, True, password_f, -1,True,cmd)
110 sts, output = utils.run(cmd, True, password_f, 1, True, "Please enter root/superuser password to add 'lp' group")
117 # This parse the given Device URI. and provides the details.
118 def parseDeviceURI(device_uri):
119 m = DEVICE_URI_PATTERN.match(device_uri)
121 raise Error(ERROR_INVALID_DEVICE_URI)
123 back_end = m.group(1).lower() or ''
124 is_hp = (back_end in ('hp', 'hpfax', 'hpaio'))
125 bus = m.group(2).lower() or ''
127 if bus not in ('usb', 'net', 'bt', 'fw', 'par'):
128 raise Error(ERROR_INVALID_DEVICE_URI)
130 model =m.group(3) or ''
131 serial = m.group(4) or ''
132 dev_file = m.group(5) or ''
133 host = m.group(6) or ''
136 zc = host = m.group(7) or ''
137 port = m.group(8) or 1
142 except (ValueError, TypeError):
148 # log.warning("++++: back_end '%s' is_hp '%s' bus '%s' model '%s' serial '%s' dev_file '%s' host '%s' zc '%s' port '%s' " %
149 # ( back_end, is_hp, bus, model, serial, dev_file, host, zc, port))
151 return back_end, is_hp, bus, model, serial, dev_file, host, zc, port
154 ####### Device class ########
155 class DetectedDevice:
156 def __init__(self, Printer_Name,Device_URI,Device_Type, ppdType, PPDFileError = False, IsEnabled=True ):
157 self.PrinterName =Printer_Name
158 self.DeviceURI = Device_URI
159 self.DeviceType = Device_Type
160 self.PPDFileType = ppdType
161 self.PPDFileError = PPDFileError
162 self.IsEnabled = IsEnabled
167 #########Main##########
168 USAGE = [(__doc__, "", "name", True),
169 ("Usage: %s [OPTIONS]" % __mod__, "", "summary", True),
171 utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
176 log.set_module(__mod__)
179 opts, args = getopt.getopt(sys.argv[1:], 'hl:gsr', ['help', 'help-rest', 'help-man', 'help-desc', 'logging='])
181 except getopt.GetoptError, e:
186 if os.getenv("HPLIP_DEBUG"):
187 log.set_level('debug')
193 if o in ('-h', '--help'):
196 elif o == '--help-rest':
199 elif o == '--help-man':
202 elif o == '--help-desc':
206 elif o in ('-l', '--logging'):
207 log_level = a.lower().strip()
218 if not log.set_level(log_level):
221 utils.log_title(__title__, __version__)
223 log_file = os.path.normpath('/var/loh/hp/hplip_queues.log')
224 log.debug(log.bold("Saving output in log file: %s" % log_file))
225 if os.path.exists(log_file):
227 log.set_logfile(log_file)
228 log.set_where(log.LOG_TO_CONSOLE_AND_FILE)
231 from base import device, pml
232 # This can fail due to hpmudext not being present
234 log.error("Device library is not avail.")
237 # Only Qt4 is supported.
239 from PyQt4.QtGui import QApplication, QMessageBox
240 from ui4.queuesconf import QueuesDiagnose
242 log.error("Unable to load Qt4 support. Is it installed?")
245 app = QApplication(sys.argv)
247 if check_user_groups() is False:
248 dialog = QueuesDiagnose(None, "","",QUEUES_MSG_SENDING)
249 core = core_install.CoreInstall()
251 if add_group(core) is False:
253 #log.error("Failed to add lp group to user[%s]. Manually add 'lp' group to usergroups"%prop.username)
254 dialog.showMessage("User must be part of 'lp' group.\nManually add 'lp' group to '%s' user. " %prop.username)
256 dialog.showSuccessMessage("Groups added successfully and reboot is required. Please reboot system to take effect.")
259 is_hpcups_installed = to_bool(sys_conf.get('configure', 'hpcups-install', '0'))
260 is_hpijs_installed = to_bool(sys_conf.get('configure', 'hpijs-install', '0'))
261 # tui.header("INSTALLED CUPS PRINTER QUEUES")
264 status, output = utils.run('lpstat -v')
267 for p in output.splitlines():
269 match = LPSTAT_PATTERN.search(p)
270 printer_name = match.group(1)
271 device_uri = match.group(2)
272 cups_printers.append((printer_name, device_uri))
273 except AttributeError:
276 log.debug(cups_printers)
277 log.debug("HPCups installation=%d HPIJS installation =%d" %(is_hpcups_installed, is_hpijs_installed))
281 for p in cups_printers:
282 printer_name, device_uri = p
284 if device_uri.startswith("cups-pdf:/"):
287 log.debug(log.bold(printer_name))
288 log.debug(log.bold('-'*len(printer_name)))
291 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = parseDeviceURI(device_uri)
293 back_end, is_hp, bus, model, serial, dev_file, host, zc, port = '', False, '', '', '', '', '', '', 1
294 if 'HP' in device_uri:
297 log.debug("Device URI: %s" % device_uri)
298 ppd_file = os.path.join('/etc/cups/ppd', printer_name + '.ppd')
299 if os.path.exists(ppd_file):
300 log.debug("PPD: %s" % ppd_file)
302 fileptr = file(ppd_file, 'r').read(4096)
304 desc = NICKNAME_PATTERN.search(fileptr).group(1)
305 except AttributeError:
308 log.debug("PPD Description: %s" % desc)
309 status, output = utils.run('lpstat -p%s' % printer_name)
310 log.debug("Printer status: %s" % output.replace("\n", ""))
312 #### checking for USb devices ####
313 if USB_PATTERN.search(device_uri):
314 Key =USB_PATTERN.search(device_uri).group(1)
315 #### checking for network devices ####
316 elif NET_PATTERN.search(device_uri):
317 Key = NET_PATTERN.search(device_uri).group(1)
318 elif NET_ZC_PATTERN.search(device_uri):
319 Key = NET_ZC_PATTERN.search(device_uri).group(1)
320 elif NET_OTHER_PATTERN.search(device_uri):
321 part_1 = NET_OTHER_PATTERN.search(device_uri).group(1)
322 part_2 = NET_OTHER_PATTERN.search(device_uri).group(2)
326 log.info("unknown protocol device_uri=%s" %device_uri)
329 log.info("unknown protocol device_uri=%s" %device_uri)
333 Is_Print_Q_Enabled= True
334 if output.find('Paused') != -1:
335 Is_Print_Q_Enabled= False
337 log.debug("Key'%s': deviceType '%s' is_hp '%s' bus '%s' model '%s' serial '%s' dev_file '%s' host '%s' zc '%s' port '%s' Enabled'%d'"\
338 %( Key,back_end, is_hp, bus, model, serial, dev_file, host, zc, port,Is_Print_Q_Enabled))
341 if back_end == 'hpfax' and not 'HP Fax' in desc:
342 log.error("Incorrect PPD file for fax queue '%s'. Fax queue must use 'HP-Fax-hplip.ppd'." % printer_name)
344 elif back_end == 'hp' and 'HP Fax' in desc:
345 log.error("Incorrect PPD file for print queue '%s'. Print queue must not use 'HP-Fax-hplip.ppd'." % printer_name)
347 elif back_end not in ('hp', 'hpfax'):
348 log.warn("Device %s is not HPLIP installed. Device must use the hp: or hpfax: to function in HPLIP."% printer_name)
352 ppd_fileType = HPCUPS
353 if not is_hpcups_installed:
355 elif 'hpijs' in desc:
357 if not is_hpijs_installed:
359 elif 'Postscript' in desc:
362 ppd_fileType =HPOTHER
365 if ppd_fileType != None:
366 device1 =DetectedDevice(printer_name, device_uri,back_end, ppd_fileType,PPDFileError, Is_Print_Q_Enabled)
367 if Key in mapofDevices:
368 mapofDevices[Key].append(device1)
371 mapofDevices[Key]=deviceList
373 log.warn("%s is not HP Device." %(printer_name))
375 for key,val in mapofDevices.items():
378 log.warn('%d queues of same device %s is configured. Remove unwanted queues.' %(len(val),val[0].PrinterName))
381 dialog = QueuesDiagnose(None, "","",QUEUES_MSG_SENDING)
382 dialog.showMessage("%d queues of same device %s is configured.\nRemove unwanted queues."%(len(val),val[0].PrinterName))
386 if 'hp' in que.DeviceType or 'hpfax' in que.DeviceType:
387 if que.PPDFileError == False:
388 log.debug("'%s' is configured correctly." %(que.PrinterName))
390 log.error("PPD file for '%s' is not correct. Need to choose correct PPD file." %(que.PrinterName))
391 Error_msg = QUEUES_INCORRECT_PPD
393 log.error("'%s' is not configured using HPLIP. Need to remove and re-cofigure from hp-setup." %(que.PrinterName))
394 Error_msg =QUEUES_CONFIG_ERROR
396 if Error_msg ==None and que.IsEnabled == False:
397 Error_msg = QUEUES_PAUSED
399 if Error_msg != None:
401 dialog = QueuesDiagnose(None, que.PrinterName,que.DeviceURI,Error_msg)
403 log.debug("Starting GUI loop...")
408 log.debug("Single print queue is configured for '%s'. " %val[0].PrinterName)
409 if 'hp' in val[0].DeviceType or 'hpfax' in val[0].DeviceType:
410 if val[0].PPDFileError == False:
411 log.debug("'%s' is configured correctly." %(val[0].PrinterName))
413 log.error("PPD file for '%s' is not correct. Need to choose correct PPD file." %(val[0].PrinterName))
414 Error_msg = QUEUES_INCORRECT_PPD
416 log.error("'%s' is not configured using HPLIP. Need to remove and re-configure using hp-setup." %(val[0].PrinterName))
417 Error_msg = QUEUES_CONFIG_ERROR
419 if Error_msg ==None and val[0].IsEnabled == False:
420 Error_msg = QUEUES_PAUSED
422 if Error_msg != None:
424 name = val[0].PrinterName
425 dialog = QueuesDiagnose(None, name, val[0].DeviceURI, Error_msg)
427 log.debug("Starting GUI loop...")
430 log.debug("No queues found.")
432 if Show_result and (Error_Found is False):
433 dialog = QueuesDiagnose(None, "","",QUEUES_MSG_SENDING)
434 dialog.showSuccessMessage("Queue(s) configured correctly using HPLIP.")
437 except KeyboardInterrupt:
438 log.error("User exit")