1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
#!/usr/bin/env python
## Copyright (C) 2008, 2009, 2010 Red Hat, Inc.
## Authors:
## Tim Waugh <twaugh@redhat.com>
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
from gettext import gettext as _
import cupshelpers
import urllib
import ppdippstr
class PhysicalDevice:
def __init__(self, device):
self.devices = None
self._network_host = None
self.add_device (device)
self._user_data = {}
self._ppdippstr = ppdippstr.backends
def _canonical_id (self, device):
mfg = device.id_dict.get ('MFG', '')
mdl = device.id_dict.get ('MDL', '')
if mfg == '' or mdl.lower ().startswith (mfg.lower ()):
make_and_model = mdl
else:
make_and_model = "%s %s" % (mfg, mdl)
return cupshelpers.ppds.ppdMakeModelSplit (make_and_model)
def _get_host_from_uri (self, uri):
(scheme, rest) = urllib.splittype (uri)
if scheme == 'hp' or scheme == 'hpfax':
if rest.startswith ("/net/"):
(rest, ipparam) = urllib.splitquery (rest[5:])
if ipparam != None and ipparam.startswith("ip="):
hostport = ipparam[3:]
else:
return None
else:
return None
else:
(hostport, rest) = urllib.splithost (rest)
if hostport == None:
return None
(host, port) = urllib.splitport (hostport)
return host
def add_device (self, device):
if self._network_host:
if hasattr (device, 'address'):
host = device.address
else:
host = self._get_host_from_uri (device.uri)
if host != self._network_host:
raise ValueError
else:
(mfg, mdl) = self._canonical_id (device)
if self.devices == None:
self.mfg = mfg
self.mdl = mdl
self.mfg_lower = mfg.lower ()
self.mdl_lower = mdl.lower ()
self.sn = device.id_dict.get ('SN', '')
self.devices = []
else:
def nicest (a, b):
def count_lower (s):
l = s.lower ()
n = 0
for i in xrange (len (s)):
if l[i] != s[i]:
n += 1
return n
if count_lower (b) < count_lower (a):
return b
return a
self.mfg = nicest (self.mfg, mfg)
self.mdl = nicest (self.mdl, mdl)
sn = device.id_dict.get ('SN', '')
if sn != '' and self.sn != '' and sn != self.sn:
raise ValueError
for d in self.devices:
if d.uri == device.uri:
return
self.devices.append (device)
self.devices.sort ()
if not self._network_host and device.device_class == "network":
# We just added a network device.
self._network_host = self._get_host_from_uri (device.uri)
def get_devices (self):
return self.devices
def get_info (self):
# If the manufacturer/model is not known, or useless (in the
# case of the hpfax backend), show the device-info field
# instead.
if self.mfg == '' or (self.mfg == "HP" and self.mdl == "Fax"):
return self._ppdippstr.get (self.devices[0].info)
info = "%s %s" % (self.mfg, self.mdl)
if len (self.sn) > 0:
info += " (%s)" % self.sn
return info
# User data
def set_data (self, key, value):
self._user_data[key] = value
def get_data (self, key):
return self._user_data.get (key)
def __str__ (self):
return "(description: %s)" % self.__repr__ ()
def __repr__ (self):
return "<PhysicalDevice.PhysicalDevice (%s,%s,%s)>" % (self.mfg,
self.mdl,
self.sn)
def __cmp__(self, other):
if other == None or type (other) != type (self):
return 1
if (self._network_host != None or
other._network_host != None):
return cmp (self._network_host, other._network_host)
if (other.mfg == '' and other.mdl == '') or \
(self.mfg == '' and self.mdl == ''):
# One or other is just a backend, not a real physical device.
if other.mfg == '' and other.mdl == '' and \
self.mfg == '' and self.mdl == '':
return cmp (self.devices[0], other.devices[0])
if other.mfg == '' and other.mdl == '':
return -1
return 1
if self.mfg == '' or self.mdl.lower ().startswith (self.mfg.lower ()):
our_make_and_model = self.mdl
else:
our_make_and_model = "%s %s" % (self.mfg, self.mdl)
(our_mfg, our_mdl) = \
cupshelpers.ppds.ppdMakeModelSplit (our_make_and_model)
if other.mfg == '' or \
other.mdl.lower ().startswith (other.mfg.lower ()):
other_make_and_model = other.mdl
else:
other_make_and_model = "%s %s" % (other.mfg, other.mdl)
(other_mfg, other_mdl) = \
cupshelpers.ppds.ppdMakeModelSplit (other_make_and_model)
mfgcmp = cmp (our_mfg.lower (), other_mfg.lower ())
if mfgcmp != 0:
return mfgcmp
mdlcmp = cmp (our_mdl.lower (), other_mdl.lower ())
if mdlcmp != 0:
return mdlcmp
if self.sn == '' or other.sn == '':
return 0
return cmp (self.sn, other.sn)
if __name__ == '__main__':
import authconn
c = authconn.Connection ()
devices = cupshelpers.getDevices (c)
physicaldevices = []
for device in devices.values ():
physicaldevice = PhysicalDevice (device)
try:
i = physicaldevices.index (physicaldevice)
physicaldevices[i].add_device (device)
except ValueError:
physicaldevices.append (physicaldevice)
physicaldevices.sort ()
for physicaldevice in physicaldevices:
print physicaldevice.get_info ()
devices = physicaldevice.get_devices ()
for device in devices:
print " ", device
|