home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.4) import socket import re import gzip import os.path as os import time import struct import threading import urllib import StringIO import httplib from g import * from codes import * import msg import utils import status import pml import slp import service from prnt import pcl, ldl, cups DEFAULT_PROBE_BUS = 'usb,par,cups' VALID_BUSES = ('par', 'net', 'cups', 'usb', 'bt', 'fw') DEFAULT_FILTER = 'none' VALID_FILTERS = ('none', 'print', 'scan', 'fax', 'pcard', 'copy') pat_deviceuri = re.compile('(.*?):/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*)|ip=(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}[^&]*))(?:&port=(\\d))?', re.IGNORECASE) http_pat_url = re.compile('/(.*?)/(\\S*?)\\?(?:serial=(\\S*)|device=(\\S*))&loc=(\\S*)', re.IGNORECASE) pat_dynamic_ctr = re.compile('CTR:\\d*\\s.*;', re.IGNORECASE) MAX_BUFFER = 8192 def makeuri(hpiod_sock, hpssd_sock, param, port = 1): ip_pat = re.compile('\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b', re.IGNORECASE) dev_pat = re.compile('/dev/.+', re.IGNORECASE) usb_pat = re.compile('(\\d+):(\\d+)', re.IGNORECASE) (cups_uri, sane_uri, fax_uri) = ('', '', '') found = False try: param = socket.gethostbyname(param) except socket.gaierror: log.debug('Gethostbyname() failed.') if dev_pat.search(param) is not None: log.debug('Trying parallel') try: (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'MakeURI', None, { 'device-file': param, 'bus': 'par' }) except Error: result_code = ERROR_INTERNAL if result_code == ERROR_SUCCESS: cups_uri = fields.get('device-uri', '') found = True elif usb_pat.search(param) is not None: log.debug('Trying USB') match_obj = usb_pat.search(param) usb_bus_id = match_obj.group(1) usb_dev_id = match_obj.group(2) try: (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'MakeURI', None, { 'usb-bus': usb_bus_id, 'usb-dev': usb_dev_id, 'bus': 'usb' }) except Error: result_code = ERROR_INTERNAL if result_code == ERROR_SUCCESS: cups_uri = fields.get('device-uri', '') found = True elif ip_pat.search(param) is not None: log.debug('Trying IP address') try: (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'MakeURI', None, { 'hostname': param, 'port': port, 'bus': 'net' }) except Error: result_code = ERROR_INTERNAL if result_code == ERROR_SUCCESS: cups_uri = fields.get('device-uri', '') found = True else: log.debug('Trying serial number') devices = probeDevices(hpssd_sock, bus = 'usb,par') for d in devices: log.debug(d) (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(d) if bus == 'par': (mq, data, result_code) = msg.xmitMessage(hpssd_sock, 'QueryModel', None, { 'device-uri': d }) (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'DeviceOpen', None, { 'device-uri': d, 'io-mode': mq.get('io-mode', '0'), 'io-mfp-mode': mq.get('io-mfp-mode', '2'), 'io-control': mq.get('io-control', '0'), 'io-scan-port': mq.get('io-scan-port', '0') }) if result_code == ERROR_SUCCESS: device_id = fields['device-id'] (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'DeviceID', None, { 'device-id': device_id }) serial = parseDeviceID(data).get('SN', '') (fields, data, result_code) = msg.xmitMessage(hpiod_sock, 'DeviceClose', None, { 'device-id': device_id }) if serial.lower() == param.lower(): found = True cups_uri = d break continue if found: (fields, data, result_code) = msg.xmitMessage(hpssd_sock, 'QueryModel', None, { 'device-uri': cups_uri }) if fields.get('scan-type', 0): sane_uri = cups_uri.replace('hp:', 'hpaio:') if fields.get('fax-type', 0): fax_uri = cups_uri.replace('hp:', 'hpfax:') return (cups_uri, sane_uri, fax_uri) def getInteractiveDeviceURI(bus = 'cups,usb,par', filter = 'none', back_end_filter = [ 'hp']): bus = bus.lower() probed_devices = probeDevices(bus = bus, filter = filter) cups_printers = cups.getPrinters() log.debug(probed_devices) log.debug(cups_printers) max_deviceid_size = 0 x = 0 devices = { } for d in probed_devices: printers = [] (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(d) if back_end in back_end_filter: for p in cups_printers: if p.device_uri == d: printers.append(p.name) continue devices[x] = (d, printers) x += 1 max_deviceid_size = max(len(d), max_deviceid_size) continue if x == 0: log.error('No devices found.') raise Error(ERROR_NO_PROBED_DEVICES_FOUND) elif x == 1: log.info(utils.bold('Using device: %s' % devices[0][0])) return devices[0][0] else: log.info(utils.bold('\nChoose device from probed devices connected on bus(es): %s:\n' % bus)) formatter = utils.TextFormatter(({ 'width': 4 }, { 'width': max_deviceid_size, 'margin': 2 }, { 'width': 100 - max_deviceid_size - 8, 'margin': 2 })) log.info(formatter.compose(('Num.', 'Device-URI', 'CUPS printer(s)'))) log.info(formatter.compose(('-' * 4, '-' * max_deviceid_size, '-' * (80 - max_deviceid_size - 10)))) for y in range(x): log.info(formatter.compose((str(y), devices[y][0], ', '.join(devices[y][1])))) while None: user_input = raw_input(utils.bold('\nEnter number 0...%d for device (q=quit) ?' % (x - 1))) if user_input == '': log.warn("Invalid input - enter a numeric value or 'q' to quit.") continue if user_input.strip()[0] in ('q', 'Q'): return None try: i = int(user_input) except ValueError: log.warn("Invalid input - enter a numeric value or 'q' to quit.") continue if i < 0 or i > x - 1: log.warn("Invalid input - enter a value between 0 and %d or 'q' to quit." % (x - 1)) continue break return devices[i][0] def probeDevices(sock = None, bus = 'cups,usb,par', timeout = 5, ttl = 4, filter = 'none', format = 'default'): close_sock = False if sock is None: close_sock = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((prop.hpssd_host, prop.hpssd_port)) except socket.error: raise Error(ERROR_UNABLE_TO_CONTACT_SERVICE) except: None<EXCEPTION MATCH>socket.error None<EXCEPTION MATCH>socket.error (fields, data, result_code) = msg.xmitMessage(sock, 'ProbeDevicesFiltered', None, { 'bus': bus, 'timeout': timeout, 'ttl': ttl, 'format': format, 'filter': filter }) if close_sock: sock.close() if result_code > ERROR_SUCCESS: return '' temp = data.splitlines() probed_devices = [] for t in temp: probed_devices.append(t.split(',')[0]) return probed_devices def getSupportedCUPSDevices(back_end_filter = [ 'hp']): devices = { } printers = cups.getPrinters() for p in printers: try: (back_end, is_hp, bus, model, serial, dev_file, host, port) = parseDeviceURI(p.device_uri) except Error: continue if back_end in back_end_filter: try: devices[p.device_uri] except KeyError: devices[p.device_uri] = [ p.name] devices[p.device_uri].append(p.name) continue return devices def parseDeviceID(device_id): d = { } x = _[1] for z in x: y = z.split(':') try: d.setdefault(y[0].strip(), y[1]) continue except IndexError: [] [] [] d.setdefault(y[0].strip(), None) continue d.setdefault('MDL', '') d.setdefault('SN', '') if 'SERIAL' in d: d['SN'] = d['SERIAL'] del d['SERIAL'] elif 'SERN' in d: d['SN'] = d['SERN'] del d['SERN'] if d['SN'].startswith('X'): d['SN'] = '' return d def parseDynamicCounter(ctr_field, convert_to_int = True): (counter, value) = ctr_field.split(' ') try: if not counter.lstrip('0'): pass counter = int('0') if convert_to_int: if not value.lstrip('0'): pass value = int('0') except ValueError: if convert_to_int: (counter, value) = (0, 0) else: (counter, value) = (0, '') except: convert_to_int return (counter, value) def parseDeviceURI(device_uri): m = pat_deviceuri.match(device_uri) if m is None: raise Error(ERROR_INVALID_DEVICE_URI) if not m.group(1).lower(): pass back_end = '' is_hp = back_end in ('hp', 'hpfax', 'hpaio') if not m.group(2).lower(): pass bus = '' if bus not in ('usb', 'net', 'bt', 'fw', 'par'): raise Error(ERROR_INVALID_DEVICE_URI) if not m.group(3): pass model = '' if not m.group(4): pass serial = '' if not m.group(5): pass dev_file = '' if not m.group(6): pass host = '' if not m.group(7): pass port = 1 if bus == 'net': try: port = int(port) except (ValueError, TypeError): port = 1 if port == 0: port = 1 return (back_end, is_hp, bus, model, serial, dev_file, host, port) def validateBusList(bus): for x in bus.split(','): bb = x.lower().strip() if bb not in VALID_BUSES: log.error('Invalid bus name: %s' % bb) return False continue return True def validateFilterList(filter): for f in filter.split(','): if f not in VALID_FILTERS: log.error("Invalid term '%s' in filter list" % f) return False continue return True AGENT_types = { AGENT_TYPE_NONE: 'invalid', AGENT_TYPE_BLACK: 'black', AGENT_TYPE_CMY: 'cmy', AGENT_TYPE_KCM: 'kcm', AGENT_TYPE_CYAN: 'cyan', AGENT_TYPE_MAGENTA: 'magenta', AGENT_TYPE_YELLOW: 'yellow', AGENT_TYPE_CYAN_LOW: 'photo_cyan', AGENT_TYPE_MAGENTA_LOW: 'photo_magenta', AGENT_TYPE_YELLOW_LOW: 'photo_yellow', AGENT_TYPE_GGK: 'photo_gray', AGENT_TYPE_BLUE: 'photo_blue', AGENT_TYPE_KCMY_CM: 'kcmy_cm', AGENT_TYPE_LC_LM: 'photo_cyan_and_photo_magenta', AGENT_TYPE_Y_M: 'yellow_and_magenta', AGENT_TYPE_C_K: 'cyan_and_black', AGENT_TYPE_LG_PK: 'light_gray_and_photo_black', AGENT_TYPE_LG: 'light_gray', AGENT_TYPE_G: 'medium_gray', AGENT_TYPE_PG: 'photo_gray', AGENT_TYPE_UNSPECIFIED: 'unspecified' } AGENT_kinds = { AGENT_KIND_NONE: 'invalid', AGENT_KIND_HEAD: 'head', AGENT_KIND_SUPPLY: 'supply', AGENT_KIND_HEAD_AND_SUPPLY: 'cartridge', AGENT_KIND_TONER_CARTRIDGE: 'toner', AGENT_KIND_MAINT_KIT: 'maint_kit', AGENT_KIND_ADF_KIT: 'adf_kit', AGENT_KIND_DRUM_KIT: 'drum_kit', AGENT_KIND_TRANSFER_KIT: 'transfer_kit', AGENT_KIND_INT_BATTERY: 'battery', AGENT_KIND_UNKNOWN: 'unknown' } AGENT_healths = { AGENT_HEALTH_OK: 'ok', AGENT_HEALTH_MISINSTALLED: 'misinstalled', AGENT_HEALTH_FAIR_MODERATE: '', AGENT_HEALTH_INCORRECT: 'incorrect', AGENT_HEALTH_FAILED: 'failed', AGENT_HEALTH_OVERTEMP: 'overtemp', AGENT_HEALTH_CHARGING: 'charging', AGENT_HEALTH_DISCHARGING: 'discharging' } AGENT_levels = { AGENT_LEVEL_TRIGGER_MAY_BE_LOW: 'low', AGENT_LEVEL_TRIGGER_PROBABLY_OUT: 'low', AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT: 'out' } MODEL_UI_REPLACEMENTS = { 'laserjet': 'LaserJet', 'psc': 'PSC', 'officejet': 'Officejet', 'deskjet': 'Deskjet', 'hp': 'HP', 'business': 'Business', 'inkjet': 'Inkjet', 'photosmart': 'Photosmart', 'color': 'Color', 'series': 'series', 'printer': 'Printer', 'mfp': 'MFP', 'mopier': 'Mopier' } def normalizeModelUIName(model): if not model.lower().startswith('hp'): z = 'HP ' + model.replace('_', ' ') else: z = model.replace('_', ' ') y = [] for x in z.split(): xx = x.lower() y.append(MODEL_UI_REPLACEMENTS.get(xx, xx)) return ' '.join(y) def normalizeModelName(model): return model.replace(' ', '_').replace('__', '_').replace('~', '').replace('/', '_').strip('_') def isLocal(bus): return bus in ('par', 'usb', 'fw', 'bt') string_cache = { } class Device(object): def __init__(self, device_uri, printer_name = None, hpssd_sock = None, hpiod_sock = None, callback = None): if device_uri is None: printers = cups.getPrinters() for p in printers: if p.name.lower() == printer_name.lower(): device_uri = p.device_uri break else: raise Error(ERROR_DEVICE_NOT_FOUND) self.device_uri = device_uri self.callback = callback self.close_socket = False self.query_device_thread = None try: (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port) = parseDeviceURI(self.device_uri) except Error: self.io_state = IO_STATE_NON_HP raise Error(ERROR_INVALID_DEVICE_URI) log.debug('URI: backend=%s, is_hp=%s, bus=%s, model=%s, serial=%s, dev=%s, host=%s, port=%d' % (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port)) self.model_ui = normalizeModelUIName(self.model) self.model = normalizeModelName(self.model) log.debug('Model/UI model: %s/%s' % (self.model, self.model_ui)) if hpiod_sock is None: self.hpiod_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.hpiod_sock.connect((prop.hpiod_host, prop.hpiod_port)) self.close_hpiod_socket = True except socket.error: raise Error(ERROR_UNABLE_TO_CONTACT_SERVICE) else: self.hpiod_sock = hpiod_sock log.debug('hpiod socket: %d' % self.hpiod_sock.fileno()) if hpssd_sock is None: self.hpssd_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.hpssd_sock.connect((prop.hpssd_host, prop.hpssd_port)) self.close_hpssd_socket = True except socket.error: raise Error(ERROR_UNABLE_TO_CONTACT_SERVICE) else: self.hpssd_sock = hpssd_sock log.debug('hpssd socket: %d' % self.hpssd_sock.fileno()) service.setAlertsEx(self.hpssd_sock) self.mq = { } self.dq = { } self.cups_printers = [] self.channels = { } self.device_id = -1 self.r_values = None self.deviceID = '' self.panel_check = True self.io_state = IO_STATE_HP_READY self.is_local = isLocal(self.bus) self.supported = False self.queryModel() if not (self.supported): log.error('Unsupported model: %s' % self.model) self.sendEvent(STATUS_DEVICE_UNSUPPORTED) else: self.supported = True self.mq.update({ 'model': self.model, 'model-ui': self.model_ui }) self.error_state = ERROR_STATE_ERROR self.device_state = DEVICE_STATE_NOT_FOUND self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND printers = cups.getPrinters() for p in printers: if self.device_uri == p.device_uri: self.cups_printers.append(p.name) self.state = p.state if self.io_state == IO_STATE_NON_HP: self.model = p.makemodel.split(',')[0] try: self.first_cups_printer = self.cups_printers[0] except IndexError: self.first_cups_printer = '' if self.mq.get('fax-type', FAX_TYPE_NONE) != FAX_TYPE_NONE: self.dq.update({ 'fax-uri': self.device_uri.replace('hp:/', 'hpfax:/').replace('hpaio:/', 'hpfax:/') }) if self.mq.get('scan-type', SCAN_TYPE_NONE) != SCAN_TYPE_NONE: self.dq.update({ 'scan-uri': self.device_uri.replace('hp:/', 'hpaio:/').replace('hpfax:/', 'hpaio:/') }) self.dq.update({ 'back-end': self.back_end, 'is-hp': self.is_hp, 'serial': self.serial, 'dev-file': self.dev_file, 'host': self.host, 'port': self.port, 'cups-printer': ','.join(self.cups_printers), 'status-code': self.status_code, 'status-desc': '', 'deviceid': '', 'panel': 0, 'panel-line1': '', 'panel-line2': '', '3bit-status-code': 0, '3bit-status-name': 'IOTrap', 'device-state': self.device_state, 'error-state': self.error_state, 'device-uri': self.device_uri, 'cups-uri': self.device_uri.replace('hpfax:/', 'hp:/').replace('hpaio:/', 'hp:/') }) self.device_vars = { 'URI': self.device_uri, 'DEVICE_URI': self.device_uri, 'SCAN_URI': self.device_uri.replace('hp:', 'hpaio:'), 'SANE_URI': self.device_uri.replace('hp:', 'hpaio:'), 'FAX_URI': self.device_uri.replace('hp:', 'hpfax:'), 'PRINTER': self.first_cups_printer, 'HOME': prop.home_dir } def xmitHpiodMessage(self, msg_type, other_fields = { }, payload = None, timeout = prop.read_timeout): return msg.xmitMessage(self.hpiod_sock, msg_type, payload, other_fields, timeout) def xmitHpssdMessage(self, msg_type, other_fields = { }, payload = None, timeout = prop.read_timeout): return msg.xmitMessage(self.hpssd_sock, msg_type, payload, other_fields, timeout) def quit(self): if self.close_hpiod_socket: self.hpiod_sock.close() if self.close_hpssd_socket: self.hpssd_sock.close() def queryModel(self): if not self.mq: (self.mq, data, result_code) = self.xmitHpssdMessage('QueryModel', { 'device-uri': self.device_uri }) self.supported = bool(self.mq) if self.supported: for m in self.mq: self.__dict__[m.replace('-', '_')] = self.mq[m] def queryString(self, string_id): if string_id not in string_cache: (fields, data, result_code) = self.xmitHpssdMessage('QueryString', { 'string-id': string_id }) if result_code == ERROR_SUCCESS: string_cache[string_id] = data return data else: return '' else: return string_cache[string_id] def open(self, network_timeout = 3): if self.supported and self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL): log.debug('Opening device: %s' % self.device_uri) prev_device_state = self.device_state self.io_state = IO_STATE_HP_NOT_AVAIL self.device_state = DEVICE_STATE_NOT_FOUND self.error_state = ERROR_STATE_ERROR self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND self.device_id = -1 (fields, data, result_code) = self.xmitHpiodMessage('DeviceOpen', { 'device-uri': self.device_uri, 'io-mode': self.mq.get('io-mode', '0'), 'io-mfp-mode': self.mq.get('io-mfp-mode', '2'), 'io-control': self.mq.get('io-control', '0'), 'io-scan-port': self.mq.get('io-scan-port', '0') }) if result_code != ERROR_SUCCESS: self.sendEvent(EVENT_ERROR_DEVICE_NOT_FOUND, typ = 'error') log.error('Unable to communicate with device: %s' % self.device_uri) raise Error(ERROR_DEVICE_NOT_FOUND) else: self.device_id = fields['device-id'] log.debug('device-id=%d' % self.device_id) self.io_state = IO_STATE_HP_OPEN self.error_state = ERROR_STATE_CLEAR log.debug('Opened device: %s (backend=%s,is_hp=%s,bus=%s,model=%s,dev=%s,serial=%s,host=%s,port=%d)' % (self.back_end, self.device_uri, self.is_hp, self.bus, self.model, self.dev_file, self.serial, self.host, self.port)) if prev_device_state == DEVICE_STATE_NOT_FOUND: self.device_state = DEVICE_STATE_JUST_FOUND else: self.device_state = DEVICE_STATE_FOUND self.getDeviceID() self.getSerialNumber() return self.device_id def close(self): if self.io_state == IO_STATE_HP_OPEN: log.debug('Closing device...') if len(self.channels) > 0: for c in self.channels.keys(): self._Device__closeChannel(c) (fields, data, result_code) = self.xmitHpiodMessage('DeviceClose', { 'device-id': self.device_id }) self.channels.clear() self.io_state = IO_STATE_HP_READY def __openChannel(self, service_name): self.open() if not self.mq['io-mode'] == IO_MODE_UNI: service_name = service_name.upper() if service_name not in self.channels: log.debug('Opening %s channel...' % service_name) (fields, data, result_code) = self.xmitHpiodMessage('ChannelOpen', { 'device-id': self.device_id, 'service-name': service_name }) try: channel_id = fields['channel-id'] except KeyError: raise Error(ERROR_INTERNAL) self.channels[service_name] = channel_id log.debug('channel-id=%d' % channel_id) return channel_id else: return self.channels[service_name] else: return -1 def openChannel(self, service_name): return self._Device__openChannel(service_name) def openPrint(self): return self._Device__openChannel('PRINT') def openFax(self): return self._Device__openChannel('HP-FAX-SEND') def openPCard(self): return self._Device__openChannel('HP-CARD-ACCESS') def openFax(self): return self._Device__openChannel('HP-FAX-SEND') def openEWS(self): return self._Device__openChannel('HP-EWS') def closePrint(self): return self._Device__closeChannel('PRINT') def closePCard(self): return self._Device__closeChannel('HP-CARD-ACCESS') def closeFax(self): return self._Device__closeChannel('HP-FAX') def openPML(self): return self._Device__openChannel('HP-MESSAGE') def closePML(self): return self._Device__closeChannel('HP-MESSAGE') def closeEWS(self): return self._Device__closeChannel('HP-EWS') def openCfgUpload(self): return self._Device__openChannel('HP-CONFIGURATION-UPLOAD') def closeCfgUpload(self): return self._Device__closeChannel('HP-CONFIGURATION-UPLOAD') def openCfgDownload(self): return self._Device__openChannel('HP-CONFIGURATION-DOWNLOAD') def closeCfgDownload(self): return self._Device__closeChannel('HP-CONFIGURATION-DOWNLOAD') def __closeChannel(self, service_name): if not (self.mq['io-mode'] == IO_MODE_UNI) and self.io_state == IO_STATE_HP_OPEN: service_name = service_name.upper() if service_name in self.channels: log.debug('Closing %s channel...' % service_name) (fields, data, result_code) = self.xmitHpiodMessage('ChannelClose', { 'device-id': self.device_id, 'channel-id': self.channels[service_name] }) del self.channels[service_name] def closeChannel(self, service_name): return self._Device__closeChannel(service_name) def getDeviceID(self): (fields, data, result_code) = self.xmitHpiodMessage('DeviceID', { 'device-id': self.device_id }) if result_code != ERROR_SUCCESS: self.raw_deviceID = '' self.deviceID = { } else: self.raw_deviceID = data self.deviceID = parseDeviceID(data) return self.deviceID def getSerialNumber(self): if self.serial: return None try: self.serial = self.deviceID['SN'] except KeyError: pass if self.serial: return None if self.mq.get('status-type', STATUS_TYPE_NONE) != STATUS_TYPE_NONE and not (self.mq.get('io-mode', IO_MODE_UNI) == IO_MODE_UNI): try: (error_code, self.serial) = self.getPML(pml.OID_SERIAL_NUMBER) except Error: self.serial = '' finally: self.closePML() if self.serial is None: self.serial = '' def getThreeBitStatus(self): (fields, data, result_code) = self.xmitHpiodMessage('DeviceStatus', { 'device-id': self.device_id }) if result_code != ERROR_SUCCESS: self.three_bit_status_code = 0 self.three_bit_status_name = 'IOTrap' else: self.three_bit_status_code = fields['status-code'] self.three_bit_status_name = fields['status-name'] def getStatusFromDeviceID(self): self.getDeviceID() return status.parseStatus(parseDeviceID(self.raw_deviceID)) def queryDevice(self, quick = False): if not (self.supported): self.dq = { } return None r_type = self.mq.get('r-type', 0) tech_type = self.mq.get('tech-type', TECH_TYPE_NONE) status_type = self.mq.get('status-type', STATUS_TYPE_NONE) io_mode = self.mq.get('io-mode', IO_MODE_UNI) if io_mode == IO_MODE_UNI and self.back_end != 'net': status_type = STATUS_TYPE_NONE agents = [] if self.device_state != DEVICE_STATE_NOT_FOUND: try: self.getThreeBitStatus() except Error: e = None log.error('Error getting 3-bit status.') raise Error(ERROR_DEVICE_IO_ERROR) if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK): try: self.getDeviceID() except Error: e = None log.error('Error getting device ID.') raise Error(ERROR_DEVICE_IO_ERROR) try: status_desc = self.queryString(self.status_code) except Error: status_desc = '' self.dq.update({ 'serial': self.serial, 'cups-printer': ','.join(self.cups_printers), 'status-code': self.status_code, 'status-desc': status_desc, 'deviceid': self.raw_deviceID, 'panel': 0, 'panel-line1': '', 'panel-line2': '', '3bit-status-code': self.three_bit_status_code, '3bit-status-name': self.three_bit_status_name, 'device-state': self.device_state, 'error-state': self.error_state }) status_block = { } if status_type == STATUS_TYPE_NONE: log.warn('No status available for device.') status_block = { 'status-code': STATUS_PRINTER_IDLE } elif status_type in (STATUS_TYPE_VSTATUS, STATUS_TYPE_S, STATUS_TYPE_S_SNMP): log.debug('Type 1/2 (S: or VSTATUS:) status') status_block = status.parseStatus(self.deviceID) elif status_type == STATUS_TYPE_LJ: log.debug('Type 3 LaserJet status') status_block = status.StatusType3(self, self.deviceID) elif status_type == STATUS_TYPE_S_W_BATTERY: log.debug('Type 4 S: status with battery check') status_block = status.parseStatus(self.deviceID) status.BatteryCheck(self, status_block) elif status_type == STATUS_TYPE_LJ_XML: log.debug('Type 6: LJ XML') status_block = status.StatusType6(self) else: log.error('Unimplemented status type: %d' % status_type) if status_block: log.debug(status_block) self.dq.update(status_block) try: status_block['agents'] except KeyError: pass agents = status_block['agents'] del self.dq['agents'] status_code = self.dq.get('status-code', STATUS_UNKNOWN) if not quick and self.mq.get('fax-type', 0) and status_code == STATUS_PRINTER_IDLE: (tx_active, rx_active) = status.getFaxStatus(self) if tx_active: status_code = STATUS_FAX_TX_ACTIVE elif rx_active: status_code = STATUS_FAX_RX_ACTIVE typ = 'event' self.error_state = STATUS_TO_ERROR_STATE_MAP.get(status_code, ERROR_STATE_CLEAR) if self.error_state == ERROR_STATE_ERROR: typ = 'error' self.sendEvent(status_code, typ = typ) try: self.dq.update({ 'status-desc': self.queryString(status_code), 'error-state': self.error_state }) except (KeyError, Error): self.dq.update({ 'status-desc': '', 'error-state': ERROR_STATE_CLEAR }) if not quick: (r_value, rg, rr, r_value_str) = (0, '000', '000000', '000000000') if status_type != STATUS_TYPE_NONE: if self.panel_check: self.panel_check = bool(self.mq.get('panel-check-type', 0)) if self.panel_check and status_type in (STATUS_TYPE_NONE, STATUS_TYPE_LJ, STATUS_TYPE_S_W_BATTERY, STATUS_TYPE_S_SNMP): try: (self.panel_check, line1, line2) = status.PanelCheck(self) finally: self.closePML() self.dq.update({ 'panel': int(self.panel_check), 'panel-line1': line1, 'panel-line2': line2 }) if r_type > 0: if self.r_values is None: (fields, data, result_code) = self.xmitHpssdMessage('GetValue', { 'device-uri': self.device_uri, 'key': 'r_value' }) if result_code == ERROR_SUCCESS and data: try: r_value = int(data.strip()) except: pass log.debug('r_value=%d' % r_value) r_value_str = str(r_value) r_value_str = ''.join([ '0' * (9 - len(r_value_str)), r_value_str]) (rg, rr) = (r_value_str[:3], r_value_str[3:]) r_value = int(rr) self.r_values = (r_value, r_value_str, rg, rr) if self.r_values is None: if status_type == STATUS_TYPE_S and self.is_local: try: r_value = self.getDynamicCounter(140) if r_value is not None: log.debug('r_value=%d' % r_value) r_value_str = str(r_value) r_value_str = ''.join([ '0' * (9 - len(r_value_str)), r_value_str]) (rg, rr) = (r_value_str[:3], r_value_str[3:]) r_value = int(rr) self.r_values = (r_value, r_value_str, rg, rr) (fields, data, result_code) = self.xmitHpssdMessage('SetValue', { 'device-uri': self.device_uri, 'key': 'r_value', 'value': r_value }) else: log.error('Error attempting to read r-value (2).') r_value = 0 except Error: log.error('Error attempting to read r-value (1).') r_value = 0 finally: self.closePrint() elif status_type == STATUS_TYPE_S and not (self.is_local) or status_type == STATUS_TYPE_S_SNMP: try: (result_code, r_value) = self.getPML(pml.OID_R_SETTING) if r_value is not None: log.debug('r_value=%d' % r_value) r_value_str = str(r_value) r_value_str = ''.join([ '0' * (9 - len(r_value_str)), r_value_str]) (rg, rr) = (r_value_str[:3], r_value_str[3:]) r_value = int(rr) self.r_values = (r_value, r_value_str, rg, rr) (fields, data, result_code) = self.xmitHpssdMessage('SetValue', { 'device-uri': self.device_uri, 'key': 'r_value', 'value': r_value }) else: r_value = 0 finally: self.closePML() else: (r_value, r_value_str, rg, rr) = self.r_values self.dq.update({ 'r': r_value, 'rs': r_value_str, 'rg': rg, 'rr': rr }) if not quick: a = 1 while True: mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), 0) if mq_agent_kind == 0: break mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0) mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '') found = False for agent in agents: agent_kind = agent['kind'] agent_type = agent['type'] if agent_kind == mq_agent_kind and agent_type == mq_agent_type: found = True break if found: agent_health = agent.get('health', AGENT_HEALTH_OK) agent_level_trigger = agent.get('level-trigger', AGENT_LEVEL_TRIGGER_SUFFICIENT_0) query = 'agent_%s_%s' % (AGENT_types.get(agent_type, 'unknown'), AGENT_kinds.get(agent_kind, 'unknown')) try: agent_desc = self.queryString(query) except Error: agent_desc = '' query = 'agent_health_ok' if status_code == STATUS_PRINTER_IDLE: if agent_health == AGENT_HEALTH_OK and agent_health == AGENT_HEALTH_FAIR_MODERATE and agent_kind == AGENT_KIND_HEAD and agent_level_trigger >= AGENT_LEVEL_TRIGGER_MAY_BE_LOW: query = 'agent_level_%s' % AGENT_levels.get(agent_level_trigger, 'unknown') if tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK): code = agent_type + STATUS_PRINTER_LOW_INK_BASE else: code = agent_type + STATUS_PRINTER_LOW_TONER_BASE self.dq['status-code'] = code try: self.dq['status-desc'] = self.queryString(code) except Error: self.dq['status-desc'] = '' self.dq['error-state'] = STATUS_TO_ERROR_STATE_MAP.get(code, ERROR_STATE_LOW_SUPPLIES) self.sendEvent(code) if agent_level_trigger in (AGENT_LEVEL_TRIGGER_PROBABLY_OUT, AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT): query = 'agent_level_out' else: query = 'agent_level_low' try: agent_health_desc = self.queryString(query) except Error: agent_health_desc = '' self.dq.update({ 'agent%d-kind' % a: agent_kind, 'agent%d-type' % a: agent_type, 'agent%d-known' % a: agent.get('known', False), 'agent%d-sku' % a: mq_agent_sku, 'agent%d-level' % a: agent.get('level', 0), 'agent%d-level-trigger' % a: agent_level_trigger, 'agent%d-ack' % a: agent.get('ack', False), 'agent%d-hp-ink' % a: agent.get('hp-ink', False), 'agent%d-health' % a: agent_health, 'agent%d-dvc' % a: agent.get('dvc', 0), 'agent%d-virgin' % a: agent.get('virgin', False), 'agent%d-desc' % a: agent_desc, 'agent%d-id' % a: agent.get('id', 0), 'agent%d-health-desc' % a: agent_health_desc }) else: agent_health = AGENT_HEALTH_MISINSTALLED agent_level_trigger = AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT query = 'agent_%s_%s' % (AGENT_types.get(mq_agent_type, 'unknown'), AGENT_kinds.get(mq_agent_kind, 'unknown')) try: agent_desc = self.queryString(query) except Error: agent_desc = '' try: agent_health_desc = self.queryString('agent_health_misinstalled') except Error: agent_health_desc = '' self.dq.update({ 'agent%d-kind' % a: mq_agent_kind, 'agent%d-type' % a: mq_agent_type, 'agent%d-known' % a: False, 'agent%d-sku' % a: mq_agent_sku, 'agent%d-level' % a: 0, 'agent%d-level-trigger' % a: agent_level_trigger, 'agent%d-ack' % a: False, 'agent%d-hp-ink' % a: False, 'agent%d-health' % a: agent_health, 'agent%d-dvc' % a: 0, 'agent%d-virgin' % a: False, 'agent%d-desc' % a: agent_desc, 'agent%d-id' % a: 0, 'agent%d-health-desc' % a: agent_health_desc }) a += 1 r_value = 0 if r_type > 0 and self.r_values is not None: r_value = self.r_values[0] a = 1 while True: mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), 0) if mq_agent_kind == 0: break mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0) mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '') query = 'agent_%s_%s' % (AGENT_types.get(mq_agent_type, 'unknown'), AGENT_kinds.get(mq_agent_kind, 'unknown')) try: agent_desc = self.queryString(query) except Error: agent_desc = '' self.dq.update({ 'agent%d-kind' % a: mq_agent_kind, 'agent%d-type' % a: mq_agent_type, 'agent%d-known' % a: False, 'agent%d-sku' % a: mq_agent_sku, 'agent%d-level' % a: 0, 'agent%d-level-trigger' % a: AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT, 'agent%d-ack' % a: False, 'agent%d-hp-ink' % a: False, 'agent%d-health' % a: AGENT_HEALTH_MISINSTALLED, 'agent%d-dvc' % a: 0, 'agent%d-virgin' % a: False, 'agent%d-health-desc' % a: self.queryString('agent_health_unknown'), 'agent%d-desc' % a: agent_desc, 'agent%d-id' % a: 0 }) a += 1 for d in self.dq: self.__dict__[d.replace('-', '_')] = self.dq[d] log.debug(self.dq) def isBusyOrInErrorState(self): self.queryDevice(quick = True) return self.error_state in (ERROR_STATE_ERROR, ERROR_STATE_BUSY) def isIdleAndNoError(self): self.queryDevice(quick = True) return self.error_state not in (ERROR_STATE_ERROR, ERROR_STATE_BUSY) def getPML(self, oid, desired_int_size = pml.INT_SIZE_INT): channel_id = self.openPML() (fields, data, result_code) = self.xmitHpiodMessage('GetPML', { 'device-id': self.device_id, 'channel-id': channel_id, 'oid': pml.PMLToSNMP(oid[0]), 'type': oid[1] }) pml_result_code = fields.get('pml-result-code', pml.ERROR_OK) if pml_result_code >= pml.ERROR_UNKNOWN_REQUEST: return (pml_result_code, None) return (pml_result_code, pml.ConvertFromPMLDataFormat(data, oid[1], desired_int_size)) def setPML(self, oid, value): channel_id = self.openPML() value = pml.ConvertToPMLDataFormat(value, oid[1]) (fields, data, result_code) = self.xmitHpiodMessage('SetPML', { 'device-id': self.device_id, 'channel-id': channel_id, 'oid': pml.PMLToSNMP(oid[0]), 'type': oid[1] }, value) return fields.get('pml-result-code', pml.ERROR_OK) def getDynamicCounter(self, counter, convert_to_int = True): if 'DYN' in self.deviceID.get('CMD', '').split(','): self.printData(pcl.buildDynamicCounter(counter), direct = True) (value, tries, times_seen, sleepy_time, max_tries) = (0, 0, 0, 0.10000000000000001, 5) time.sleep(0.10000000000000001) while True: if self.callback: self.callback() sleepy_time += 0.10000000000000001 tries += 1 time.sleep(sleepy_time) self.getDeviceID() if 'CTR' in self.deviceID and pat_dynamic_ctr.search(self.raw_deviceID) is not None: (dev_counter, value) = parseDynamicCounter(self.deviceID['CTR'], convert_to_int) if counter == dev_counter: self.printData(pcl.buildDynamicCounter(0), direct = True) if not convert_to_int: value = '#' + value return value if tries > max_tries: self.printData(pcl.buildDynamicCounter(0), direct = True) return None self.printData(pcl.buildDynamicCounter(counter), direct = True) else: raise Error(ERROR_DEVICE_DOES_NOT_SUPPORT_OPERATION) def readPrint(self, bytes_to_read, stream = None, timeout = prop.read_timeout): return self._Device__readChannel(self.openPrint, bytes_to_read, stream, timeout) def readPCard(self, bytes_to_read, stream = None, timeout = prop.read_timeout): return self._Device__readChannel(self.openPCard, bytes_to_read, stream, timeout) def readFax(self, bytes_to_read, stream = None, timeout = prop.read_timeout): return self._Device__readChannel(self.openFax, bytes_to_read, stream, timeout) def readCfgUpload(self, bytes_to_read, stream = None, timeout = prop.read_timeout): return self._Device__readChannel(self.openCfgUpload, bytes_to_read, stream, timeout) def readEWS(self, bytes_to_read, stream = None, timeout = prop.read_timeout): return self._Device__readChannel(self.openEWS, bytes_to_read, stream, timeout, True) def __readChannel(self, opener, bytes_to_read, stream = None, timeout = prop.read_timeout, allow_short_read = False): channel_id = opener() log.debug('Reading channel %d...' % channel_id) num_bytes = 0 if stream is None: buffer = '' while True: (fields, data, result_code) = self.xmitHpiodMessage('ChannelDataIn', { 'device-id': self.device_id, 'channel-id': channel_id, 'bytes-to-read': bytes_to_read, 'timeout': timeout }) l = len(data) if result_code != ERROR_SUCCESS: log.error('Channel read error') raise Error(ERROR_DEVICE_IO_ERROR) if not l: log.debug('End of data') break if stream is None: buffer = ''.join([ buffer, data]) else: stream.write(data) num_bytes += l if self.callback is not None: self.callback() if num_bytes == bytes_to_read or allow_short_read: log.debug('Read complete') break continue if stream is None: log.debug('Returned %d total bytes in buffer.' % num_bytes) return buffer else: log.debug('Wrote %d total bytes to stream.' % num_bytes) return num_bytes def writePrint(self, data): return self._Device__writeChannel(self.openPrint, data) def writePCard(self, data): return self._Device__writeChannel(self.openPCard, data) def writeFax(self, data): return self._Device__writeChannel(self.openFax, data) def writeEWS(self, data): return self._Device__writeChannel(self.openEWS, data) def writeCfgDownload(self, data): return self._Device__writeChannel(self.openCfgDownload, data) def __writeChannel(self, opener, data): channel_id = opener() log.debug('Writing channel %d...' % channel_id) buffer = data bytes_out = 0 total_bytes_to_write = len(data) while len(buffer) > 0: (fields, data, result_code) = self.xmitHpiodMessage('ChannelDataOut', { 'device-id': self.device_id, 'channel-id': channel_id }, buffer[:prop.max_message_len]) if result_code != ERROR_SUCCESS: log.error('Channel write error') raise Error(ERROR_DEVICE_IO_ERROR) buffer = buffer[prop.max_message_len:] bytes_out += fields['bytes-written'] if self.callback is not None: self.callback() continue if total_bytes_to_write != bytes_out: raise Error(ERROR_DEVICE_IO_ERROR) return bytes_out def writeEmbeddedPML(self, oid, value, style = 1, direct = True): if style == 1: func = pcl.buildEmbeddedPML2 else: func = pcl.buildEmbeddedPML data = func(pcl.buildPCLCmd('&', 'b', 'W', pml.buildEmbeddedPMLSetPacket(oid[0], value, oid[1]))) self.printData(data, direct = True) def printGzipFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False): return self.printFile(file_name, printer_name, direct, raw, remove) def printParsedGzipPostscript(self, print_file, printer_name = None): try: os.stat(print_file) except OSError: log.error('File not found: %s' % print_file) return None (temp_file_fd, temp_file_name) = utils.make_temp_file() f = gzip.open(print_file, 'r') x = f.readline() while not x.startswith('%PY_BEGIN'): os.write(temp_file_fd, x) x = f.readline() sub_lines = [] x = f.readline() while not x.startswith('%PY_END'): sub_lines.append(x) x = f.readline() SUBS = { 'VERSION': prop.version, 'MODEL': self.model_ui, 'URI': self.device_uri, 'BUS': self.bus, 'SERIAL': self.serial, 'IP': self.host, 'PORT': self.port, 'DEVNODE': self.dev_file } if self.bus == 'net': SUBS['DEVNODE'] = 'n/a' else: SUBS['IP'] = 'n/a' SUBS['PORT'] = 'n/a' for s in sub_lines: os.write(temp_file_fd, s % SUBS) os.write(temp_file_fd, f.read()) f.close() os.close(temp_file_fd) self.printFile(temp_file_name, printer_name, direct = False, raw = False, remove = True) def printFile(self, file_name, printer_name = None, direct = False, raw = True, remove = False): is_gzip = os.path.splitext(file_name)[-1].lower() == '.gz' if printer_name is None: try: printer_name = self.cups_printers[0] except IndexError: raise Error(ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE) except: None<EXCEPTION MATCH>IndexError None<EXCEPTION MATCH>IndexError log.debug("Printing file '%s' to queue '%s' (gzip=%s, direct=%s, raw=%s, remove=%s)" % (file_name, printer_name, is_gzip, direct, raw, remove)) if direct: if is_gzip: self.writePrint(gzip.open(file_name, 'r').read()) else: self.writePrint(file(file_name, 'r').read()) elif raw: lp_opt = '-oraw' else: lp_opt = '' if is_gzip: c = 'gunzip -c %s | lp -c -d%s %s' % (file_name, printer_name, lp_opt) else: c = 'lp -c -d%s %s %s' % (printer_name, lp_opt, file_name) log.debug(c) os.system(c) if remove: os.remove(file_name) def printTestPage(self, printer_name = None): return self.printParsedGzipPostscript(os.path.join(prop.home_dir, 'data', 'ps', 'testpage.ps.gz'), printer_name) def printData(self, data, printer_name = None, direct = True, raw = True): if direct: self.writePrint(data) else: (temp_file_fd, temp_file_name) = utils.make_temp_file() os.write(temp_file_fd, data) os.close(temp_file_fd) self.printFile(temp_file_name, printer_name, direct, raw, remove = True) def cancelJob(self, jobid): cups.cancelJob(jobid) self.sendEvent(STATUS_PRINTER_CANCELING, jobid) def sendEvent(self, event, jobid = 0, typ = 'event'): msg.sendEvent(self.hpssd_sock, 'Event', None, { 'job-id': jobid, 'event-type': typ, 'event-code': event, 'username': prop.username, 'device-uri': self.device_uri, 'retry-timeout': 0 }) def queryHistory(self): (fields, data, result_code) = self.xmitHpssdMessage('QueryHistory', { 'device-uri': self.device_uri }) result = [] lines = data.strip().splitlines() lines.reverse() for x in lines: (yr, mt, dy, hr, mi, sec, wd, yd, dst, job, user, ec, ess, esl) = x.strip().split(',', 13) result.append((int(yr), int(mt), int(dy), int(hr), int(mi), int(sec), int(wd), int(yd), int(dst), int(job), user, int(ec), ess, esl)) return result def getEWSUrl(self, url, stream): try: if self.is_local: url2 = '%s&loc=%s' % (self.device_uri, url) data = self else: url2 = 'http://%s%s' % (self.host, url) data = None log.debug('Opening: %s' % url2) opener = LocalOpener({ }) try: f = opener.open(url2, data) except Error: log.error('Status read failed: %s' % url2) stream.seek(0) stream.truncate() try: stream.write(f.read()) finally: f.close() finally: self.closeEWS() class xStringIO(StringIO.StringIO): def makefile(self, x, y): return self class LocalOpener(urllib.URLopener): def open_hp(self, url, dev): log.debug('open_hp(%s)' % url) match_obj = http_pat_url.search(url) if not match_obj.group(1): pass bus = '' if not match_obj.group(2): pass model = '' if not match_obj.group(3): pass serial = '' if not match_obj.group(4): pass device = '' if not match_obj.group(5): pass loc = '' dev.openEWS() dev.writeEWS('GET %s HTTP/1.0\nContent-Length:0\nHost:localhost\nUser-Agent:hplip\n\n' % loc) reply = xStringIO() dev.readEWS(MAX_BUFFER, reply) reply.seek(0) response = httplib.HTTPResponse(reply) response.begin() if response.status != httplib.OK: raise Error(ERROR_DEVICE_STATUS_NOT_AVAILABLE) else: return response.fp