1# -*- coding: utf-8 -*- 2# 3# (c) Copyright 2003-2018 HP Development Company, L.P. 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19# Author: Don Welch 20# 21 22# Std Lib 23import sys 24import re 25import getopt 26import os 27 28# Local 29from .g import * 30from . import tui, utils, device 31 32USAGE_FLAG_NONE = 0x00 33USAGE_FLAG_DEVICE_ARGS = 0x01 34USAGE_FLAG_SUPRESS_G_DEBUG_FLAG = 0x02 35USAGE_FLAG_FILE_ARGS = 0x04 36 37 38uiscan=False 39class Module(object): 40 def __init__(self, mod, title, version, doc, 41 usage_data=None, avail_modes=None, 42 supported_ui_toolkits=None, 43 run_as_root_ok=False, quiet=False, deprecated=False): 44 45 self.mod = mod 46 self.title = title 47 self.version = version 48 self.doc = doc 49 self.usage_data = usage_data 50 os.umask(0o037) 51 log.set_module(mod) 52 self.args = [] 53 self.quiet = quiet 54 self.deprecated = deprecated 55 self.lock_file = None 56 self.help_only_support = False 57 prop.prog = sys.argv[0] 58 59 if os.getenv("HPLIP_DEBUG"): 60 log.set_level('debug') 61 62 self.avail_modes = avail_modes 63 if supported_ui_toolkits is not None: 64 self.supported_ui_toolkits = supported_ui_toolkits 65 self.num_supported_ui_toolkits = len(self.supported_ui_toolkits) 66 else: 67 self.supported_ui_toolkits = [] 68 self.num_supported_ui_toolkits = 0 69 70 self.default_ui_toolkit = sys_conf.get('configure', 'ui-toolkit', 'qt4') 71 72 self.num_installed_ui_toolkits = 0 73 self.installed_ui_toolkits = [] 74 if utils.to_bool(sys_conf.get('configure', 'qt3', '0')): 75 self.installed_ui_toolkits.append(UI_TOOLKIT_QT3) 76 self.num_installed_ui_toolkits += 1 77 78 if utils.to_bool(sys_conf.get('configure', 'qt4', '0')): 79 self.installed_ui_toolkits.append(UI_TOOLKIT_QT4) 80 self.num_installed_ui_toolkits += 1 81 82 if utils.to_bool(sys_conf.get('configure', 'qt5', '0')): 83 self.installed_ui_toolkits.append(UI_TOOLKIT_QT5) 84 self.num_installed_ui_toolkits += 1 85 86 self.default_mode = INTERACTIVE_MODE 87 88 self.num_valid_modes = 0 89 if self.avail_modes is not None: 90 if GUI_MODE in self.avail_modes and prop.gui_build and self.installed_ui_toolkits: 91 self.num_valid_modes += 1 92 93 if INTERACTIVE_MODE in self.avail_modes: 94 self.num_valid_modes += 1 95 96 if NON_INTERACTIVE_MODE in self.avail_modes: 97 self.num_valid_modes += 1 98 99 if self.avail_modes is not None: 100 if INTERACTIVE_MODE in self.avail_modes: 101 self.default_mode = INTERACTIVE_MODE 102 103 elif NON_INTERACTIVE_MODE in self.avail_modes: 104 self.default_mode = NON_INTERACTIVE_MODE 105 106 if self.supported_ui_toolkits is not None and prop.gui_build and self.installed_ui_toolkits: 107 108 if self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT4 in self.supported_ui_toolkits and \ 109 UI_TOOLKIT_QT3 not in self.supported_ui_toolkits and INTERACTIVE_MODE in self.avail_modes: 110 111 # interactive + qt4 and default is qt3 --> set to interactive (if avail) (e.g., hp-align) 112 self.default_mode = INTERACTIVE_MODE 113 self.default_ui_toolkit = 'none' 114 115 elif (UI_TOOLKIT_QT4 in self.supported_ui_toolkits and self.default_ui_toolkit == 'qt4' and UI_TOOLKIT_QT4 in self.installed_ui_toolkits) or \ 116 (UI_TOOLKIT_QT3 in self.supported_ui_toolkits and self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT3 in self.installed_ui_toolkits) or \ 117 (UI_TOOLKIT_QT5 in self.supported_ui_toolkits and self.default_ui_toolkit == 'qt5' and UI_TOOLKIT_QT5 in self.installed_ui_toolkits): 118 self.default_mode = GUI_MODE 119 120 elif self.default_ui_toolkit == 'qt3' and UI_TOOLKIT_QT3 not in self.supported_ui_toolkits: 121 122 if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits: # (e.g, hp-linefeedcal?) 123 self.default_ui_toolkit = 'qt4' 124 self.default_mode = GUI_MODE 125 if UI_TOOLKIT_QT5 in self.supported_ui_toolkits and UI_TOOLKIT_QT5 in self.installed_ui_toolkits: 126 self.default_ui_toolkit = 'qt5' 127 self.default_mode = GUI_MODE 128 129 elif INTERACTIVE_MODE in self.avail_modes: 130 self.default_mode = INTERACTIVE_MODE 131 132 elif NON_INTERACTIVE_MODE in self.avail_modes: 133 self.default_mode = NON_INTERACTIVE_MODE 134 135 else: 136 log.error("%s cannot be run using Qt3 toolkit." % self.mod) 137# sys.exit(1) 138 self.help_only_support = True 139 140 elif self.default_ui_toolkit == 'qt4' and UI_TOOLKIT_QT4 not in self.supported_ui_toolkits: 141 142 if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits: # (e.g., hp-unload) 143 self.default_ui_toolkit = 'qt3' 144 self.default_mode = GUI_MODE 145 146 elif INTERACTIVE_MODE in self.avail_modes: 147 self.default_mode = INTERACTIVE_MODE 148 149 elif NON_INTERACTIVE_MODE in self.avail_modes: 150 self.default_mode = NON_INTERACTIVE_MODE 151 152 else: 153 log.error("%s cannot be run using Qt4 toolkit." % self.mod) 154# sys.exit(1) 155 self.help_only_support = True 156 157 158 self.mode = self.default_mode 159 160 #log.debug("Default ui-toolkit: %s" % self.default_ui_toolkit) 161 #log.debug("Default mode: %s" % self.default_mode) 162 163 if os.getuid() == 0 and not run_as_root_ok: 164 log.warn("%s should not be run as root/superuser." % mod) 165 166 167 def setUsage(self, include_flags=0, extra_options=None, 168 extra_notes=None, see_also_list=None): 169 170 if self.doc: 171 self.usage_data = [(self.doc, "", "name", True)] 172 else: 173 self.usage_data = [] 174 175 summary = ['Usage:', self.mod] 176 content = [] 177 notes = [] 178 179 if include_flags & USAGE_FLAG_DEVICE_ARGS == USAGE_FLAG_DEVICE_ARGS: 180 summary.append('[DEVICE_URI|PRINTER_NAME]') 181 content.append(utils.USAGE_ARGS) 182 content.append(utils.USAGE_DEVICE) 183 content.append(utils.USAGE_PRINTER) 184 185 if self.avail_modes is not None and self.num_valid_modes > 0: 186 summary.append('[MODE]') 187 content.append(utils.USAGE_SPACE) 188 content.append(utils.USAGE_MODE) 189 190 if self.num_installed_ui_toolkits > 0: 191 if GUI_MODE in self.avail_modes and prop.gui_build: 192 content.append(utils.USAGE_GUI_MODE) 193 194 if INTERACTIVE_MODE in self.avail_modes: 195 content.append(utils.USAGE_INTERACTIVE_MODE) 196 197 if NON_INTERACTIVE_MODE in self.avail_modes: 198 content.append(utils.USAGE_NON_INTERACTIVE_MODE) 199 200 # [options] 201 summary.append('[OPTIONS]') 202 content.append(utils.USAGE_SPACE) 203 content.append(utils.USAGE_OPTIONS) 204 205 if self.avail_modes is not None and GUI_MODE in self.avail_modes and \ 206 self.supported_ui_toolkits is not None and self.num_supported_ui_toolkits > 0 and \ 207 prop.gui_build and self.num_installed_ui_toolkits > 0: 208 209 if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits: 210 content.append(utils.USAGE_USE_QT3) 211 212 if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits: 213 content.append(utils.USAGE_USE_QT4) 214 215 if UI_TOOLKIT_QT5 in self.supported_ui_toolkits and UI_TOOLKIT_QT5 in self.installed_ui_toolkits: 216 content.append(utils.USAGE_USE_QT5) 217 218 219 content.append(utils.USAGE_LOGGING1) 220 content.append(utils.USAGE_LOGGING2) 221 if include_flags & USAGE_FLAG_SUPRESS_G_DEBUG_FLAG != USAGE_FLAG_SUPRESS_G_DEBUG_FLAG: 222 content.append(utils.USAGE_LOGGING3) # Issue with --gg in hp-sendfax 223 224 # --loc/--lang 225 #if self.avail_modes is not None and GUI_MODE in self.avail_modes and prop.gui_build: 226 # content.append(utils.USAGE_LANGUAGE) 227 228 content.append(utils.USAGE_HELP) 229 230 if extra_options is not None: 231 for e in extra_options: 232 content.append(e) 233 234 # [FILES] 235 if include_flags & USAGE_FLAG_FILE_ARGS: 236 summary.append('[FILES]') 237 238 # Notes 239 if extra_notes is not None or notes: 240 content.append(utils.USAGE_SPACE) 241 content.append(utils.USAGE_NOTES) 242 243 for n in notes: 244 content.append(n) 245 246 if extra_notes is not None: 247 for n in extra_notes: 248 content.append(n) 249 250 # See Also 251 if see_also_list is not None: 252 content.append(utils.USAGE_SPACE) 253 content.append(utils.USAGE_SEEALSO) 254 for s in see_also_list: 255 content.append((s, '', 'seealso', False)) 256 257 content.insert(0, (' '.join(summary), '', 'summary', True)) 258 259 for c in content: 260 self.usage_data.append(c) 261 262 263 def parseStdOpts(self, extra_params=None, 264 extra_long_params=None, 265 handle_device_printer=True, 266 supress_g_debug_flag=False): 267 268 params = 'l:h' # 'l:hq:' 269 if not supress_g_debug_flag: 270 params = ''.join([params, 'g']) 271 272 long_params = ['logging=', 'help', 'help-rest', 'help-man', 273 'help-desc', 274 #'lang=', 'loc=', 275 'debug', 'dbg'] 276 277 if handle_device_printer: 278 params = ''.join([params, 'd:p:P:']) 279 long_params.extend(['device=', 'device-uri=', 'printer=', 'printer-name']) 280 281 if self.num_valid_modes > 0: 282 if GUI_MODE in self.avail_modes and prop.gui_build: 283 params = ''.join([params, 'u']) 284 long_params.extend(['gui', 'ui']) 285 286 if INTERACTIVE_MODE in self.avail_modes: 287 params = ''.join([params, 'i']) 288 long_params.extend(['interactive', 'text']) 289 290 if NON_INTERACTIVE_MODE in self.avail_modes: 291 params = ''.join([params, 'n']) 292 long_params.extend(['noninteractive', 'non-interactive', 'batch']) 293 294 if self.supported_ui_toolkits is not None and \ 295 self.num_supported_ui_toolkits >= 1 and prop.gui_build and \ 296 self.avail_modes is not None and GUI_MODE in self.avail_modes: 297 298 if UI_TOOLKIT_QT3 in self.supported_ui_toolkits and UI_TOOLKIT_QT3 in self.installed_ui_toolkits: 299 long_params.extend(['qt3', 'use-qt3']) 300 301 if UI_TOOLKIT_QT4 in self.supported_ui_toolkits and UI_TOOLKIT_QT4 in self.installed_ui_toolkits: 302 long_params.extend(['qt4', 'use-qt4']) 303 304 if extra_params is not None: 305 params = ''.join([params, extra_params]) 306 307 if extra_long_params is not None: 308 long_params.extend(extra_long_params) 309 310 opts = None 311 show_usage = None 312 device_uri = None 313 printer_name = None 314 uiscan=False 315 error_msg = [] 316 mode = self.default_mode 317 if prop.gui_build: 318 ui_toolkit = self.default_ui_toolkit 319 else: 320 ui_toolkit = 'none' 321 lang = None 322 323 try: 324 opts, self.args = getopt.getopt(sys.argv[1:], params, long_params) 325 except getopt.GetoptError as e: 326 error_msg = [e.msg] 327 328 else: 329 for o, a in opts: 330 if o in ('-d', '--device', '--device-uri'): 331 device_uri = a 332 333 elif o in ('-P', '-p', '--printer', '--printer-name'): 334 printer_name = a 335 336 elif o in ('-l', '--logging'): 337 log_level = a.lower().strip() 338 if not log.set_level(log_level): 339 show_usage = 'text' 340 341 elif o in ('-g', '--debug', '--dbg'): 342 log.set_level('debug') 343 344 elif o in ('-u', '--gui', '--ui'): 345 if self.avail_modes is not None and GUI_MODE in self.avail_modes and \ 346 self.supported_ui_toolkits is not None and prop.gui_build: 347 mode = GUI_MODE 348 else: 349 error_msg.append("Unable to enter GUI mode.") 350 351 elif o in ('-i', '--interactive', '--text'): 352 if self.avail_modes is not None and INTERACTIVE_MODE in self.avail_modes: 353 mode = INTERACTIVE_MODE 354 ui_toolkit = 'none' 355 356 elif o in ('-n', '--non-interactive', '--batch'): 357 if self.avail_modes is not None and NON_INTERACTIVE_MODE in self.avail_modes: 358 mode = NON_INTERACTIVE_MODE 359 ui_toolkit = 'none' 360 361 elif o in ('-h', '--help'): 362 show_usage = 'text' 363 364 elif o == '--help-rest': 365 show_usage = 'rest' 366 367 elif o == '--help-man': 368 show_usage = 'man' 369 370 elif o == '--help-desc': 371 show_usage = 'desc' 372 373 elif o == '--uiscan': 374 uiscan = True 375 376 elif o in ('--qt3', '--use-qt3'): 377 if self.avail_modes is not None and GUI_MODE in self.avail_modes: 378 if self.supported_ui_toolkits is not None and \ 379 UI_TOOLKIT_QT3 in self.supported_ui_toolkits and prop.gui_build and \ 380 UI_TOOLKIT_QT3 in self.installed_ui_toolkits: 381 382 mode = GUI_MODE 383 ui_toolkit = 'qt3' 384 else: 385 error_msg.append("%s does not support Qt3. Unable to enter GUI mode." % self.mod) 386 387 elif o in ('--qt4', '--use-qt4'): 388 if self.avail_modes is not None and GUI_MODE in self.avail_modes: 389 if self.supported_ui_toolkits is not None and \ 390 UI_TOOLKIT_QT4 in self.supported_ui_toolkits and prop.gui_build and \ 391 UI_TOOLKIT_QT4 in self.installed_ui_toolkits: 392 393 mode = GUI_MODE 394 ui_toolkit = 'qt4' 395 else: 396 error_msg.append("%s does not support Qt4. Unable to enter GUI mode." % self.mod) 397 398 elif o in ('--qt5', '--use-qt5'): 399 if self.avail_modes is not None and GUI_MODE in self.avail_modes: 400 if self.supported_ui_toolkits is not None and \ 401 UI_TOOLKIT_QT5 in self.supported_ui_toolkits and prop.gui_build and \ 402 UI_TOOLKIT_QT5 in self.installed_ui_toolkits: 403 404 mode = GUI_MODE 405 ui_toolkit = 'qt5' 406 else: 407 error_msg.append("%s does not support Qt4. Unable to enter GUI mode." % self.mod) 408 409 410 #elif o in ('--lang', '--loc'): 411 # if a.strip() == '?': 412 # utils.log_title(self.title, self.version) 413 # self.showLanguages() 414 # sys.exit(0) 415 # else: 416 # lang = utils.validate_language(a.lower()) 417 418 if error_msg: 419 show_usage = 'text' 420 421 if self.help_only_support: 422 if show_usage or error_msg: 423 if uiscan == False: 424 self.usage(show_usage, error_msg) 425 else: 426 log.info(log.bold("\nPlease check usage '%s --help'"%self.mod)) 427 show_usage = 'text' 428 else: 429 if uiscan == False: 430 self.usage(show_usage, error_msg) 431 432 if show_usage is not None: 433 sys.exit(0) 434 435 self.mode = mode 436 return opts, device_uri, printer_name, mode, ui_toolkit, lang 437 438 439 def showLanguages(self): 440 f = tui.Formatter() 441 f.header = ("Language Code", "Alternate Name(s)") 442 for loc, ll in list(supported_locales.items()): 443 f.add((ll[0], ', '.join(ll[1:]))) 444 445 f.output() 446 447 448 def usage(self, show_usage='text', error_msg=None): 449 if show_usage is None: 450 if not self.quiet: 451 self.showTitle() 452 return 453 454 if show_usage == 'text': 455 self.showTitle() 456 log.info() 457 458 if show_usage == 'desc': 459 print(self.doc) 460 461 else: 462 utils.format_text(self.usage_data, show_usage, self.title, self.mod, self.version) 463 464 if error_msg: 465 for e in error_msg: 466 log.error(e) 467 468 sys.exit(1) 469 470 sys.exit(0) 471 472 if show_usage == 'text': 473 sys.exit(0) 474 475 476 def showTitle(self, show_ver=True): 477 if not self.quiet: 478 log.info("") 479 480 if show_ver: 481 #if uiscan == False: 482 log.info(log.bold("HP Linux Imaging and Printing System (ver. %s)" % prop.version)) 483 else: 484 #if uiscan == False: 485 log.info(log.bold("HP Linux Imaging and Printing System")) 486 487 #if uiscan == False: 488 log.info(log.bold("%s ver. %s" % (self.title, self.version))) 489 log.info("") 490 log.info("Copyright (c) 2001-18 HP Development Company, LP") 491 log.info("This software comes with ABSOLUTELY NO WARRANTY.") 492 log.info("This is free software, and you are welcome to distribute it") 493 log.info("under certain conditions. See COPYING file for more details.") 494 log.info("") 495 if self.deprecated: 496 log.warn(log.bold("%s support is deprecated. Feature can be used as is. Fixes or updates will not be provided" %self.title)) 497 log.info("") 498 499 500 def getDeviceUri(self, device_uri=None, printer_name=None, back_end_filter=device.DEFAULT_BE_FILTER, 501 filter=device.DEFAULT_FILTER, devices=None, restrict_to_installed_devices=True): 502 """ Validate passed in parameters, and, if in text mode, have user select desired device to use. 503 Used for tools that are device-centric and accept -d (and maybe also -p). 504 Use the filter(s) to restrict what constitute valid devices. 505 506 Return the matching device URI based on: 507 1. Passed in device_uri if it is valid (filter passes) 508 2. Corresponding device_uri from the printer_name if it is valid (filter passes) ('*' means default printer) 509 3. User input from menu (based on bus and filter) 510 511 device_uri and printer_name can both be specified if they correspond to the same device. 512 513 Returns: 514 device_uri|None 515 (returns None if passed in device_uri is invalid or printer_name doesn't correspond to device_uri) 516 """ 517 518 log.debug("getDeviceUri(%s, %s, %s, %s, , %s)" % 519 (device_uri, printer_name, back_end_filter, filter, restrict_to_installed_devices)) 520 log.debug("Mode=%s" % self.mode) 521 522 scan_uri_flag = False 523 if 'hpaio' in back_end_filter: 524 scan_uri_flag = True 525 526 device_uri_ok = False 527 printer_name_ok = False 528 device_uri_ret = None 529 530 if devices is None: 531 devices = device.getSupportedCUPSDevices(back_end_filter, filter) 532 log.debug(devices) 533 if not devices and restrict_to_installed_devices: 534 log.error("No device found that support this feature.") 535 return None 536 537 if device_uri is not None: 538 if device_uri in devices: 539 device_uri_ok = True 540 541 elif restrict_to_installed_devices: 542 log.error("'%s' device doesn't support this feature (or) Invalid device URI" % device_uri) 543 return None 544 545 else: 546 device_uri_ok = True 547 548 if printer_name is not None: 549 #Find the printer_name in the models of devices 550 log.debug(devices) 551 for uri in devices: 552 log.debug(uri) 553 back_end, is_hp, bb, model, serial, dev_file, host, zc, port = \ 554 device.parseDeviceURI(uri) 555 log.debug("back_end=%s, is_hp=%s, bb=%s, model=%s, serial=%s, dev_file=%s, host=%s, zc=%s, port= %s" % (back_end, is_hp, bb, model, serial, dev_file, host, zc, port)) 556 cups_printer = devices[uri] 557 if printer_name.lower() in [m.lower() for m in cups_printer]: 558 printer_name_ok = True 559 printer_name_device_uri = device_uri = uri 560 device_uri_ok = True 561 if printer_name_ok is not True: 562 log.error("'%s' device doesn't support this feature (or) Invalid printer name" % printer_name) 563 printer_name = None 564 if restrict_to_installed_devices: 565 return None 566 567 568 569 if device_uri is not None and printer_name is None and device_uri_ok: # Only device_uri specified 570 device_uri_ret = device_uri 571 572 elif device_uri is not None and printer_name is not None: # Both specified 573 if device_uri_ok and printer_name_ok: 574 if device_uri == printer_name_device_uri: 575 device_uri_ret = device_uri 576 else: 577 log.error("Printer name %s and device URI %s refer to different devices." % (printer_name, device_uri)) 578 printer_name, printer_name = None, None 579 580 elif device_uri is None and printer_name is not None and printer_name_ok: # Only printer name specified 581 device_uri_ret = device.getDeviceURIByPrinterName(printer_name, scan_uri_flag) 582 583 elif len(devices) == 1: # Nothing specified, and only 1 device avail. 584 device_uri_ret = list(devices.keys())[0] 585 586 if device_uri_ret is None and len(devices): 587 if self.mode == INTERACTIVE_MODE: 588 device_uri_ret = tui.device_table(devices, scan_uri_flag) 589 else: 590 device_uri_ret = list(devices.keys())[0] 591 592 if device_uri_ret is not None: 593 user_conf.set('last_used', 'device_uri', device_uri_ret) 594 595 else: 596 if self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE): 597 log.error("No device selected/specified or that supports this functionality.") 598 sys.exit(1) 599# else: 600# log.debug("No device selected/specified") 601 602 return device_uri_ret 603 604 605 def getPrinterName(self, printer_name, device_uri, back_end_filter=device.DEFAULT_BE_FILTER, 606 filter=device.DEFAULT_FILTER, restrict_to_installed_devices=True): 607 """ Validate passed in parameters, and, if in text mode, have user select desired printer to use. 608 Used for tools that are printer queue-centric and accept -p (and maybe also -d). 609 Use the filter(s) to restrict what constitute valid printers. 610 611 Return the matching printer_name based on: 612 1. Passed in printer_name if it is valid (filter passes) ('*' means default printer) 613 2. From single printer_name of corresponding passed in device_uri (filter passes) 614 3. User input from menu (CUPS printer list, filtered) [or if > 1 queue for device_uri] 615 616 device_uri and printer_name can both be specified if they correspond to the same device. 617 618 Returns: 619 (printer_name|None, device_uri|None) (tuple) 620 (returns None if passed in printer_name is invalid or device_uri doesn't correspond to printer_name) 621 """ 622 623 log.debug("getPrinterName(%s, %s, %s, %s)" % (device_uri, printer_name, back_end_filter, filter)) 624 log.debug("Mode=%s" % self.mode) 625 626 device_uri_ok = False 627 printer_name_ok = False 628 printer_name_ret = None 629 device_uri_ret = None 630 631 printers = device.getSupportedCUPSPrinterNames(back_end_filter, filter) 632 log.debug(printers) 633 634 if not printers: 635 log.error("No device found that support this feature.") 636 return False, None, None 637 638 if device_uri is not None: 639 devices = device.getSupportedCUPSDevices(back_end_filter, filter) 640 if device_uri in devices: 641 device_uri_ok = True 642 device_uri_ret = device_uri 643 else: 644 log.error("'%s' device doesn't support this feature (or) Invalid device URI" % device_uri) 645 device_uri = None 646 if restrict_to_installed_devices: 647 return False, None, None 648 649 if printer_name is not None: 650 if printer_name == '*': 651 from prnt import cups 652 default_printer = cups.getDefaultPrinter() 653 if default_printer is not None: 654 printer_name_ret = default_printer 655 else: 656 log.error("CUPS default printer not set") 657 printer_name = None 658 659 else: 660 if printer_name.lower() in [p.lower() for p in printers]: 661 printer_name_ok = True 662 device_uri_ret = device.getDeviceURIByPrinterName(printer_name) 663 else: 664 log.error("'%s' device doesn't support this feature (or) Invalid printer name" % printer_name) 665 printer_name = None 666 if restrict_to_installed_devices: 667 return False, None, None 668 669 if device_uri is not None and printer_name is None and device_uri_ok: # Only device_uri specified 670 if len(devices[device_uri]) == 1: 671 printer_name_ret = devices[device_uri][0] 672 673 elif device_uri is not None and printer_name is not None: # Both specified 674 if device_uri_ok and printer_name_ok: 675 if device_uri == device_uri_ret: 676 printer_name_ret = printer_name 677 else: 678 log.error("Printer name and device URI refer to different devices.") 679 680 elif device_uri is None and printer_name is not None and printer_name_ok: # Only printer name specified 681 printer_name_ret = printer_name 682 683 elif len(printers) == 1: # nothing specified, and only 1 avail. printer 684 printer_name_ret = printers[0] 685 686 if printer_name_ret is None and self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE) and len(printers): 687 printer_name_ret = tui.printer_table(printers) 688 689 if printer_name_ret is not None and device_uri_ret is None: 690 device_uri_ret = device.getDeviceURIByPrinterName(printer_name_ret) 691 692 if device_uri_ret is not None: 693 user_conf.set('last_used', 'device_uri', device_uri_ret) 694 695 if printer_name_ret is not None: 696 user_conf.set('last_used', 'printer_name', printer_name_ret) 697 698 else: 699 if self.mode in (INTERACTIVE_MODE, NON_INTERACTIVE_MODE): 700 log.error("No printer selected/specified or that supports this functionality.") 701 sys.exit(1) 702 else: 703 log.debug("No printer selected/specified") 704 705 return True, printer_name_ret, device_uri_ret 706 707 708 def lockInstance(self, suffix='',suppress_error=False): 709 if suffix: 710 ok, self.lock_file = utils.lock_app('-'.join([self.mod, suffix]),suppress_error) 711 else: 712 ok, self.lock_file = utils.lock_app(self.mod,suppress_error) 713 714 if not ok: 715 sys.exit(1) 716 717 718 def unlockInstance(self): 719 if self.lock_file is not None: 720 utils.unlock(self.lock_file) 721