diff -Nru system-config-printer-1.5.9+20170526/aclocal.m4 system-config-printer-1.5.9+20170619/aclocal.m4 --- system-config-printer-1.5.9+20170526/aclocal.m4 2017-05-26 13:04:09.000000000 +0000 +++ system-config-printer-1.5.9+20170619/aclocal.m4 2017-06-19 19:48:02.000000000 +0000 @@ -3764,7 +3764,7 @@ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], -[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl +[python python2 python3 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 dnl python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) diff -Nru system-config-printer-1.5.9+20170526/configure system-config-printer-1.5.9+20170619/configure --- system-config-printer-1.5.9+20170526/configure 2017-05-26 13:04:10.000000000 +0000 +++ system-config-printer-1.5.9+20170619/configure 2017-06-19 19:48:03.000000000 +0000 @@ -6782,7 +6782,7 @@ $as_echo_n "(cached) " >&6 else - for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + for am_cv_pathless_PYTHON in python python2 python3 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros diff -Nru system-config-printer-1.5.9+20170526/cupshelpers/cupshelpers.py system-config-printer-1.5.9+20170619/cupshelpers/cupshelpers.py --- system-config-printer-1.5.9+20170526/cupshelpers/cupshelpers.py 2017-05-26 12:58:08.000000000 +0000 +++ system-config-printer-1.5.9+20170619/cupshelpers/cupshelpers.py 2017-06-19 19:47:00.000000000 +0000 @@ -562,6 +562,9 @@ 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 @@ 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 @@ 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 -Nru system-config-printer-1.5.9+20170526/debian/changelog system-config-printer-1.5.9+20170619/debian/changelog --- system-config-printer-1.5.9+20170526/debian/changelog 2017-06-14 01:15:26.000000000 +0000 +++ system-config-printer-1.5.9+20170619/debian/changelog 2017-06-19 19:48:59.000000000 +0000 @@ -1,3 +1,18 @@ +system-config-printer (1.5.9+20170619-0ubuntu1) artful; urgency=medium + + * New upstream release + - GIT snapshot from June 19, 2017, after 1.5.9 release + - Determine IP addresses of discovered network printers to find out + whether discovered entries come from the same physical device + - Let USB entries from the printing and from the fax part of the + same multi-function printer appear together. + - Debug output for assignments of discovered entries to physical + devices. + - Consider the CUPS backends "driverless" and "bjnp" as network + printer backends. + + -- Till Kamppeter Mon, 19 Jun 2017 16:48:59 -0300 + system-config-printer (1.5.9+20170526-0ubuntu2) artful; urgency=medium * Fix path for the installation of debug.py and smburi.py. diff -Nru system-config-printer-1.5.9+20170526/newprinter.py system-config-printer-1.5.9+20170619/newprinter.py --- system-config-printer-1.5.9+20170526/newprinter.py 2017-05-26 12:58:08.000000000 +0000 +++ system-config-printer-1.5.9+20170619/newprinter.py 2017-06-19 19:47:00.000000000 +0000 @@ -1986,7 +1986,7 @@ # 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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": diff -Nru system-config-printer-1.5.9+20170526/PhysicalDevice.py system-config-printer-1.5.9+20170619/PhysicalDevice.py --- system-config-printer-1.5.9+20170526/PhysicalDevice.py 2017-05-26 12:58:08.000000000 +0000 +++ system-config-printer-1.5.9+20170619/PhysicalDevice.py 2017-06-19 19:47:00.000000000 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ (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 @@ 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 @@ 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 @@ 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)