Fixed build error by changing buildrequires from pkgconfig(turbo-jpeg) to libjpeg...
[platform/upstream/hplip.git] / setup.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # (c) Copyright 2003-2009 Hewlett-Packard Development Company, L.P.
5 #
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.
10 #
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.
15 #
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
19 #
20 # Author: Don Welch
21 #
22
23
24 __version__ = '9.0'
25 __title__ = 'Printer/Fax Setup Utility'
26 __mod__ = 'hp-setup'
27 __doc__ = "Installs HPLIP printers and faxes in the CUPS spooler. Tries to automatically determine the correct PPD file to use. Allows the printing of a testpage. Performs basic fax parameter setup."
28
29 # Std Lib
30 import sys
31 import getopt
32 import time
33 import os.path
34 import re
35 import os
36 import gzip
37
38 try:
39     import readline
40 except ImportError:
41     pass
42
43 # Local
44 from base.g import *
45 from base import device, utils, tui, models, module
46 from prnt import cups
47
48 pm = None
49
50 def plugin_download_callback(c, s, t):
51     pm.update(int(100*c*s/t),
52              utils.format_bytes(c*s))
53
54
55 nickname_pat = re.compile(r'''\*NickName:\s*\"(.*)"''', re.MULTILINE)
56
57 USAGE = [ (__doc__, "", "name", True),
58           ("Usage: %s [MODE] [OPTIONS] [SERIAL NO.|USB bus:device|IP|DEVNODE]" % __mod__, "", "summary", True),
59           utils.USAGE_MODE,
60           utils.USAGE_GUI_MODE,
61           utils.USAGE_INTERACTIVE_MODE,
62           utils.USAGE_SPACE,
63           utils.USAGE_OPTIONS,
64           ("Automatic mode:", "-a or --auto (-i mode only)", "option", False),
65           ("To specify the port on a multi-port JetDirect:", "--port=<port> (Valid values are 1\*, 2, and 3. \*default)", "option", False),
66           ("No testpage in automatic mode:", "-x (-i mode only)", "option", False),
67           ("To specify a CUPS printer queue name:", "-p<printer> or --printer=<printer> (-i mode only)", "option", False),
68           ("To specify a CUPS fax queue name:", "-f<fax> or --fax=<fax> (-i mode only)", "option", False),
69           ("Type of queue(s) to install:", "-t<typelist> or --type=<typelist>. <typelist>: print*, fax\* (\*default) (-i mode only)", "option", False),
70           ("To specify the device URI to install:", "-d<device> or --device=<device> (--qt4 mode only)", "option", False),
71           ("Remove printers or faxes instead of setting-up:", "-r or --rm or --remove (-u only)", "option", False),
72           utils.USAGE_LANGUAGE,
73           utils.USAGE_LOGGING1, utils.USAGE_LOGGING2, utils.USAGE_LOGGING3,
74           utils.USAGE_HELP,
75           ("[SERIAL NO.|USB ID|IP|DEVNODE]", "", "heading", False),
76           ("USB bus:device (usb only):", """"xxx:yyy" where 'xxx' is the USB bus and 'yyy' is the USB device. (Note: The ':' and all leading zeros must be present.)""", 'option', False),
77           ("", "Use the 'lsusb' command to obtain this information.", "option", False),
78           ("IPs (network only):", 'IPv4 address "a.b.c.d" or "hostname"', "option", False),
79           ("DEVNODE (parallel only):", '"/dev/parportX", X=0,1,2,...', "option", False),
80           ("SERIAL NO. (usb and parallel only):", '"serial no."', "option", True),
81           utils.USAGE_EXAMPLES,
82           ("Setup using GUI mode:", "$ hp-setup", "example", False),
83           ("Setup using GUI mode, specifying usb:", "$ hp-setup -b usb", "example", False),
84           ("Setup using GUI mode, specifying an IP:", "$ hp-setup 192.168.0.101", "example", False),
85           ("One USB printer attached, automatic:", "$ hp-setup -i -a", "example", False),
86           ("USB, IDs specified:", "$ hp-setup -i 001:002", "example", False),
87           ("Network:", "$ hp-setup -i 66.35.250.209", "example", False),
88           ("Network, Jetdirect port 2:", "$ hp-setup -i --port=2 66.35.250.209", "example", False),
89           ("Parallel:", "$ hp-setup -i /dev/parport0", "example", False),
90           ("USB or parallel, using serial number:", "$ hp-setup -i US12345678A", "example", False),
91           ("USB, automatic:", "$ hp-setup -i --auto 001:002", "example", False),
92           ("Parallel, automatic, no testpage:", "$ hp-setup -i -a -x /dev/parport0", "example", False),
93           ("Parallel, choose device:", "$ hp-setup -i -b par", "example", False),
94           utils.USAGE_SPACE,
95           utils.USAGE_NOTES,
96           ("1. If no serial number, USB ID, IP, or device node is specified, the USB and parallel busses will be probed for devices.", "", 'note', False),
97           ("2. Using 'lsusb' to obtain USB IDs: (example)", "", 'note', False),
98           ("   $ lsusb", "", 'note', False),
99           ("         Bus 003 Device 011: ID 03f0:c202 Hewlett-Packard", "", 'note', False),
100           ("   $ hp-setup --auto 003:011", "", 'note', False),
101           ("   (Note: You may have to run 'lsusb' from /sbin or another location. Use '$ locate lsusb' to determine this.)", "", 'note', True),
102           ("3. Parameters -a, -f, -p, or -t are not valid in GUI (-u) mode.", "", 'note', True),
103           utils.USAGE_SPACE,
104           utils.USAGE_SEEALSO,
105           ("hp-makeuri", "", "seealso", False),
106           ("hp-probe", "", "seealso", False),
107         ]
108
109
110 def showPasswordUI(prompt):
111     import getpass
112     print ""
113     print log.bold(prompt)
114     username = raw_input("Username: ")
115     password = getpass.getpass("Password: ")
116
117     return (username, password)
118
119
120 def restart_cups():
121     if os.path.exists('/etc/init.d/cups'):
122         return '/etc/init.d/cups restart'
123
124     elif os.path.exists('/etc/init.d/cupsys'):
125         return '/etc/init.d/cupsys restart'
126
127     else:
128         return 'killall -HUP cupsd'
129
130
131 mod = module.Module(__mod__, __title__, __version__, __doc__, USAGE,
132                     (INTERACTIVE_MODE, GUI_MODE),
133                     (UI_TOOLKIT_QT3, UI_TOOLKIT_QT4),
134                     run_as_root_ok=True)
135
136 opts, device_uri, printer_name, mode, ui_toolkit, loc = \
137     mod.parseStdOpts('axp:P:f:t:b:d:rq',
138                      ['ttl=', 'filter=', 'search=', 'find=',
139                       'method=', 'time-out=', 'timeout=',
140                       'printer=', 'fax=', 'type=', 'port=',
141                        'auto', 'device=', 'rm', 'remove'],
142                       handle_device_printer=False)
143
144 selected_device_name = None
145 printer_name = None
146 fax_name = None
147 bus = None
148 setup_print = True
149 setup_fax = True
150 makeuri = None
151 auto = False
152 testpage_in_auto_mode = True
153 jd_port = 1
154 remove = False
155 ignore_plugin_check = False
156
157 for o, a in opts:
158     if o == '-x':
159         testpage_in_auto_mode = False
160
161     elif o in ('-P', '-p', '--printer'):
162         printer_name = a
163
164     elif o in ('-f', '--fax'):
165         fax_name = a
166
167     elif o in ('-d', '--device'):
168         device_uri = a
169
170     elif o in ('-b', '--bus'):
171         bus = [x.lower().strip() for x in a.split(',')]
172         if not device.validateBusList(bus, False):
173             mod.usage(error_msg=['Invalid bus name'])
174
175     elif o in ('-t', '--type'):
176         setup_fax, setup_print = False, False
177         a = a.strip().lower()
178         for aa in a.split(','):
179             if aa.strip() not in ('print', 'fax'):
180                 mod.usage(error_msg=['Invalid type.'])
181
182             if aa.strip() == 'print':
183                 setup_print = True
184
185             elif aa.strip() == 'fax':
186                 if not prop.fax_build:
187                     log.error("Cannot enable fax setup - HPLIP not built with fax enabled.")
188                 else:
189                     setup_fax = True
190
191     elif o == '--port':
192         try:
193             jd_port = int(a)
194         except ValueError:
195             #log.error("Invalid port number. Must be between 1 and 3 inclusive.")
196             mod.usage(error_msg=['Invalid port number. Must be between 1 and 3 inclusive.'])
197
198     elif o in ('-a', '--auto'):
199         auto = True
200
201     elif o in ('-r', '--rm', '--remove'):
202         remove = True
203     elif o in ('-q'):
204         ignore_plugin_check = True
205
206
207 try:
208     param = mod.args[0]
209 except IndexError:
210     param = ''
211
212 log.debug("param=%s" % param)
213
214 if printer_name is not None:
215    selected_device_name = printer_name
216 else:
217    if fax_name is not None:
218       selected_device_name = fax_name
219 log.debug("selected_device_name=%s" % selected_device_name)
220
221 if mode == GUI_MODE:
222     if selected_device_name is not None: 
223         log.warning("-p or -f option is not supported")
224     if ui_toolkit == 'qt3':
225         if not utils.canEnterGUIMode():
226             log.error("%s requires GUI support (try running with --qt4). Also, try using interactive (-i) mode." % __mod__)
227             sys.exit(1)
228     else:
229         if not utils.canEnterGUIMode4():
230             log.error("%s requires GUI support (try running with --qt3). Also, try using interactive (-i) mode." % __mod__)
231             sys.exit(1)
232
233 if mode == GUI_MODE:
234     if ui_toolkit == 'qt3':
235         try:
236             from qt import *
237             from ui import setupform
238         except ImportError:
239             log.error("Unable to load Qt3 support. Is it installed?")
240             sys.exit(1)
241
242         if remove:
243             log.warn("-r/--rm/--remove not supported in qt3 mode.")
244
245         app = QApplication(sys.argv)
246         QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()"))
247
248         if loc is None:
249             loc = user_conf.get('ui', 'loc', 'system')
250             if loc.lower() == 'system':
251                 loc = str(QTextCodec.locale())
252                 log.debug("Using system locale: %s" % loc)
253
254         if loc.lower() != 'c':
255             e = 'utf8'
256             try:
257                 l, x = loc.split('.')
258                 loc = '.'.join([l, e])
259             except ValueError:
260                 l = loc
261                 loc = '.'.join([loc, e])
262
263             log.debug("Trying to load .qm file for %s locale." % loc)
264             trans = QTranslator(None)
265
266             qm_file = 'hplip_%s.qm' % l
267             log.debug("Name of .qm file: %s" % qm_file)
268             loaded = trans.load(qm_file, prop.localization_dir)
269
270             if loaded:
271                 app.installTranslator(trans)
272             else:
273                 loc = 'c'
274
275         if loc == 'c':
276             log.debug("Using default 'C' locale")
277         else:
278             log.debug("Using locale: %s" % loc)
279             QLocale.setDefault(QLocale(loc))
280             prop.locale = loc
281             try:
282                 locale.setlocale(locale.LC_ALL, locale.normalize(loc))
283             except locale.Error:
284                 pass
285
286         try:
287             w = setupform.SetupForm(bus, param, jd_port)
288         except Error:
289             log.error("Unable to connect to HPLIP I/O. Please (re)start HPLIP and try again.")
290             sys.exit(1)
291
292         app.setMainWidget(w)
293         w.show()
294
295         app.exec_loop()
296
297     else: # qt4
298         try:
299             from PyQt4.QtGui import QApplication, QMessageBox
300             from ui4.setupdialog import SetupDialog
301         except ImportError:
302             log.error("Unable to load Qt4 support. Is it installed?")
303             sys.exit(1)
304
305         app = QApplication(sys.argv)
306         log.debug("Sys.argv=%s printer_name=%s param=%s jd_port=%s device_uri=%s remove=%s" % (sys.argv, printer_name, param, jd_port, device_uri, remove))
307         dlg = SetupDialog(None, param, jd_port, device_uri, remove)
308         dlg.show()
309         try:
310             log.debug("Starting GUI loop...")
311             app.exec_()
312         except KeyboardInterrupt:
313             sys.exit(0)
314
315
316 else: # INTERACTIVE_MODE
317     try:
318
319         cups.setPasswordCallback(showPasswordUI)
320
321         if remove:
322             log.error("-r/--rm/--remove not supported in -i mode.")
323             sys.exit(1)
324
325         if not auto:
326             log.info("(Note: Defaults for each question are maked with a '*'. Press <enter> to accept the default.)")
327             log.info("")
328
329         # ******************************* MAKEURI
330         if param:
331             device_uri, sane_uri, fax_uri = device.makeURI(param, jd_port)
332
333         # ******************************* CONNECTION TYPE CHOOSER
334         if not device_uri and bus is None:
335             bus = tui.connection_table()
336
337             if bus is None:
338                 sys.exit(0)
339
340             log.info("\nUsing connection type: %s" % bus[0])
341
342             log.info("")
343
344         # ******************************* DEVICE CHOOSER
345
346         if not device_uri:
347             log.debug("\nDEVICE CHOOSER setup_fax=%s, setup_print=%s" % (setup_fax, setup_print))
348             device_uri = mod.getDeviceUri(device_uri, selected_device_name, devices = device.probeDevices(bus))
349
350
351         # ******************************* QUERY MODEL AND COLLECT PPDS
352         log.info(log.bold("\nSetting up device: %s\n" % device_uri))
353
354         log.info("")
355         print_uri = device_uri.replace("hpfax:", "hp:")
356         fax_uri = device_uri.replace("hp:", "hpfax:")
357
358         back_end, is_hp, bus, model, \
359             serial, dev_file, host, zc, port = \
360             device.parseDeviceURI(device_uri)
361
362         log.debug("Model=%s" % model)
363         mq = device.queryModelByURI(device_uri)
364
365         if not mq or mq.get('support-type', SUPPORT_TYPE_NONE) == SUPPORT_TYPE_NONE:
366             log.error("Unsupported printer model.")
367             sys.exit(1)
368
369         if mq.get('fax-type', FAX_TYPE_NONE) in (FAX_TYPE_NONE, FAX_TYPE_NOT_SUPPORTED) and setup_fax:
370             #log.warning("Cannot setup fax - device does not have fax feature.")
371             setup_fax = False
372
373         # ******************************* PLUGIN
374
375         norm_model = models.normalizeModelName(model).lower()
376         plugin = mq.get('plugin', PLUGIN_NONE)
377
378         plugin_installed = utils.to_bool(sys_state.get('plugin', 'installed', '0'))
379         if ignore_plugin_check is False and plugin > PLUGIN_NONE and not plugin_installed:
380             tui.header("PLUG-IN INSTALLATION")
381
382             hp_plugin = utils.which('hp-plugin')
383
384             if hp_plugin:
385                 if prop.gui_build:
386                     os.system("hp-plugin -i")
387                 else:
388                     os.system("hp-plugin")
389
390         ppds = cups.getSystemPPDs()
391
392         default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
393         stripped_model = cups.stripModel2(default_model)
394
395         installed_print_devices = device.getSupportedCUPSDevices(['hp'])
396         for d in installed_print_devices.keys():
397             for p in installed_print_devices[d]:
398                 log.debug("found print queue '%s'" % p)
399
400         installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
401         for d in installed_fax_devices.keys():
402             for f in installed_fax_devices[d]:
403                 log.debug("found fax queue '%s'" % f)
404
405         # ******************************* PRINT QUEUE SETUP
406         if setup_print:
407
408             tui.header("PRINT QUEUE SETUP")
409
410             if not auto and print_uri in installed_print_devices:
411                 log.warning("One or more print queues already exist for this device: %s." %
412                     ', '.join(installed_print_devices[print_uri]))
413
414                 ok, setup_print = tui.enter_yes_no("\nWould you like to install another print queue for this device", 'n')
415                 if not ok: sys.exit(0)
416
417         if setup_print:
418             if auto:
419                 printer_name = default_model
420
421             printer_default_model = default_model
422
423             installed_printer_names = device.getSupportedCUPSPrinterNames(['hp'])
424             # Check for duplicate names
425             if (device_uri in installed_print_devices and printer_default_model in installed_print_devices[device_uri]) \
426                or (printer_default_model in installed_printer_names):
427                     i = 2
428                     while True:
429                         t = printer_default_model + "_%d" % i
430                         if (t not in installed_printer_names) and(device_uri not in installed_print_devices or t not in installed_print_devices[device_uri]):
431                             printer_default_model += "_%d" % i
432                             break
433                         i += 1
434
435             if not auto:
436                 if printer_name is None:
437                     while True:
438                         printer_name = raw_input(log.bold("\nPlease enter a name for this print queue (m=use model name:'%s'*, q=quit) ?" % printer_default_model))
439
440                         if printer_name.lower().strip() == 'q':
441                             log.info("OK, done.")
442                             sys.exit(0)
443
444                         if not printer_name or printer_name.lower().strip() == 'm':
445                             printer_name = printer_default_model
446
447                         name_ok = True
448
449                         for d in installed_print_devices.keys():
450                             for p in installed_print_devices[d]:
451                                 if printer_name == p:
452                                     log.error("A print queue with that name already exists. Please enter a different name.")
453                                     name_ok = False
454                                     break
455
456                         for d in installed_fax_devices.keys():
457                             for f in installed_fax_devices[d]:
458                                 if printer_name == f:
459                                     log.error("A fax queue with that name already exists. Please enter a different name.")
460                                     name_ok = False
461                                     break
462
463                         for c in printer_name:
464                             if c in cups.INVALID_PRINTER_NAME_CHARS:
465                                 log.error("Invalid character '%s' in printer name. Please enter a name that does not contain this character." % c)
466                                 name_ok = False
467
468                         if name_ok:
469                             break
470             else:
471                 printer_name = printer_default_model
472
473             log.info("Using queue name: %s" % printer_name)
474
475             default_model = utils.xstrip(model.replace('series', '').replace('Series', ''), '_')
476             stripped_model = default_model.lower().replace('hp-', '').replace('hp_', '')
477
478             log.info("Locating PPD file... Please wait.")
479             print_ppd = cups.getPPDFile2(stripped_model, ppds)
480             enter_ppd = False
481
482             if print_ppd is None:
483                 enter_ppd = True
484                 log.error("Unable to find an appropriate PPD file.")
485
486             else:
487                 print_ppd, desc = print_ppd
488                 log.info("\nFound PPD file: %s" % print_ppd)
489
490                 if desc:
491                     log.info("Description: %s" % desc)
492 #
493                     if not auto:
494                         log.info("\nNote: The model number may vary slightly from the actual model number on the device.")
495                         ok, ans = tui.enter_yes_no("\nDoes this PPD file appear to be the correct one")
496                         if not ok: sys.exit(0)
497                         if not ans: enter_ppd = True
498
499
500             if enter_ppd:
501                 enter_ppd = False
502
503                 ok, enter_ppd = tui.enter_yes_no("\nWould you like to specify the path to the correct PPD file to use", 'n')
504                 if not ok: sys.exit(0)
505
506                 if enter_ppd:
507                     ok = False
508
509                     while True:
510                         user_input = raw_input(log.bold("\nPlease enter the full filesystem path to the PPD file to use (q=quit) :"))
511
512                         if user_input.lower().strip() == 'q':
513                             log.info("OK, done.")
514                             sys.exit(0)
515
516                         file_path = user_input
517
518                         if os.path.exists(file_path) and os.path.isfile(file_path):
519
520                             if file_path.endswith('.gz'):
521                                 nickname = gzip.GzipFile(file_path, 'r').read(4096)
522                             else:
523                                 nickname = file(file_path, 'r').read(4096)
524
525                             try:
526                                 desc = nickname_pat.search(nickname).group(1)
527                             except AttributeError:
528                                 desc = ''
529
530                             if desc:
531                                 log.info("Description for the file: %s" % desc)
532                             else:
533                                 log.error("No PPD 'NickName' found. This file may not be a valid PPD file.")
534
535                             ok, ans = tui.enter_yes_no("\nUse this file")
536                             if not ok: sys.exit(0)
537                             if ans: print_ppd = file_path
538
539                         else:
540                             log.error("File not found or not an appropriate (PPD) file.")
541
542                         if ok:
543                             break
544                 else:
545                     log.error("PPD file required. Setup cannot continue. Exiting.")
546                     sys.exit(1)
547
548             if auto:
549                 location, info = '', 'Automatically setup by HPLIP'
550             else:
551                 while True:
552                     location = raw_input(log.bold("Enter a location description for this printer (q=quit) ?"))
553
554                     if location.strip().lower() == 'q':
555                         log.info("OK, done.")
556                         sys.exit(0)
557
558                     # TODO: Validate chars
559                     break
560
561                 while True:
562                     info = raw_input(log.bold("Enter additonal information or notes for this printer (q=quit) ?"))
563
564                     if info.strip().lower() == 'q':
565                         log.info("OK, done.")
566                         sys.exit(0)
567
568                     # TODO: Validate chars
569                     break
570
571             log.info(log.bold("\nAdding print queue to CUPS:"))
572             log.info("Device URI: %s" % print_uri)
573             log.info("Queue name: %s" % printer_name)
574             log.info("PPD file: %s" % print_ppd)
575             log.info("Location: %s" % location)
576             log.info("Information: %s" % info)
577
578             log.debug("Restarting CUPS...")
579             status, output = utils.run(restart_cups())
580             log.debug("Restart CUPS returned: exit=%d output=%s" % (status, output))
581
582             cups.setPasswordPrompt("You do not have permission to add a printer.")
583             if not os.path.exists(print_ppd): # assume foomatic: or some such
584                 status, status_str = cups.addPrinter(printer_name.encode('utf8'), print_uri,
585                     location, '', print_ppd, info)
586             else:
587                 status, status_str = cups.addPrinter(printer_name.encode('utf8'), print_uri,
588                     location, print_ppd, '', info)
589
590             log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
591
592             installed_print_devices = device.getSupportedCUPSDevices(['hp'])
593
594             if print_uri not in installed_print_devices or \
595                 printer_name not in installed_print_devices[print_uri]:
596
597                 log.error("Printer queue setup failed. Please restart CUPS and try again.")
598                 sys.exit(1)
599             else:
600                 pass
601                 # TODO:
602                 #service.sendEvent(hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=print_uri)
603
604
605         # ******************************* FAX QUEUE SETUP
606         if setup_fax and not prop.fax_build:
607             log.error("Cannot setup fax - HPLIP not built with fax enabled.")
608             setup_fax = False
609
610         if setup_fax:
611
612             try:
613                 from fax import fax
614             except ImportError:
615                 # This can fail on Python < 2.3 due to the datetime module
616                 setup_fax = False
617                 log.warning("Fax setup disabled - Python 2.3+ required.")
618
619         log.info("")
620
621         if setup_fax:
622
623             tui.header("FAX QUEUE SETUP")
624
625             if not auto and fax_uri in installed_fax_devices:
626                 log.warning("One or more fax queues already exist for this device: %s." % ', '.join(installed_fax_devices[fax_uri]))
627                 ok, setup_fax = tui.enter_yes_no("\nWould you like to install another fax queue for this device", 'n')
628                 if not ok: sys.exit(0)
629
630         if setup_fax:
631             if auto: # or fax_name is None:
632                 fax_name = default_model + '_fax'
633
634             fax_default_model = default_model + '_fax'
635
636             installed_fax_names = device.getSupportedCUPSPrinterNames(['hpfax'])
637             # Check for duplicate names
638             if (fax_uri in installed_fax_devices and fax_default_model in installed_fax_devices[fax_uri]) \
639                 or (fax_default_model in installed_fax_names):
640                     i = 2
641                     while True:
642                         t = fax_default_model + "_%d" % i
643                         if (t in installed_fax_names) and (fax_uri not in installed_fax_devices or t not in installed_fax_devices[fax_uri]):
644                             fax_default_model += "_%d" % i
645                             break
646                         i += 1
647
648             if not auto:
649                 if fax_name is None:
650                     while True:
651                         fax_name = raw_input(log.bold("\nPlease enter a name for this fax queue (m=use model name:'%s'*, q=quit) ?" % fax_default_model))
652
653                         if fax_name.lower().strip() == 'q':
654                             log.info("OK, done.")
655                             sys.exit(0)
656
657                         if not fax_name or fax_name.lower().strip() == 'm':
658                             fax_name = fax_default_model
659
660                         name_ok = True
661
662                         for d in installed_print_devices.keys():
663                             for p in installed_print_devices[d]:
664                                 if fax_name == p:
665                                     log.error("A print queue with that name already exists. Please enter a different name.")
666                                     name_ok = False
667                                     break
668
669                         for d in installed_fax_devices.keys():
670                             for f in installed_fax_devices[d]:
671                                 if fax_name == f:
672                                     log.error("A fax queue with that name already exists. Please enter a different name.")
673                                     name_ok = False
674                                     break
675
676                         for c in fax_name:
677                             if c in (' ', '#', '/', '%'):
678                                 log.error("Invalid character '%s' in fax name. Please enter a name that does not contain this character." % c)
679                                 name_ok = False
680
681                         if name_ok:
682                             break
683
684             else:
685                 fax_name = fax_default_model
686
687             log.info("Using queue name: %s" % fax_name)
688
689             fax_type = mq.get('fax-type', FAX_TYPE_NONE)
690
691             if prop.hpcups_build:
692                 if fax_type == FAX_TYPE_SOAP or fax_type == FAX_TYPE_LEDMSOAP:
693                     fax_ppd_name = 'HP-Fax2-hpcups'
694                 else:
695                     fax_ppd_name = 'HP-Fax-hpcups'
696             else: # hpijs
697                 if fax_type == FAX_TYPE_SOAP or fax_type == FAX_TYPE_LEDMSOAP:
698                     fax_ppd_name = 'HP-Fax2-hpijs'
699                 else:
700                     fax_ppd_name = 'HP-Fax-hpijs'
701
702             for f in ppds:
703                 if f.find(fax_ppd_name) >= 0:
704                     fax_ppd = f
705                     log.debug("Found PDD file: %s" % fax_ppd)
706                     break
707             else:
708                 log.error("Unable to find HP fax PPD file! Please check you HPLIP installation and try again.")
709                 sys.exit(1)
710
711             if auto:
712                 location, info = '', 'Automatically setup by HPLIP'
713             else:
714                 while True:
715                     location = raw_input(log.bold("Enter a location description for this printer (q=quit) ?"))
716
717                     if location.strip().lower() == 'q':
718                         log.info("OK, done.")
719                         sys.exit(0)
720
721                     # TODO: Validate chars
722                     break
723
724                 while True:
725                     info = raw_input(log.bold("Enter additonal information or notes for this printer (q=quit) ?"))
726
727                     if info.strip().lower() == 'q':
728                         log.info("OK, done.")
729                         sys.exit(0)
730
731                     # TODO: Validate chars
732                     break
733
734             log.info(log.bold("\nAdding fax queue to CUPS:"))
735             log.info("Device URI: %s" % fax_uri)
736             log.info("Queue name: %s" % fax_name)
737             log.info("PPD file: %s" % fax_ppd)
738             log.info("Location: %s" % location)
739             log.info("Information: %s" % info)
740
741             cups.setPasswordPrompt("You do not have permission to add a fax device.")
742             if not os.path.exists(fax_ppd): # assume foomatic: or some such
743                 status, status_str = cups.addPrinter(fax_name.encode('utf8'), fax_uri,
744                     location, '', fax_ppd, info)
745             else:
746                 status, status_str = cups.addPrinter(fax_name.encode('utf8'), fax_uri,
747                     location, fax_ppd, '', info)
748
749             log.debug("addPrinter() returned (%d, %s)" % (status, status_str))
750
751             installed_fax_devices = device.getSupportedCUPSDevices(['hpfax'])
752
753             log.debug(installed_fax_devices)
754
755             if fax_uri not in installed_fax_devices or \
756                 fax_name not in installed_fax_devices[fax_uri]:
757
758                 log.error("Fax queue setup failed. Please restart CUPS and try again.")
759                 sys.exit(1)
760             else:
761                 pass
762                 # TODO:
763                 #service.sendEvent(hpssd_sock, EVENT_CUPS_QUEUES_CHANGED, device_uri=fax_uri)
764
765
766         # ******************************* FAX HEADER SETUP
767             tui.header("FAX HEADER SETUP")
768
769             if auto:
770                 setup_fax = False
771             else:
772                 while True:
773                     user_input = raw_input(log.bold("\nWould you like to perform fax header setup (y=yes*, n=no, q=quit) ?")).strip().lower()
774
775                     if user_input == 'q':
776                         log.info("OK, done.")
777                         sys.exit(0)
778
779                     if not user_input:
780                         user_input = 'y'
781
782                     setup_fax = (user_input == 'y')
783
784                     if user_input in ('y', 'n', 'q'):
785                         break
786
787                     log.error("Please enter 'y' or 'n'")
788
789             if setup_fax:
790                 d = fax.getFaxDevice(fax_uri, disable_dbus=True)
791
792                 try:
793                     d.open()
794                 except Error:
795                     log.error("Unable to communicate with the device. Please check the device and try again.")
796                 else:
797                     try:
798                         tries = 0
799                         ok = True
800
801                         while True:
802                             tries += 1
803
804                             try:
805                                 current_phone_num = str(d.getPhoneNum())
806                                 current_station_name = str(d.getStationName())
807                             except Error:
808                                 log.error("Could not communicate with device. Device may be busy. Please wait for retry...")
809                                 time.sleep(5)
810                                 ok = False
811
812                                 if tries > 12:
813                                     break
814
815                             else:
816                                 ok = True
817                                 break
818
819                         if ok:
820                             while True:
821                                 if current_phone_num:
822                                     phone_num = raw_input(log.bold("\nEnter the fax phone number for this device (c=use current:'%s'*, q=quit) ?" % current_phone_num))
823                                 else:
824                                     phone_num = raw_input(log.bold("\nEnter the fax phone number for this device (q=quit) ?"))
825                                 if phone_num.strip().lower() == 'q':
826                                     log.info("OK, done.")
827                                     sys.exit(0)
828
829                                 if current_phone_num and (not phone_num or phone_num.strip().lower() == 'c'):
830                                     phone_num = current_phone_num
831
832                                 if len(phone_num) > 50:
833                                     log.error("Phone number length is too long (>50 characters). Please enter a shorter number.")
834                                     continue
835
836                                 ok = True
837                                 for x in phone_num:
838                                     if x not in '0123456789-(+) ':
839                                         log.error("Invalid characters in phone number. Please only use 0-9, -, (, +, and )")
840                                         ok = False
841                                         break
842
843                                 if not ok:
844                                     continue
845
846                                 break
847
848                             while True:
849                                 if current_station_name:
850                                     station_name = raw_input(log.bold("\nEnter the name and/or company for this device (c=use current:'%s'*, q=quit) ?" % current_station_name))
851                                 else:
852                                     station_name = raw_input(log.bold("\nEnter the name and/or company for this device (q=quit) ?"))
853                                 if station_name.strip().lower() == 'q':
854                                     log.info("OK, done.")
855                                     sys.exit(0)
856
857                                 if current_station_name and (not station_name or station_name.strip().lower() == 'c'):
858                                     station_name = current_station_name
859
860
861                                 if len(station_name) > 50:
862                                     log.error("Name/company length is too long (>50 characters). Please enter a shorter name/company.")
863                                     continue
864                                 break
865
866                             try:
867                                 d.setStationName(station_name)
868                                 d.setPhoneNum(phone_num)
869                             except Error:
870                                 log.error("Could not communicate with device. Device may be busy.")
871                             else:
872                                 log.info("\nParameters sent to device.")
873
874                     finally:
875                         d.close()
876
877         # ******************************* TEST PAGE
878         if setup_print:
879             print_test_page = False
880
881             tui.header("PRINTER TEST PAGE")
882
883             if auto:
884                 if testpage_in_auto_mode:
885                     print_test_page = True
886             else:
887                 ok, print_test_page = tui.enter_yes_no("\nWould you like to print a test page")
888                 if not ok: sys.exit(0)
889
890             if print_test_page:
891                 path = utils.which('hp-testpage')
892
893                 if printer_name:
894                     param = "-p%s" % printer_name
895                 else:
896                     param = "-d%s" % print_uri
897
898                 if len(path) > 0:
899                     cmd = 'hp-testpage %s' % param
900                 else:
901                     cmd = 'python ./testpage.py %s' % param
902
903                 log.debug(cmd)
904
905                 os.system(cmd)
906
907     except KeyboardInterrupt:
908         log.error("User exit")
909
910 log.info("")
911 log.info("Done.")
912