diff --git a/PhysicalDevice.py b/PhysicalDevice.py index 5393b55ab..00043222e 100644 --- a/PhysicalDevice.py +++ b/PhysicalDevice.py @@ -23,8 +23,9 @@ gettext.install(domain=config.PACKAGE, localedir=config.localedir) import cupshelpers import urllib.parse - import ppdippstr +import socket +from debug import * class PhysicalDevice: def __init__(self, device): @@ -32,6 +33,7 @@ def __init__(self, device): self._network_host = None self.dnssd_hostname = None self._cupsserver = False + self.firsturi = None self.add_device (device) self._user_data = {} self._ppdippstr = ppdippstr.backends @@ -59,6 +61,18 @@ def _add_dot_local_if_needed(self, hostname): else: return hostname + def _get_address (self, hostname): + try: + address = socket.getaddrinfo(hostname, 0, + family=socket.AF_INET)[0][4][0] + except: + try: + address = socket.getaddrinfo(hostname, 0, + family=socket.AF_INET6)[0][4][0] + except: + address = None + return address + def _get_host_from_uri (self, uri): hostport = None host = None @@ -92,6 +106,20 @@ def _get_host_from_uri (self, uri): if hostport: (host, port) = urllib.parse.splitport (hostport) + if (host): + ip = None + try: + ip = self._get_address(host) + if ip: + host = ip + except: + pass + elif (dnssdhost): + try: + host = self._get_address(dnssdhost) + except: + host = None + return self._add_dot_local_if_needed(host), \ self._add_dot_local_if_needed(dnssdhost) @@ -160,6 +188,11 @@ def count_lower (s): if d.uri == device.uri: return + # Use the URI of the very first device added as a kind of identifier + # for this physical device record, to make debugging easier + if not self.firsturi: + self.firsturi = device.uri; + self.devices.append (device) self.devices.sort () @@ -175,11 +208,21 @@ def count_lower (s): address = device.address if address: self._network_host = self._add_dot_local_if_needed(address) + if (hasattr (device, 'hostname') and self.dnssd_hostname is None): hostname = device.hostname if hostname: self.dnssd_hostname = self._add_dot_local_if_needed(hostname) + if (self.dnssd_hostname and self._network_host is None): + try: + self._network_host = self._get_address(hostname); + except: + self._network_host = None + + debugprint("Device %s added to physical device: %s" % + (device.uri, repr(self))) + def get_devices (self): return self.devices @@ -236,9 +279,9 @@ def __str__ (self): return "(description: %s)" % self.__repr__ () def __repr__ (self): - return "" % (self.mfg, - self.mdl, - self.sn) + return ("" % + (self.mfg, self.mdl, self.sn, self._network_host, + self.dnssd_hostname, self.firsturi)) def __eq__(self, other): if type (other) != type (self): @@ -292,7 +335,13 @@ def split_make_and_model (dev): (our_mfg, our_mdl) = split_make_and_model (self) (other_mfg, other_mdl) = split_make_and_model (other) - if our_mfg != other_mfg or our_mdl != other_mdl: + if our_mfg != other_mfg: + return False + + if our_mfg == "hp" and self.sn != '' and self.sn == other.sn: + return True + + if our_mdl != other_mdl: return False if self.sn == '' or other.sn == '': @@ -304,6 +353,9 @@ def __lt__(self, other): if type (other) != type (self): return False + if self == other: + return False; + if self._network_host != other._network_host: if self._network_host is None: return True @@ -313,6 +365,15 @@ def __lt__(self, other): return self._network_host < other._network_host + if self.dnssd_hostname != other.dnssd_hostname: + if self.dnssd_hostname is None: + return True + + if other.dnssd_hostname is None: + return False + + return self.dnssd_hostname < other.dnssd_hostname + devs = other.get_devices() if devs: uris = [x.uri for x in self.devices] @@ -335,7 +396,9 @@ def split_make_and_model (dev): make_and_model = dev.mdl else: make_and_model = "%s %s" % (dev.mfg, dev.mdl) - return cupshelpers.ppds.ppdMakeModelSplit (make_and_model) + (mfg, mdl) = cupshelpers.ppds.ppdMakeModelSplit (make_and_model) + return (cupshelpers.ppds.normalize (mfg), + cupshelpers.ppds.normalize (mdl)) (our_mfg, our_mdl) = split_make_and_model (self) (other_mfg, other_mdl) = split_make_and_model (other) diff --git a/cupshelpers/cupshelpers.py b/cupshelpers/cupshelpers.py index 76ae9df38..978ab8019 100755 --- a/cupshelpers/cupshelpers.py +++ b/cupshelpers/cupshelpers.py @@ -562,6 +562,9 @@ def __lt__(self, other): stype = "dnssds" elif self.uri.find("._printer") != -1: stype = "dnssdl" + if stype == "usb": + if self.uri.lower().find("fax") != -1: + stype = "usbfax" otype = other.type if otype == "dnssd": if other.uri.find("._ipp") != -1: @@ -570,6 +573,9 @@ def __lt__(self, other): otype = "dnssds" elif other.uri.find("._printer") != -1: otype = "dnssdl" + if otype == "usb": + if other.uri.lower().find("fax") != -1: + otype = "usbfax" if not self.is_class and (stype != otype): # "hp"/"hpfax" before "usb" before * before "parallel" before @@ -622,6 +628,10 @@ def __lt__(self, other): return False if stype == "usb": return True + if otype == "usbfax": + return False + if stype == "usbfax": + return True result = bool(self.id) < bool(other.id) if not result: result = self.info < other.info diff --git a/newprinter.py b/newprinter.py index c8d973a10..d0d4491b0 100644 --- a/newprinter.py +++ b/newprinter.py @@ -1986,7 +1986,7 @@ def fetchDevices(self, network=False, current_uri=None): # Search for Bluetooth printers together with the network printers # as the Bluetooth search takes rather long time - network_schemes = ["dnssd", "snmp", "bluetooth"] + network_schemes = ["dnssd", "snmp", "driverless", "bjnp", "bluetooth"] error_handler = self.error_getting_devices if network == False: reply_handler = (lambda x, y: @@ -2369,17 +2369,28 @@ def replace_generic (device): device2.uri = "delete" devices = [x for x in devices if x.uri not in ("hp", "hpfax", "hal", "beh", "smb", - "scsi", "http", + "scsi", "http", "bjnp", "delete")] newdevices = [] for device in devices: + debugprint("Adding device with URI %s" % device.uri) + if (hasattr (device, 'address')): + debugprint(" Device address %s" % device.address) + if (hasattr (device, 'hostname')): + debugprint(" Device host name %s" % device.hostname) physicaldevice = PhysicalDevice (device) + debugprint (" Created physical device %s" % repr(physicaldevice)) try: i = self.devices.index (physicaldevice) + debugprint (" Physical device %d is the same printer" % i) self.devices[i].add_device (device) + debugprint (" New physical device %s is same as physical device %d: %s" % + (repr(physicaldevice), i, repr(self.devices[i]))) + debugprint (" Joining devices") except ValueError: self.devices.append (physicaldevice) newdevices.append (physicaldevice) + debugprint (" Physical device %s is a completely new device" % repr(physicaldevice)) self.devices.sort() if current_uri: @@ -2398,7 +2409,15 @@ def replace_generic (device): network_iter = self.devices_network_iter find_nw_iter = self.devices_find_nw_iter - for device in newdevices: + for newdevice in newdevices: + device = None + try: + i = self.devices.index (newdevice) + device = self.devices[i] + except ValueError: + debugprint("ERROR: Cannot identify new physical device with its entry in the device list (%s)" % + repr(newdevice)) + continue devs = device.get_devices () network = devs[0].device_class == 'network' info = device.get_info () @@ -3018,7 +3037,11 @@ def on_tvNPDevices_cursor_changed(self, widget): elif device.type == "serial": device.menuentry = _("Serial Port") elif device.type == "usb": - device.menuentry = _("USB") + if (hasattr(device, "uri") and + device.uri.lower().find("fax") > -1): + device.menuentry = _("Fax") + " - " + _("USB") + else: + device.menuentry = _("USB") elif device.type == "bluetooth": device.menuentry = _("Bluetooth") elif device.type == "hp": @@ -3206,6 +3229,7 @@ def on_tvNPDeviceURIs_cursor_changed(self, widget): page = self.new_printer_device_tabs.get (device.type, self.PAGE_SELECT_DEVICE) self.ntbkNPType.set_current_page(page) + debugprint("Selected connection type. URI: %s" % device.uri) location = '' type = device.type url = device.uri.split(":", 1)[-1] @@ -3215,7 +3239,14 @@ def on_tvNPDeviceURIs_cursor_changed(self, widget): if device.type == "parallel": text = _("A printer connected to the parallel port.") elif device.type == "usb": - text = _("A printer connected to a USB port.") + if (hasattr(device, "uri") and + device.uri.lower().find("fax") > -1): + device.menuentry = _("Fax") + " - " + _("USB") + text = _("A fax machine or the fax function " + "of a multi-function device connected " + "to a USB port.") + else: + text = _("A printer connected to a USB port.") elif device.type == "bluetooth": text = _("A printer connected via Bluetooth.") elif device.type == "hp":