58
63
except ImportError:
59
64
log.warn("python-dbus not installed.")
67
# Ignore: .../dbus/connection.py:242: DeprecationWarning: object.__init__() takes no parameters
68
# (occurring on Python 2.6/dBus 0.83/Ubuntu 9.04)
69
warnings.simplefilter("ignore", DeprecationWarning)
62
72
DEFAULT_PROBE_BUS = ['usb', 'par', 'cups']
63
73
VALID_BUSES = ('par', 'net', 'cups', 'usb') #, 'bt', 'fw')
66
76
VALID_FILTERS = ('print', 'scan', 'fax', 'pcard', 'copy')
67
77
DEFAULT_BE_FILTER = ('hp',)
69
pat_deviceuri = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*))(?:&port=(\d))?""", re.IGNORECASE)
79
pat_deviceuri = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*)|zc=(\S+))(?:&port=(\d))?""", re.IGNORECASE)
70
80
http_pat_url = re.compile(r"""/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*))&loc=(\S*)""", re.IGNORECASE)
71
81
direct_pat = re.compile(r'direct (.*?) "(.*?)" "(.*?)" "(.*?)"', re.IGNORECASE)
74
84
# Note: If ; not present, CTR value is invalid
75
85
pat_dynamic_ctr = re.compile(r"""CTR:\d*\s.*;""", re.IGNORECASE)
79
87
# Cache for model data
80
88
model_dat = models.ModelData()
82
90
ip_pat = re.compile(r"""\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)
84
91
dev_pat = re.compile(r"""/dev/.+""", re.IGNORECASE)
85
92
usb_pat = re.compile(r"""(\d+):(\d+)""", re.IGNORECASE)
297
304
cups_uri, sane_uri, fax_uri = '', '', ''
300
# see if the param represents a hostname
302
param = socket.gethostbyname(param)
303
except socket.gaierror:
304
log.debug("Gethostbyname() failed. Trying other patterns...")
306
307
if dev_pat.search(param) is not None: # parallel
307
308
log.debug("Trying parallel with %s" % param)
343
344
log.debug("Not found.")
346
else: # Try Zeroconf hostname
347
log.debug("Trying ZC hostname %s" % param)
349
result_code, uri = hpmudext.make_zc_uri(param, port)
351
if result_code == hpmudext.HPMUD_R_OK and uri:
352
log.debug("Found: %s" % uri)
356
log.debug("Not found.")
346
359
log.debug("Trying serial number %s" % param)
347
360
devices = probeDevices(bus=['usb', 'par'])
352
365
# usb has serial in URI...
354
back_end, is_hp, bus, model, serial, dev_file, host, port = \
367
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
355
368
parseDeviceURI(d)
413
426
def queryModelByURI(device_uri):
415
428
back_end, is_hp, bus, model, \
416
serial, dev_file, host, port = \
429
serial, dev_file, host, zc, port = \
417
430
parseDeviceURI(device_uri)
419
432
raise Error(ERROR_INVALID_DEVICE_URI)
428
441
def probeDevices(bus=DEFAULT_PROBE_BUS, timeout=10,
429
ttl=4, filter=DEFAULT_FILTER, search='', net_search='slp',
442
ttl=4, filter=DEFAULT_FILTER, search='', net_search='mdns',
430
443
back_end_filter=('hp',)):
432
445
num_devices, ret_devices = 0, {}
473
486
model = models.normalizeModelName(device_id.get('MDL', '?UNKNOWN?'))
475
488
if num_ports_on_jd == 1:
476
device_uri = 'hp:/net/%s?ip=%s' % (model, ip)
489
if net_search == 'slp':
490
device_uri = 'hp:/net/%s?ip=%s' % (model, ip)
492
device_uri = 'hp:/net/%s?zc=%s' % (model, hn)
478
device_uri = 'hp:/net/%s?ip=%s&port=%d' % (model, ip, (port+1))
494
if net_search == 'slp':
495
device_uri = 'hp:/net/%s?ip=%s&port=%d' % (model, ip, (port + 1))
497
device_uri = 'hp:/net/%s?zc=%s&port=%d' % (model, hn, (port + 1))
481
500
mq = queryModelByModel(model)
517
back_end, is_hp, bb, model, serial, dev_file, host, port = \
536
back_end, is_hp, bb, model, serial, dev_file, host, zc, port = \
518
537
parseDeviceURI(uri)
549
568
if device_uri != '':
551
back_end, is_hp, bs, model, serial, dev_file, host, port = \
570
back_end, is_hp, bs, model, serial, dev_file, host, zc, port = \
552
571
parseDeviceURI(device_uri)
554
573
log.debug("Unrecognized URI: %s" % device_uri)
604
623
for p in printers:
606
back_end, is_hp, bus, model, serial, dev_file, host, port = \
625
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
607
626
parseDeviceURI(p.device_uri)
650
669
for p in printers:
652
back_end, is_hp, bus, model, serial, dev_file, host, port = \
671
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
653
672
parseDeviceURI(p.device_uri)
693
712
for p in printers:
695
back_end, is_hp, bus, model, serial, dev_file, host, port = \
714
back_end, is_hp, bus, model, serial, dev_file, host, zc, port = \
696
715
parseDeviceURI(p.device_uri)
799
return back_end, is_hp, bus, model, serial, dev_file, host, port
821
log.debug("%s: back_end:%s is_hp:%s bus:%s model:%s serial:%s dev_file:%s host:%s zc:%s port:%s" %
822
(device_uri, back_end, is_hp, bus, model, serial, dev_file, host, zc, port))
824
return back_end, is_hp, bus, model, serial, dev_file, host, zc, port
802
827
def isLocal(bus):
921
946
AGENT_types = { AGENT_TYPE_NONE : 'invalid',
922
947
AGENT_TYPE_BLACK : 'black',
948
AGENT_TYPE_BLACK_B8800 : 'black',
923
949
AGENT_TYPE_CMY : 'cmy',
924
950
AGENT_TYPE_KCM : 'kcm',
925
951
AGENT_TYPE_CYAN : 'cyan',
1034
1060
self.back_end, self.is_hp, self.bus, self.model, \
1035
self.serial, self.dev_file, self.host, self.port = \
1061
self.serial, self.dev_file, self.host, self.zc, self.port = \
1036
1062
parseDeviceURI(self.device_uri)
1038
1064
self.io_state = IO_STATE_NON_HP
1080
1106
self.device_state = DEVICE_STATE_NOT_FOUND
1081
1107
self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND
1084
if self.device_uri == p.device_uri:
1085
self.cups_printers.append(p.name)
1086
self.state = p.state # ?
1088
if self.io_state == IO_STATE_NON_HP:
1089
self.model = p.makemodel.split(',')[0]
1092
self.first_cups_printer = self.cups_printers[0]
1094
self.first_cups_printer = ''
1109
self.updateCUPSPrinters()
1096
1111
if self.mq.get('fax-type', FAX_TYPE_NONE) != FAX_TYPE_NONE:
1097
1112
self.dq.update({ 'fax-uri' : self.device_uri.replace('hp:/', 'hpfax:/').replace('hpaio:/', 'hpfax:/')})
1106
1121
'dev-file' : self.dev_file,
1107
1122
'host' : self.host,
1108
1123
'port' : self.port,
1109
'cups-printer' : ','.join(self.cups_printers),
1124
'cups-printers' : self.cups_printers,
1110
1125
'status-code' : self.status_code,
1111
1126
'status-desc' : '',
1112
1127
'deviceid' : '',
1163
1178
def open(self, open_for_printing=False):
1165
# raise Error(ERROR_DEVICE_NOT_FOUND)
1168
1179
if self.supported and self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL):
1169
1180
prev_device_state = self.device_state
1170
1181
self.io_state = IO_STATE_HP_NOT_AVAIL
1318
1332
def closeSoapFax(self):
1319
1333
return self.__closeChannel(hpmudext.HPMUD_S_SOAP_FAX)
1335
def closeWifiConfig(self):
1336
return self.__closeChannel(hpmudext.HPMUD_S_WIFI_CHANNEL)
1321
1338
def __closeChannel(self, service_name):
1322
1339
#if not self.mq['io-mode'] == IO_MODE_UNI and \
1323
1340
if self.io_state == IO_STATE_HP_OPEN:
1488
1505
def __queryFax(self, quick=False, reread_cups_printers=False):
1489
# print "__queryFax()"
1490
# raise Error(ERROR_DEVICE_IO_ERROR)
1493
1506
io_mode = self.mq.get('io-mode', IO_MODE_UNI)
1494
1507
self.status_code = STATUS_PRINTER_IDLE
1509
1522
status_desc = self.queryString(self.status_code)
1511
#print self.status_code
1513
1524
self.dq.update({
1514
1525
'serial' : self.serial,
1515
'cups-printer' : ','.join(self.cups_printers),
1526
'cups-printers' : self.cups_printers,
1516
1527
'status-code' : self.status_code,
1517
1528
'status-desc' : status_desc,
1518
1529
'deviceid' : self.raw_deviceID,
1533
1544
elif rx_active:
1534
1545
self.status_code = STATUS_FAX_RX_ACTIVE
1536
#print self.status_code
1538
1547
self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.status_code, ERROR_STATE_CLEAR)
1539
1548
self.error_code = self.status_code
1540
1549
self.sendEvent(self.error_code)
1542
#print "Error state=", self.error_state, self.device_uri
1545
1552
self.dq.update({'status-desc' : self.queryString(self.status_code),
1546
1553
'error-state' : self.error_state,
1571
1578
'panel-line2': line2,})
1573
1580
if not quick and reread_cups_printers:
1574
self.cups_printers = []
1575
log.debug("Re-reading CUPS printer queue information.")
1576
printers = cups.getPrinters()
1578
if self.device_uri == p.device_uri:
1579
self.cups_printers.append(p.name)
1580
self.state = p.state # ?
1582
if self.io_state == IO_STATE_NON_HP:
1583
self.model = p.makemodel.split(',')[0]
1585
self.dq.update({'cups-printer' : ','.join(self.cups_printers)})
1588
self.first_cups_printer = self.cups_printers[0]
1590
self.first_cups_printer = ''
1581
self.updateCUPSPrinters()
1593
1583
for d in self.dq:
1594
1584
self.__dict__[d.replace('-','_')] = self.dq[d]
1596
1586
self.last_event = Event(self.device_uri, '', self.status_code, prop.username, 0, '', time.time())
1597
#print self.last_event
1599
1588
log.debug(self.dq)
1603
#pprint.pprint(self.dq)
1592
def updateCUPSPrinters(self):
1593
self.cups_printers = []
1594
log.debug("Re-reading CUPS printer queue information.")
1595
printers = cups.getPrinters()
1597
if self.device_uri == p.device_uri:
1598
self.cups_printers.append(p.name)
1599
self.state = p.state # ?
1601
if self.io_state == IO_STATE_NON_HP:
1602
self.model = p.makemodel.split(',')[0]
1604
self.dq.update({'cups-printers' : self.cups_printers})
1607
self.first_cups_printer = self.cups_printers[0]
1609
self.first_cups_printer = ''
1608
1614
def queryDevice(self, quick=False, reread_cups_printers=False):
1609
# print "queryDevice()"
1610
# raise Error(ERROR_DEVICE_IO_ERROR)
1613
1615
if not self.supported:
1652
1654
self.dq.update({
1653
1655
'serial' : self.serial,
1654
'cups-printer' : ','.join(self.cups_printers),
1656
'cups-printers' : self.cups_printers,
1655
1657
'status-code' : self.status_code,
1656
1658
'status-desc' : status_desc,
1657
1659
'deviceid' : self.raw_deviceID,
1684
1686
log.debug("Type 8: LJ PJL")
1685
1687
status_block = status.StatusType8(self)
1689
elif status_type == STATUS_TYPE_LEDM:
1690
log.debug("Type 10: LEDM")
1691
status_block = status.StatusType10(self)
1688
1694
log.error("Unimplemented status type: %d" % status_type)
1726
1732
self.error_code = status_code
1727
1733
self.sendEvent(self.error_code)
1729
#print "Error state=", self.error_state, self.device_uri
1732
1736
self.dq.update({'status-desc' : self.queryString(status_code),
1733
1737
'error-state' : self.error_state,
1775
1779
if not quick and reread_cups_printers:
1776
self.cups_printers = []
1777
log.debug("Re-reading CUPS printer queue information.")
1778
printers = cups.getPrinters()
1780
if self.device_uri == p.device_uri:
1781
self.cups_printers.append(p.name)
1782
self.state = p.state # ?
1784
if self.io_state == IO_STATE_NON_HP:
1785
self.model = p.makemodel.split(',')[0]
1787
self.dq.update({'cups-printer' : ','.join(self.cups_printers)})
1790
self.first_cups_printer = self.cups_printers[0]
1792
self.first_cups_printer = ''
1780
self.updateCUPSPrinters()
1795
1783
# Make sure there is some valid agent data for this r_value
2108
2096
def readSoapFax(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=True):
2109
2097
return self.__readChannel(self.openSoapFax, bytes_to_read, stream, timeout, allow_short_read)
2099
def readWifiConfig(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=True):
2100
return self.__readChannel(self.openWifiConfig, bytes_to_read, stream, timeout, allow_short_read)
2111
2102
def __readChannel(self, opener, bytes_to_read, stream=None,
2112
2103
timeout=prop.read_timeout, allow_short_read=False):
2113
# print "__readChannel()"
2114
# raise Error(ERROR_DEVICE_IO_ERROR)
2117
2105
channel_id = opener()
2119
log.debug("Reading channel %d..." % channel_id)
2107
log.debug("Reading channel %d (device-id=%d, bytes_to_read=%d, allow_short=%s, timeout=%d)..." %
2108
(channel_id, self.device_id, bytes_to_read, allow_short_read, timeout))
2127
2116
result_code, data = \
2128
2117
hpmudext.read_channel(self.device_id, channel_id, bytes_to_read, timeout)
2119
log.debug("Result code=%d" % result_code)
2132
2123
if result_code == hpmudext.HPMUD_R_IO_TIMEOUT:
2185
2176
def writeSoapFax(self, data):
2186
2177
return self.__writeChannel(self.openSoapFax, data)
2179
def writeWifiConfig(self, data):
2180
return self.__writeChannel(self.openWifiConfig, data)
2189
2182
def __writeChannel(self, opener, data):
2190
# print "__writeChannel()"
2191
# raise Error(ERROR_DEVICE_IO_ERROR)
2194
2183
channel_id = opener()
2196
2184
buffer, bytes_out, total_bytes_to_write = data, 0, len(data)
2197
log.debug("Writing %d bytes to channel %d..." % (total_bytes_to_write,channel_id))
2186
log.debug("Writing %d bytes to channel %d (device-id=%d)..." % (total_bytes_to_write, channel_id, self.device_id))
2199
2188
while len(buffer) > 0:
2200
2189
result_code, bytes_written = \
2201
2190
hpmudext.write_channel(self.device_id, channel_id,
2202
2191
buffer[:prop.max_message_len])
2193
log.debug("Result code=%d" % result_code)
2204
2195
if result_code != hpmudext.HPMUD_R_OK:
2205
2196
log.error("Channel write error")
2206
2197
raise Error(ERROR_DEVICE_IO_ERROR)
2287
2278
is_gzip = os.path.splitext(file_name)[-1].lower() == '.gz'
2289
2280
if printer_name is None:
2291
printer_name = self.cups_printers[0]
2281
printer_name = self.first_cups_printer
2283
if not printer_name:
2293
2284
raise Error(ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE)
2295
2286
log.debug("Printing file '%s' to queue '%s' (gzip=%s, direct=%s, raw=%s, remove=%s)" %
2403
2394
url2 = "http://%s%s" % (self.host, url)
2396
status, ip = hpmudext.get_zc_ip_address(self.zc)
2397
if status == hpmudext.HPMUD_R_OK:
2398
url2 = "http://%s%s" % (ip, url)
2406
2401
log.debug("Opening: %s" % url2)