home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / system-config-printer / check-device-ids.py < prev    next >
Encoding:
Python Source  |  2010-09-28  |  8.7 KB  |  275 lines

  1. #!/usr/bin/env python
  2.  
  3. ## check-device-ids
  4.  
  5. ## Copyright (C) 2010 Red Hat, Inc.
  6. ## Authors:
  7. ##  Tim Waugh <twaugh@redhat.com>
  8.  
  9. ## This program is free software; you can redistribute it and/or modify
  10. ## it under the terms of the GNU General Public License as published by
  11. ## the Free Software Foundation; either version 2 of the License, or
  12. ## (at your option) any later version.
  13.  
  14. ## This program is distributed in the hope that it will be useful,
  15. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ## GNU General Public License for more details.
  18.  
  19. ## You should have received a copy of the GNU General Public License
  20. ## along with this program; if not, write to the Free Software
  21. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  
  23. import dbus
  24. import cups
  25. import cupshelpers
  26. from cupshelpers.ppds import PPDs, ppdMakeModelSplit
  27. import sys
  28.  
  29. cups.setUser ('root')
  30. c = cups.Connection ()
  31.  
  32. devices = None
  33. if len (sys.argv) > 1 and sys.argv[1] == '--help':
  34.     print "Syntax: check-device-ids <device-make-and-model> <device-id>"
  35.     sys.exit (1)
  36.  
  37. if len (sys.argv) == 3:
  38.     id_dict = cupshelpers.parseDeviceID (sys.argv[2])
  39.     if id_dict.has_key ("MFG") and id_dict.has_key ("MDL"):
  40.         devices = { 'user-specified:':
  41.                         { 'device-make-and-model': sys.argv[1],
  42.                           'device-id': sys.argv[2] }
  43.                     }
  44. else:
  45.     print ("\nIf you have not already done so, you may get more results\n"
  46.            "by temporarily disabling your firewall (or by allowing\n"
  47.            "incoming UDP packets on port 161).\n")
  48.  
  49. if devices == None:
  50.     print "Examining connected devices"
  51.     try:
  52.         devices = c.getDevices (exclude_schemes=["dnssd", "hal", "hpfax"])
  53.     except cups.IPPError, (e, m):
  54.         if e == cups.IPP_FORBIDDEN:
  55.             print "Run this as root to examine IDs from attached devices."
  56.             sys.exit (1)
  57.  
  58.         if e == cups.IPP_NOT_AUTHORIZED:
  59.             print "Not authorized."
  60.             sys.exit (1)
  61.  
  62. if len (devices) == 0:
  63.     print "No attached devices."
  64.     sys.exit (0)
  65.  
  66. n = 0
  67. device_ids = []
  68. for device, attrs in devices.iteritems ():
  69.     if device.find (":") == -1:
  70.         continue
  71.  
  72.     make_and_model = attrs.get ('device-make-and-model')
  73.     device_id = attrs.get ('device-id')
  74.     if make_and_model and not device_id:
  75.         try:
  76.             hostname = None
  77.             if (device.startswith ("socket://") or
  78.                 device.startswith ("lpd://")):
  79.                 hostname = device[9:]
  80.                 colon = hostname.find (":")
  81.                 if colon != -1:
  82.                     hostname = hostname[:colon]
  83.  
  84.             if hostname:
  85.                 devs = []
  86.  
  87.                 def got_device (dev):
  88.                     if dev != None:
  89.                         devs.append (dev)
  90.  
  91.                 import probe_printer
  92.                 pf = probe_printer.PrinterFinder ()
  93.                 pf.hostname = hostname
  94.                 pf.callback_fn = got_device
  95.                 pf._cached_attributes = dict()
  96.                 print "Sending SNMP request to %s for device-id" % hostname
  97.                 pf._probe_snmp ()
  98.  
  99.                 for dev in devs:
  100.                     if dev.id:
  101.                         device_id = dev.id
  102.                         attrs.update ({'device-id': dev.id})
  103.                         break
  104.  
  105.         except Exception, e:
  106.             print "Exception: %s" % repr (e)
  107.  
  108.     if not (make_and_model and device_id):
  109.         print "Skipping %s, insufficient data" % device
  110.         continue
  111.  
  112.     id_fields = cupshelpers.parseDeviceID (device_id)
  113.     this_id = "MFG:%s;MDL:%s;" % (id_fields['MFG'], id_fields['MDL'])
  114.     device_ids.append (this_id)
  115.     n += 1
  116.  
  117. if not device_ids:
  118.     print "No Device IDs available."
  119.     sys.exit (0)
  120.  
  121. try:
  122.     bus = dbus.SessionBus ()
  123.  
  124.     print "Installing relevant drivers using session service"
  125.     try:
  126.         obj = bus.get_object ("org.freedesktop.PackageKit",
  127.                               "/org/freedesktop/PackageKit")
  128.         proxy = dbus.Interface (obj, "org.freedesktop.PackageKit.Modify")
  129.         proxy.InstallPrinterDrivers (0, device_ids,
  130.                                      "hide-finished", timeout=3600)
  131.     except dbus.exceptions.DBusException, e:
  132.         print "Ignoring exception: %s" % e
  133. except dbus.exceptions.DBusException:
  134.     try:
  135.         bus = dbus.SystemBus ()
  136.  
  137.         print "Installing relevant drivers using system service"
  138.         try:
  139.             obj = bus.get_object ("com.redhat.PrinterDriversInstaller",
  140.                                   "/com/redhat/PrinterDriversInstaller")
  141.             proxy = dbus.Interface (obj,
  142.                                     "com.redhat.PrinterDriversInstaller")
  143.             for device_id in device_ids:
  144.                 id_dict = cupshelpers.parseDeviceID (device_id)
  145.                 proxy.InstallDrivers (id_dict['MFG'], id_dict['MDL'], '',
  146.                                       timeout=3600)
  147.         except dbus.exceptions.DBusException, e:
  148.             print "Ignoring exception: %s" % e
  149.     except dbus.exceptions.DBusException:
  150.         print "D-Bus not available so skipping package installation"
  151.  
  152.  
  153. print "Fetching driver list"
  154. ppds = PPDs (c.getPPDs ())
  155. ppds._init_ids ()
  156. makes = ppds.getMakes ()
  157.  
  158. def driver_uri_to_filename (uri):
  159.     schemeparts = uri.split (':', 2)
  160.     if len (schemeparts) < 2:
  161.         if uri.startswith ("lsb/usr/"):
  162.             return "/usr/share/ppd/" + uri[8:]
  163.         elif uri.startswith ("lsb/opt/"):
  164.             return "/opt/share/ppd/" + uri[8:]
  165.         elif uri.startswith ("lsb/local/"):
  166.             return "/usr/local/share/ppd/" + uri[10:]
  167.  
  168.         return "/usr/share/cups/model/" + uri
  169.  
  170.     scheme = schemeparts[0]
  171.     if scheme != "drv":
  172.         return "/usr/lib/cups/driver/" + scheme
  173.  
  174.     rest = schemeparts[1]
  175.     rest = rest.lstrip ('/')
  176.     parts = rest.split ('/')
  177.     if len (parts) > 1:
  178.         parts = parts[:len (parts) - 1]
  179.  
  180.     return "/usr/share/cups/drv/" + reduce (lambda x, y: x + "/" + y, parts)
  181.  
  182. def driver_uri_to_pkg (uri):
  183.     filename = driver_uri_to_filename (uri)
  184.  
  185.     try:
  186.         import packagekit.client, packagekit.enums
  187.         client = packagekit.client.PackageKitClient ()
  188.         packages = client.search_file ([filename],
  189.                                        packagekit.enums.FILTER_INSTALLED)
  190.         return packages[0].name
  191.     except:
  192.         return filename
  193.  
  194. i = 1
  195. if sys.stdout.encoding == 'UTF-8':
  196.     item = unichr (0x251c) + unichr (0x2500) + unichr (0x2500)
  197.     last = unichr (0x2514) + unichr (0x2500) + unichr (0x2500)
  198. else:
  199.     item = "|--"
  200.     last = "`--"
  201.  
  202. for device, attrs in devices.iteritems ():
  203.     make_and_model = attrs.get ('device-make-and-model')
  204.     device_id = attrs.get ('device-id')
  205.     if device.find (":") == -1:
  206.         continue
  207.  
  208.     if not (make_and_model and device_id):
  209.         continue
  210.  
  211.     id_fields = cupshelpers.parseDeviceID (device_id)
  212.     if i < n:
  213.         line = item
  214.     else:
  215.         line = last
  216.  
  217.     cmd = id_fields['CMD']
  218.     if cmd:
  219.         cmd = "CMD:%s;" % reduce (lambda x, y: x + ',' + y, cmd)
  220.     else:
  221.         cmd = ""
  222.  
  223.     scheme = device.split (":", 1)[0]
  224.     print "%s %s (%s): MFG:%s;MDL:%s;%s" % (line, make_and_model,
  225.                                             scheme,
  226.                                             id_fields['MFG'],
  227.                                             id_fields['MDL'],
  228.                                             cmd)
  229.     
  230.     try:
  231.         drivers = ppds.ids[id_fields['MFG'].lower ()][id_fields['MDL'].lower ()]
  232.     except KeyError:
  233.         drivers = []
  234.  
  235.     if i < n:
  236.         more = unichr (0x2502)
  237.     else:
  238.         more = " "
  239.  
  240.     if drivers:
  241.         drivers = ppds.orderPPDNamesByPreference (drivers)
  242.         n_drivers = len (drivers)
  243.         j = 1
  244.         for driver in drivers:
  245.             if j < n_drivers:
  246.                 print "%s   %s %s [%s]" % (more, item, driver,
  247.                                            driver_uri_to_pkg (driver))
  248.             else:
  249.                 print "%s   %s %s [%s]" % (more, last, driver,
  250.                                            driver_uri_to_pkg (driver))
  251.  
  252.             j += 1
  253.     else:
  254.         print "%s   (No drivers)" % more
  255.  
  256.     (mfr, mdl) = ppdMakeModelSplit (make_and_model)
  257.     matches = set (ppds.getInfoFromModel (mfr, mdl))
  258.     mfrl = mfr.lower ()
  259.     mdls = None
  260.     for make in makes:
  261.         if make.lower () == mfrl:
  262.             mdls = ppds.makes[make]
  263.             break
  264.     if mdls:
  265.         (s, bestmatches) = ppds._findBestMatchPPDs (mdls, mdl)
  266.         if s == ppds.STATUS_SUCCESS:
  267.             matches = matches.union (set (bestmatches))
  268.  
  269.     missing = set (matches) - set (drivers)
  270.     for each in missing:
  271.         print "%s       MISSING  %s [%s]" % (more, each,
  272.                                              driver_uri_to_pkg (each))
  273.  
  274.     i += 1
  275.