We have a corporate printer database, and a simple script which will query it and "discover" the printers in the office where the user is based. To generate the CUPS uri, we can use 'hp-makeuri -c'. This queries the printer by SNMP to obtain the IEEE1284 ident string, and creates a URI appropriately. We then *want* the IEEE1284 ident string, since that needs to be in the output that CUPS sees too (and GNOME control-center fails if it isn't). So we would need to fetch it from each printer for a *second* time, since the information isn't available from hp-makeuri (or the backend python libraries that it calls). This doubles the time it takes to query each printer. And time is a problem, since there is a timeout on discovery (cf. bug 996664). It would be useful if hp-makeuri would give me the information I need in a single invocation. As it is, I've ditched hp-makeuri completely and I'm doing it myself. But this is horrid. Don't make me do this :) (And yes, it sucks that I have to give a dotted-quad IP address instead of the hostname, and I have no idea how it works with IPv6). printers = db.printer_query(location) for p in printers: try: ip = socket.gethostbyname(p['hostname']) # The hp-makeuri tool will query the IEEE1284 ident string to # generate the URI, but there's no way to get it to *tell* us # what the ident string was, and we need it too. So rather than # doubling the latency by fetching it again for ourselves, we # just do it once and generate the URI for ourselves. It isn't # particularly complex. var = netsnmp.Varbind('.1.3.6.1.4.1.11.2.3.9.1.1.7.0') devid = netsnmp.snmpget(var, DestHost=ip, Version=1)[0] idmodel = None iddesc = None for idpart in devid.split(';'): if idpart.startswith('MDL:'): idmodel = idpart[4:] elif idpart.startswith('MODEL:'): idmodel = idpart[6:] elif idpart.startswith('DES:'): iddesc = idpart[4:] elif idpart.startswith('DESCRIPTION:'): iddesc = idpart[12:] if idmodel is None: continue # This check is never going to fail, since the SNMP query is HP-specific # in the first place. But just in case we fix that... if idmodel.startswith("HP") or idmodel.startswith("hp"): # This matches generalize_model() in hpmud.c backend='hp' uri='hp:/net/' + re.sub('_+$', '', re.sub('[/ ]+', '_', idmodel))+ '?ip=' + ip else: backend='socket' uri='socket://%s:9100' % p['hostname'] if iddesc is None: iddesc = idmodel location = "%s %s-%s" % ( p['sitecity'], p['building'], p['floor'] ) if p['pole'] != "n/a": location = location + " (" + p['pole'] + ")" devinfo = iddesc + " (" + location + ")" # device-class device-uri "device-make-and-model" "device-info" "device-id" "device-location" print "%s %s \"%s\" \"%s\" \"%s\" \"%s\"" % ( backend, uri, iddesc, devinfo, devid, location ) sys.stdout.flush() except Exception, e: print str(e)
Reported upstream.