~ubuntu-branches/ubuntu/raring/hplip/raring-proposed

« back to all changes in this revision

Viewing changes to .pc/hp-setup-prompt-for-custom-PPD.dpatch/setup.py

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-05-26 11:20:39 UTC
  • mfrom: (1.5.6) (31.1.3 precise)
  • Revision ID: package-import@ubuntu.com-20120526112039-bevxczegxnbyr5m7
Tags: 3.12.4-1
* New upstream release
* Switch to source/format 3.0 (quilt) - drop dpatch
* Refreshed debian/patches
* dh_autoreconf debian/autogen.sh & set local-options single-debian-patch
* Update to debian/compat -> 9
* Fix "hardened build flags" patch from Moritz - thanks (Closes: #667828)
* Fix "duplex descriptor uninitialized" patch from Matej (Closes: #583273)
* Fix "please migrate to kde-runtime" patch from Pino (Closes: #666544)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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