Merge ~kissiel/checkbox-support:fix-bad-landing into checkbox-support:master
- Git
- lp:~kissiel/checkbox-support
- fix-bad-landing
- Merge into master
Proposed by
Maciej Kisielewski
Status: | Merged |
---|---|
Approved by: | Maciej Kisielewski |
Approved revision: | 98204f4fcc6410220bfef3551b1667e7282233e6 |
Merged at revision: | 42df1c3010d1719130e296c91f441a5477136927 |
Proposed branch: | ~kissiel/checkbox-support:fix-bad-landing |
Merge into: | checkbox-support:master |
Diff against target: |
681 lines (+36/-591) 4 files modified
checkbox_support/parsers/sysfs_usb.py (+0/-6) checkbox_support/scripts/lsusb.py (+36/-540) dev/null (+0/-43) setup.py (+0/-2) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sylvain Pineau (community) | Approve | ||
Review via email: mp+392209@code.launchpad.net |
Commit message
Description of the change
Yesterday I landed the lsusb branch w/o the squashed commits (and review markers) being on it. This MR fixes it.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/checkbox_support/parsers/sysfs_usb.py b/checkbox_support/parsers/sysfs_usb.py | |||
2 | index 56fbacd..148ea86 100644 | |||
3 | --- a/checkbox_support/parsers/sysfs_usb.py | |||
4 | +++ b/checkbox_support/parsers/sysfs_usb.py | |||
5 | @@ -153,8 +153,6 @@ def read_entry(sysfs_path, field): | |||
6 | 153 | return fentry.readline().strip('\n') | 153 | return fentry.readline().strip('\n') |
7 | 154 | 154 | ||
8 | 155 | 155 | ||
9 | 156 | # REVIEW : the next two classes share a lot of functionality, I kept them | ||
10 | 157 | # separate as there are just two and it helps with readibility | ||
11 | 158 | class UsbInterface(dict): | 156 | class UsbInterface(dict): |
12 | 159 | """ | 157 | """ |
13 | 160 | A proxy to sysfs entry for a USB Interface. | 158 | A proxy to sysfs entry for a USB Interface. |
14 | @@ -167,8 +165,6 @@ class UsbInterface(dict): | |||
15 | 167 | while parent: | 165 | while parent: |
16 | 168 | self._level += 1 | 166 | self._level += 1 |
17 | 169 | parent = parent.parent | 167 | parent = parent.parent |
18 | 170 | # REVIEW : If this is too 'hucky' then I could just go with explicit | ||
19 | 171 | # assigment of the fields. May be more readible that way. | ||
20 | 172 | hex_int_fields = [ | 168 | hex_int_fields = [ |
21 | 173 | 'bInterfaceClass', 'bInterfaceSubClass', 'bInterfaceProtocol'] | 169 | 'bInterfaceClass', 'bInterfaceSubClass', 'bInterfaceProtocol'] |
22 | 174 | for field in hex_int_fields: | 170 | for field in hex_int_fields: |
23 | @@ -183,8 +179,6 @@ class UsbInterface(dict): | |||
24 | 183 | self['bInterfaceClass'], self['bInterfaceSubClass'], | 179 | self['bInterfaceClass'], self['bInterfaceSubClass'], |
25 | 184 | self['bInterfaceProtocol']) | 180 | self['bInterfaceProtocol']) |
26 | 185 | 181 | ||
27 | 186 | # REVIEW: I was tempted to overload __str__, but I went with an explicit | ||
28 | 187 | # function. | ||
29 | 188 | def to_str(self): | 182 | def to_str(self): |
30 | 189 | """Generate a string representation of this Interface.""" | 183 | """Generate a string representation of this Interface.""" |
31 | 190 | template = ( | 184 | template = ( |
32 | diff --git a/checkbox_support/scripts/lsusb.py b/checkbox_support/scripts/lsusb.py | |||
33 | index c243835..a2d4677 100755 | |||
34 | --- a/checkbox_support/scripts/lsusb.py | |||
35 | +++ b/checkbox_support/scripts/lsusb.py | |||
36 | @@ -1,547 +1,43 @@ | |||
41 | 1 | #!/usr/bin/env python3 | 1 | # This file is part of Checkbox. |
38 | 2 | # lsusb.py | ||
39 | 3 | # Displays your USB devices in reasonable form. | ||
40 | 4 | # (c) Kurt Garloff <garloff@suse.de>, 2/2009, GPL v2 or v3. | ||
42 | 5 | # | 2 | # |
45 | 6 | # Copyright 2016 Canonical Ltd. | 3 | # Copyright 2020 Canonical Ltd. |
46 | 7 | # Sylvain Pineau <sylvain.pineau@canonical.com> | 4 | # Written by: |
47 | 5 | # Maciej Kisielewski <maciej.kisielewski@canonical.com> | ||
48 | 8 | # | 6 | # |
531 | 9 | # Usage: See usage() | 7 | # Checkbox is free software: you can redistribute it and/or modify |
532 | 10 | 8 | # it under the terms of the GNU General Public License version 3, | |
533 | 11 | from functools import total_ordering | 9 | # as published by the Free Software Foundation. |
534 | 12 | import getopt | 10 | # |
535 | 13 | import os | 11 | # Checkbox is distributed in the hope that it will be useful, |
536 | 14 | import re | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
537 | 15 | import sys | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
538 | 16 | 14 | # GNU General Public License for more details. | |
539 | 17 | # Global options | 15 | # |
540 | 18 | showint = False | 16 | # You should have received a copy of the GNU General Public License |
541 | 19 | showhubint = False | 17 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. |
60 | 20 | noemptyhub = False | ||
61 | 21 | nohub = False | ||
62 | 22 | warnsort = False | ||
63 | 23 | shortmode = False | ||
64 | 24 | |||
65 | 25 | prefix = "/sys/bus/usb/devices/" | ||
66 | 26 | usbids = "/usr/share/usb.ids" | ||
67 | 27 | |||
68 | 28 | esc = chr(27) | ||
69 | 29 | norm = esc + "[0;0m" | ||
70 | 30 | bold = esc + "[0;1m" | ||
71 | 31 | red = esc + "[0;31m" | ||
72 | 32 | green = esc + "[0;32m" | ||
73 | 33 | amber = esc + "[0;33m" | ||
74 | 34 | |||
75 | 35 | cols = ("", "", "", "", "") | ||
76 | 36 | |||
77 | 37 | usbvendors = [] | ||
78 | 38 | usbproducts = [] | ||
79 | 39 | usbclasses = [] | ||
80 | 40 | |||
81 | 41 | devlst = ( | ||
82 | 42 | 'host', # usb-storage | ||
83 | 43 | 'video4linux/video', # uvcvideo et al. | ||
84 | 44 | 'sound/card', # snd-usb-audio | ||
85 | 45 | 'net/', # cdc_ether, ... | ||
86 | 46 | 'input/input', # usbhid | ||
87 | 47 | 'usb:hiddev', # usb hid | ||
88 | 48 | 'bluetooth/hci', # btusb | ||
89 | 49 | 'ttyUSB', # btusb | ||
90 | 50 | 'tty/', # cdc_acm | ||
91 | 51 | 'usb:lp', # usblp | ||
92 | 52 | 'usb/', # hiddev, usblp | ||
93 | 53 | ) | ||
94 | 54 | |||
95 | 55 | |||
96 | 56 | def readattr(path, name): | ||
97 | 57 | "Read attribute from sysfs and return as string" | ||
98 | 58 | f = open(prefix + path + "/" + name) | ||
99 | 59 | return f.readline().rstrip("\n") | ||
100 | 60 | |||
101 | 61 | |||
102 | 62 | def readlink(path, name): | ||
103 | 63 | "Read symlink and return basename" | ||
104 | 64 | return os.path.basename(os.readlink(prefix + path + "/" + name)) | ||
105 | 65 | |||
106 | 66 | |||
107 | 67 | @total_ordering | ||
108 | 68 | class UsbClass: | ||
109 | 69 | "Container for USB Class/Subclass/Protocol" | ||
110 | 70 | |||
111 | 71 | def __init__(self, cl, sc, pr, str=""): | ||
112 | 72 | self.pclass = cl | ||
113 | 73 | self.subclass = sc | ||
114 | 74 | self.proto = pr | ||
115 | 75 | self.desc = str | ||
116 | 76 | |||
117 | 77 | def __repr__(self): | ||
118 | 78 | return self.desc | ||
119 | 79 | |||
120 | 80 | def __lt__(self, oth): | ||
121 | 81 | if self.pclass != oth.pclass: | ||
122 | 82 | return self.pclass - oth.pclass | ||
123 | 83 | if self.subclass != oth.subclass: | ||
124 | 84 | return self.subclass - oth.subclass | ||
125 | 85 | return self.proto - oth.proto | ||
126 | 86 | |||
127 | 87 | def __eq__(self, oth): | ||
128 | 88 | if self.pclass != oth.pclass: | ||
129 | 89 | return False | ||
130 | 90 | if self.subclass != oth.subclass: | ||
131 | 91 | return False | ||
132 | 92 | return self.proto == oth.proto | ||
133 | 93 | |||
134 | 94 | |||
135 | 95 | @total_ordering | ||
136 | 96 | class UsbVendor: | ||
137 | 97 | "Container for USB Vendors" | ||
138 | 98 | |||
139 | 99 | def __init__(self, vid, vname=""): | ||
140 | 100 | self.vid = vid | ||
141 | 101 | self.vname = vname | ||
142 | 102 | |||
143 | 103 | def __repr__(self): | ||
144 | 104 | return self.vname | ||
145 | 105 | |||
146 | 106 | def __lt__(self, oth): | ||
147 | 107 | return self.vid - oth.vid | ||
148 | 108 | |||
149 | 109 | def __eq__(self, oth): | ||
150 | 110 | return self.vid == oth.vid | ||
151 | 111 | |||
152 | 112 | |||
153 | 113 | @total_ordering | ||
154 | 114 | class UsbProduct: | ||
155 | 115 | "Container for USB VID:PID devices" | ||
156 | 116 | |||
157 | 117 | def __init__(self, vid, pid, pname=""): | ||
158 | 118 | self.vid = vid | ||
159 | 119 | self.pid = pid | ||
160 | 120 | self.pname = pname | ||
161 | 121 | |||
162 | 122 | def __repr__(self): | ||
163 | 123 | return self.pname | ||
164 | 124 | |||
165 | 125 | def __lt__(self, oth): | ||
166 | 126 | if self.vid != oth.vid: | ||
167 | 127 | return self.vid - oth.vid | ||
168 | 128 | return self.pid - oth.pid | ||
169 | 129 | |||
170 | 130 | def __eq__(self, oth): | ||
171 | 131 | if self.vid != oth.vid: | ||
172 | 132 | return False | ||
173 | 133 | return self.pid == oth.pid | ||
174 | 134 | |||
175 | 135 | |||
176 | 136 | def ishexdigit(str): | ||
177 | 137 | "return True if all digits are valid hex digits" | ||
178 | 138 | for dg in str: | ||
179 | 139 | if not dg.isdigit() and dg not in 'abcdef': | ||
180 | 140 | return False | ||
181 | 141 | return True | ||
182 | 142 | |||
183 | 143 | |||
184 | 144 | def parse_usb_ids(): | ||
185 | 145 | "Parse /usr/share/usb.ids and fill usbvendors, usbproducts, usbclasses" | ||
186 | 146 | id = 0 | ||
187 | 147 | sid = 0 | ||
188 | 148 | mode = 0 | ||
189 | 149 | strg = "" | ||
190 | 150 | cstrg = "" | ||
191 | 151 | with open(usbids, encoding="utf-8", errors='ignore') as f: | ||
192 | 152 | for ln in f: | ||
193 | 153 | if ln[0] == '#': | ||
194 | 154 | continue | ||
195 | 155 | ln = ln.rstrip('\n') | ||
196 | 156 | if len(ln) == 0: | ||
197 | 157 | continue | ||
198 | 158 | if ishexdigit(ln[0:4]): | ||
199 | 159 | mode = 0 | ||
200 | 160 | id = int(ln[:4], 16) | ||
201 | 161 | usbvendors.append(UsbVendor(id, ln[6:])) | ||
202 | 162 | continue | ||
203 | 163 | if ln[0] == '\t' and ishexdigit(ln[1:3]): | ||
204 | 164 | sid = int(ln[1:5], 16) | ||
205 | 165 | # USB devices | ||
206 | 166 | if mode == 0: | ||
207 | 167 | usbproducts.append(UsbProduct(id, sid, ln[7:])) | ||
208 | 168 | continue | ||
209 | 169 | elif mode == 1: | ||
210 | 170 | nm = ln[5:] | ||
211 | 171 | if nm != "Unused": | ||
212 | 172 | strg = cstrg + ":" + nm | ||
213 | 173 | else: | ||
214 | 174 | strg = cstrg + ":" | ||
215 | 175 | usbclasses.append(UsbClass(id, sid, -1, strg)) | ||
216 | 176 | continue | ||
217 | 177 | if ln[0] == 'C': | ||
218 | 178 | mode = 1 | ||
219 | 179 | id = int(ln[2:4], 16) | ||
220 | 180 | cstrg = ln[6:] | ||
221 | 181 | usbclasses.append(UsbClass(id, -1, -1, cstrg)) | ||
222 | 182 | continue | ||
223 | 183 | if ( | ||
224 | 184 | mode == 1 and ln[0] == '\t' and ln[1] == '\t' and | ||
225 | 185 | ishexdigit(ln[2:4]) | ||
226 | 186 | ): | ||
227 | 187 | prid = int(ln[2:4], 16) | ||
228 | 188 | usbclasses.append(UsbClass(id, sid, prid, strg + ":" + ln[6:])) | ||
229 | 189 | continue | ||
230 | 190 | mode = 2 | ||
231 | 191 | |||
232 | 192 | |||
233 | 193 | def find_usb_prod(vid, pid): | ||
234 | 194 | "Return device name from USB Vendor:Product list" | ||
235 | 195 | strg = "" | ||
236 | 196 | dev = UsbVendor(vid, "") | ||
237 | 197 | try: | ||
238 | 198 | strg = [v for v in usbvendors if v == dev][0].__repr__() | ||
239 | 199 | except IndexError: | ||
240 | 200 | return "" | ||
241 | 201 | dev = UsbProduct(vid, pid, "") | ||
242 | 202 | try: | ||
243 | 203 | strg += " " + [p for p in usbproducts if p == dev][0].__repr__() | ||
244 | 204 | except IndexError: | ||
245 | 205 | return strg | ||
246 | 206 | return strg | ||
247 | 207 | |||
248 | 208 | |||
249 | 209 | def find_usb_class(cid, sid, pid): | ||
250 | 210 | "Return USB protocol from usbclasses list" | ||
251 | 211 | if cid == 0xff and sid == 0xff and pid == 0xff: | ||
252 | 212 | return "Vendor Specific" | ||
253 | 213 | dev = UsbClass(cid, sid, pid, "") | ||
254 | 214 | try: | ||
255 | 215 | return [c for c in usbclasses if c == dev][0].__repr__() | ||
256 | 216 | except IndexError: | ||
257 | 217 | pass | ||
258 | 218 | dev = UsbClass(cid, sid, -1, "") | ||
259 | 219 | try: | ||
260 | 220 | return [c for c in usbclasses if c == dev][0].__repr__() | ||
261 | 221 | except IndexError: | ||
262 | 222 | pass | ||
263 | 223 | dev = UsbClass(cid, -1, -1, "") | ||
264 | 224 | try: | ||
265 | 225 | return [c for c in usbclasses if c == dev][0].__repr__() | ||
266 | 226 | except IndexError: | ||
267 | 227 | return "" | ||
268 | 228 | |||
269 | 229 | |||
270 | 230 | def find_storage(hostno): | ||
271 | 231 | "Return SCSI block dev names for host" | ||
272 | 232 | res = "" | ||
273 | 233 | for ent in os.listdir("/sys/class/scsi_device/"): | ||
274 | 234 | (host, bus, tgt, lun) = ent.split(":") | ||
275 | 235 | if host == hostno: | ||
276 | 236 | try: | ||
277 | 237 | path = "/sys/class/scsi_device/%s/device/block" % ent | ||
278 | 238 | for ent2 in os.listdir(path): | ||
279 | 239 | res += ent2 + " " | ||
280 | 240 | except: | ||
281 | 241 | pass | ||
282 | 242 | return res | ||
283 | 243 | |||
284 | 244 | |||
285 | 245 | def find_dev(driver, usbname): | ||
286 | 246 | "Return pseudo devname that's driven by driver" | ||
287 | 247 | res = "" | ||
288 | 248 | for nm in devlst: | ||
289 | 249 | dir = prefix + usbname | ||
290 | 250 | prep = "" | ||
291 | 251 | idx = nm.find('/') | ||
292 | 252 | if idx != -1: | ||
293 | 253 | prep = nm[:idx+1] | ||
294 | 254 | dir += "/" + nm[:idx] | ||
295 | 255 | nm = nm[idx+1:] | ||
296 | 256 | ln = len(nm) | ||
297 | 257 | try: | ||
298 | 258 | for ent in os.listdir(dir): | ||
299 | 259 | if ent[:ln] == nm: | ||
300 | 260 | res += prep+ent+" " | ||
301 | 261 | if nm == "host": | ||
302 | 262 | res += "(" + find_storage(ent[ln:])[:-1] + ")" | ||
303 | 263 | except: | ||
304 | 264 | pass | ||
305 | 265 | return res | ||
306 | 266 | |||
307 | 267 | |||
308 | 268 | class UsbInterface: | ||
309 | 269 | "Container for USB interface info" | ||
310 | 270 | |||
311 | 271 | def __init__(self, parent=None, level=1): | ||
312 | 272 | self.parent = parent | ||
313 | 273 | self.level = level | ||
314 | 274 | self.fname = "" | ||
315 | 275 | self.iclass = 0 | ||
316 | 276 | self.isclass = 0 | ||
317 | 277 | self.iproto = 0 | ||
318 | 278 | self.noep = 0 | ||
319 | 279 | self.driver = "" | ||
320 | 280 | self.devname = "" | ||
321 | 281 | self.protoname = "" | ||
322 | 282 | |||
323 | 283 | def read(self, fname): | ||
324 | 284 | fullpath = "" | ||
325 | 285 | if self.parent: | ||
326 | 286 | fullpath += self.parent.fname + "/" | ||
327 | 287 | fullpath += fname | ||
328 | 288 | self.fname = fname | ||
329 | 289 | self.iclass = int(readattr(fullpath, "bInterfaceClass"), 16) | ||
330 | 290 | self.isclass = int(readattr(fullpath, "bInterfaceSubClass"), 16) | ||
331 | 291 | self.iproto = int(readattr(fullpath, "bInterfaceProtocol"), 16) | ||
332 | 292 | self.noep = int(readattr(fullpath, "bNumEndpoints")) | ||
333 | 293 | try: | ||
334 | 294 | self.driver = readlink(fname, "driver") | ||
335 | 295 | self.devname = find_dev(self.driver, fname) | ||
336 | 296 | except: | ||
337 | 297 | pass | ||
338 | 298 | self.protoname = find_usb_class(self.iclass, self.isclass, self.iproto) | ||
339 | 299 | |||
340 | 300 | def __str__(self): | ||
341 | 301 | return "%-16s(IF) %02x:%02x:%02x %iEPs (%s) %s%s %s%s%s\n" % \ | ||
342 | 302 | (" " * self.level+self.fname, self.iclass, | ||
343 | 303 | self.isclass, self.iproto, self.noep, | ||
344 | 304 | self.protoname, | ||
345 | 305 | cols[3], self.driver, | ||
346 | 306 | cols[4], self.devname, cols[0]) | ||
347 | 307 | |||
348 | 308 | |||
349 | 309 | class UsbDevice: | ||
350 | 310 | "Container for USB device info" | ||
351 | 311 | |||
352 | 312 | def __init__(self, parent=None, level=0): | ||
353 | 313 | self.parent = parent | ||
354 | 314 | self.level = level | ||
355 | 315 | self.display_name = "" | ||
356 | 316 | self.fname = "" | ||
357 | 317 | self.busnum = 0 | ||
358 | 318 | self.devnum = 0 | ||
359 | 319 | self.iclass = 0 | ||
360 | 320 | self.isclass = 0 | ||
361 | 321 | self.iproto = 0 | ||
362 | 322 | self.vid = 0 | ||
363 | 323 | self.pid = 0 | ||
364 | 324 | self.name = "" | ||
365 | 325 | self.usbver = "" | ||
366 | 326 | self.speed = "" | ||
367 | 327 | self.maxpower = "" | ||
368 | 328 | self.noports = 0 | ||
369 | 329 | self.nointerfaces = 0 | ||
370 | 330 | self.driver = "" | ||
371 | 331 | self.devname = "" | ||
372 | 332 | self.interfaces = [] | ||
373 | 333 | self.children = [] | ||
374 | 334 | |||
375 | 335 | def read(self, fname): | ||
376 | 336 | self.fname = fname | ||
377 | 337 | self.iclass = int(readattr(fname, "bDeviceClass"), 16) | ||
378 | 338 | self.isclass = int(readattr(fname, "bDeviceSubClass"), 16) | ||
379 | 339 | self.iproto = int(readattr(fname, "bDeviceProtocol"), 16) | ||
380 | 340 | self.vid = int(readattr(fname, "idVendor"), 16) | ||
381 | 341 | self.pid = int(readattr(fname, "idProduct"), 16) | ||
382 | 342 | self.busnum = int(readattr(fname, "busnum")) | ||
383 | 343 | self.devnum = int(readattr(fname, "devnum")) | ||
384 | 344 | self.usbver = readattr(fname, "version") | ||
385 | 345 | try: | ||
386 | 346 | self.name = readattr(fname, "manufacturer") + " " \ | ||
387 | 347 | + readattr(fname, "product") | ||
388 | 348 | if self.name[:5] == "Linux": | ||
389 | 349 | rx = re.compile(r"Linux [^ ]* .hci[-_]hcd") | ||
390 | 350 | mch = rx.match(self.name) | ||
391 | 351 | if mch: | ||
392 | 352 | self.name = "Linux Foundation %.2f root hub" % float( | ||
393 | 353 | self.usbver) | ||
394 | 354 | except: | ||
395 | 355 | pass | ||
396 | 356 | if not self.name: | ||
397 | 357 | self.name = find_usb_prod(self.vid, self.pid) | ||
398 | 358 | # Some USB Card readers have a better name than Generic ... | ||
399 | 359 | if self.name[:7] == "Generic": | ||
400 | 360 | oldnm = self.name | ||
401 | 361 | self.name = find_usb_prod(self.vid, self.pid) | ||
402 | 362 | if not self.name: | ||
403 | 363 | self.name = oldnm | ||
404 | 364 | self.speed = readattr(fname, "speed") | ||
405 | 365 | self.maxpower = readattr(fname, "bMaxPower") | ||
406 | 366 | self.noports = int(readattr(fname, "maxchild")) | ||
407 | 367 | try: | ||
408 | 368 | self.nointerfaces = int(readattr(fname, "bNumInterfaces")) | ||
409 | 369 | except: | ||
410 | 370 | self.nointerfaces = 0 | ||
411 | 371 | try: | ||
412 | 372 | self.driver = readlink(fname, "driver") | ||
413 | 373 | self.devname = find_dev(self.driver, fname) | ||
414 | 374 | except: | ||
415 | 375 | pass | ||
416 | 376 | |||
417 | 377 | def readchildren(self): | ||
418 | 378 | if self.fname[0:3] == "usb": | ||
419 | 379 | fname = self.fname[3:] | ||
420 | 380 | else: | ||
421 | 381 | fname = self.fname | ||
422 | 382 | for dirent in os.listdir(prefix + self.fname): | ||
423 | 383 | if not dirent[0:1].isdigit(): | ||
424 | 384 | continue | ||
425 | 385 | if os.access(prefix + dirent + "/bInterfaceClass", os.R_OK): | ||
426 | 386 | iface = UsbInterface(self, self.level+1) | ||
427 | 387 | iface.read(dirent) | ||
428 | 388 | self.interfaces.append(iface) | ||
429 | 389 | else: | ||
430 | 390 | usbdev = UsbDevice(self, self.level+1) | ||
431 | 391 | usbdev.read(dirent) | ||
432 | 392 | usbdev.readchildren() | ||
433 | 393 | self.children.append(usbdev) | ||
434 | 394 | |||
435 | 395 | def __str__(self): | ||
436 | 396 | if self.iclass == 9: | ||
437 | 397 | col = cols[2] | ||
438 | 398 | if noemptyhub and len(self.children) == 0: | ||
439 | 399 | return "" | ||
440 | 400 | if nohub: | ||
441 | 401 | str = "" | ||
442 | 402 | else: | ||
443 | 403 | col = cols[1] | ||
444 | 404 | if not nohub or self.iclass != 9: | ||
445 | 405 | if shortmode: | ||
446 | 406 | str = "ID %04x:%04x %s" % (self.vid, self.pid, self.name) | ||
447 | 407 | else: | ||
448 | 408 | str = "Bus %03d Device %03d: ID %04x:%04x %s" % \ | ||
449 | 409 | (self.busnum, self.devnum, self.vid, self.pid, self.name) | ||
450 | 410 | str += "\n" | ||
451 | 411 | if showint: | ||
452 | 412 | for iface in self.interfaces: | ||
453 | 413 | str += iface.__str__() | ||
454 | 414 | for child in self.children: | ||
455 | 415 | str += child.__str__() | ||
456 | 416 | return str | ||
457 | 417 | |||
458 | 418 | |||
459 | 419 | def deepcopy(lst): | ||
460 | 420 | "Returns a deep copy from the list lst" | ||
461 | 421 | copy = [] | ||
462 | 422 | for item in lst: | ||
463 | 423 | copy.append(item) | ||
464 | 424 | return copy | ||
465 | 425 | |||
466 | 426 | |||
467 | 427 | def display_diff(lst1, lst2, fmtstr, args): | ||
468 | 428 | "Compare lists (same length!) and display differences" | ||
469 | 429 | for idx in range(0, len(lst1)): | ||
470 | 430 | if lst1[idx] != lst2[idx]: | ||
471 | 431 | print("Warning: " + fmtstr % args(lst2[idx])) | ||
472 | 432 | |||
473 | 433 | |||
474 | 434 | def fix_usbvend(): | ||
475 | 435 | "Sort USB vendor list and (optionally) display diffs" | ||
476 | 436 | if warnsort: | ||
477 | 437 | oldusbvend = deepcopy(usbvendors) | ||
478 | 438 | usbvendors.sort() | ||
479 | 439 | if warnsort: | ||
480 | 440 | display_diff(usbvendors, oldusbvend, "Unsorted Vendor ID %04x", | ||
481 | 441 | lambda x: (x.vid,)) | ||
482 | 442 | |||
483 | 443 | |||
484 | 444 | def fix_usbprod(): | ||
485 | 445 | "Sort USB products list" | ||
486 | 446 | if warnsort: | ||
487 | 447 | oldusbprod = deepcopy(usbproducts) | ||
488 | 448 | usbproducts.sort() | ||
489 | 449 | if warnsort: | ||
490 | 450 | display_diff(usbproducts, oldusbprod, | ||
491 | 451 | "Unsorted Vendor:Product ID %04x:%04x", | ||
492 | 452 | lambda x: (x.vid, x.pid)) | ||
493 | 453 | |||
494 | 454 | |||
495 | 455 | def fix_usbclass(): | ||
496 | 456 | "Sort USB class list" | ||
497 | 457 | if warnsort: | ||
498 | 458 | oldusbcls = deepcopy(usbclasses) | ||
499 | 459 | usbclasses.sort() | ||
500 | 460 | if warnsort: | ||
501 | 461 | display_diff(usbclasses, oldusbcls, | ||
502 | 462 | "Unsorted USB class %02x:%02x:%02x", | ||
503 | 463 | lambda x: (x.pclass, x.subclass, x.proto)) | ||
504 | 464 | |||
505 | 465 | |||
506 | 466 | def usage(): | ||
507 | 467 | "Displays usage information" | ||
508 | 468 | print("Usage: lsusb.py [options]") | ||
509 | 469 | print("Options:") | ||
510 | 470 | print(" -h display this help") | ||
511 | 471 | print(" -i display interface information") | ||
512 | 472 | print(" -I display interface information, even for hubs") | ||
513 | 473 | print(" -u suppress empty hubs") | ||
514 | 474 | print(" -U suppress all hubs") | ||
515 | 475 | print(" -c use colors") | ||
516 | 476 | print(" -s short mode") | ||
517 | 477 | print(" -w display warning if usb.ids is not sorted correctly") | ||
518 | 478 | print(" -f FILE override filename for /usr/share/usb.ids") | ||
519 | 479 | return 2 | ||
520 | 480 | |||
521 | 481 | |||
522 | 482 | def read_usb(): | ||
523 | 483 | "Read toplevel USB entries and print" | ||
524 | 484 | for dirent in os.listdir(prefix): | ||
525 | 485 | if not dirent[0:3] == "usb": | ||
526 | 486 | continue | ||
527 | 487 | usbdev = UsbDevice(None, 0) | ||
528 | 488 | usbdev.read(dirent) | ||
529 | 489 | usbdev.readchildren() | ||
530 | 490 | print(usbdev.__str__(), end="") | ||
542 | 491 | 18 | ||
543 | 19 | import argparse | ||
544 | 20 | from checkbox_support.parsers import sysfs_usb | ||
545 | 492 | 21 | ||
546 | 493 | def main(): | 22 | def main(): |
597 | 494 | "main entry point" | 23 | parser = argparse.ArgumentParser() |
598 | 495 | global showint, showhubint, noemptyhub, nohub, warnsort, cols, usbids, \ | 24 | parser.add_argument( |
599 | 496 | shortmode | 25 | '-s', '--short', action='store_true', |
600 | 497 | try: | 26 | help="Print output in a short form") |
601 | 498 | (optlist, args) = getopt.gnu_getopt(sys.argv[1:], "hiIuUwcsf:", ("help",)) | 27 | parser.add_argument( |
602 | 499 | except getopt.GetoptError as exc: | 28 | '-l', '--long', action='store_true', |
603 | 500 | print("Error:", exc) | 29 | help="Use the new output format") |
604 | 501 | sys.exit(usage()) | 30 | parser.add_argument('-f', '--file', help="Path to the usb.ids file") |
605 | 502 | for opt in optlist: | 31 | args = parser.parse_args() |
606 | 503 | if opt[0] == "-h" or opt[0] == "--help": | 32 | |
607 | 504 | usage() | 33 | usb_ids = sysfs_usb.UsbIds(args.file) |
608 | 505 | sys.exit(0) | 34 | for dev in sysfs_usb.get_usb_devices(usb_ids): |
609 | 506 | if opt[0] == "-i": | 35 | if args.short: |
610 | 507 | showint = True | 36 | print(dev.to_short_str()) |
611 | 508 | continue | 37 | elif args.long: |
612 | 509 | if opt[0] == "-I": | 38 | print(dev.to_str()) |
613 | 510 | showint = True | 39 | else: |
614 | 511 | showhubint = True | 40 | print(dev.to_legacy_str()) |
565 | 512 | continue | ||
566 | 513 | if opt[0] == "-u": | ||
567 | 514 | noemptyhub = True | ||
568 | 515 | continue | ||
569 | 516 | if opt[0] == "-U": | ||
570 | 517 | noemptyhub = True | ||
571 | 518 | nohub = True | ||
572 | 519 | continue | ||
573 | 520 | if opt[0] == "-c": | ||
574 | 521 | cols = (norm, bold, red, green, amber) | ||
575 | 522 | continue | ||
576 | 523 | if opt[0] == "-w": | ||
577 | 524 | warnsort = True | ||
578 | 525 | continue | ||
579 | 526 | if opt[0] == "-f": | ||
580 | 527 | usbids = opt[1] | ||
581 | 528 | continue | ||
582 | 529 | if opt[0] == "-s": | ||
583 | 530 | shortmode = True | ||
584 | 531 | continue | ||
585 | 532 | if len(args) > 0: | ||
586 | 533 | print("Error: excess args %s ..." % args[0]) | ||
587 | 534 | sys.exit(usage()) | ||
588 | 535 | try: | ||
589 | 536 | parse_usb_ids() | ||
590 | 537 | fix_usbvend() | ||
591 | 538 | fix_usbprod() | ||
592 | 539 | fix_usbclass() | ||
593 | 540 | except: | ||
594 | 541 | print(" WARNING: Failure to read usb.ids", file=sys.stderr) | ||
595 | 542 | print(sys.exc_info(), file=sys.stderr) | ||
596 | 543 | read_usb() | ||
615 | 544 | 41 | ||
618 | 545 | # Entry point | 42 | if __name__ == '__main__': |
617 | 546 | if __name__ == "__main__": | ||
619 | 547 | main() | 43 | main() |
620 | diff --git a/checkbox_support/scripts/lsusb3.py b/checkbox_support/scripts/lsusb3.py | |||
621 | 548 | deleted file mode 100644 | 44 | deleted file mode 100644 |
622 | index a2d4677..0000000 | |||
623 | --- a/checkbox_support/scripts/lsusb3.py | |||
624 | +++ /dev/null | |||
625 | @@ -1,43 +0,0 @@ | |||
626 | 1 | # This file is part of Checkbox. | ||
627 | 2 | # | ||
628 | 3 | # Copyright 2020 Canonical Ltd. | ||
629 | 4 | # Written by: | ||
630 | 5 | # Maciej Kisielewski <maciej.kisielewski@canonical.com> | ||
631 | 6 | # | ||
632 | 7 | # Checkbox is free software: you can redistribute it and/or modify | ||
633 | 8 | # it under the terms of the GNU General Public License version 3, | ||
634 | 9 | # as published by the Free Software Foundation. | ||
635 | 10 | # | ||
636 | 11 | # Checkbox is distributed in the hope that it will be useful, | ||
637 | 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
638 | 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
639 | 14 | # GNU General Public License for more details. | ||
640 | 15 | # | ||
641 | 16 | # You should have received a copy of the GNU General Public License | ||
642 | 17 | # along with Checkbox. If not, see <http://www.gnu.org/licenses/>. | ||
643 | 18 | |||
644 | 19 | import argparse | ||
645 | 20 | from checkbox_support.parsers import sysfs_usb | ||
646 | 21 | |||
647 | 22 | def main(): | ||
648 | 23 | parser = argparse.ArgumentParser() | ||
649 | 24 | parser.add_argument( | ||
650 | 25 | '-s', '--short', action='store_true', | ||
651 | 26 | help="Print output in a short form") | ||
652 | 27 | parser.add_argument( | ||
653 | 28 | '-l', '--long', action='store_true', | ||
654 | 29 | help="Use the new output format") | ||
655 | 30 | parser.add_argument('-f', '--file', help="Path to the usb.ids file") | ||
656 | 31 | args = parser.parse_args() | ||
657 | 32 | |||
658 | 33 | usb_ids = sysfs_usb.UsbIds(args.file) | ||
659 | 34 | for dev in sysfs_usb.get_usb_devices(usb_ids): | ||
660 | 35 | if args.short: | ||
661 | 36 | print(dev.to_short_str()) | ||
662 | 37 | elif args.long: | ||
663 | 38 | print(dev.to_str()) | ||
664 | 39 | else: | ||
665 | 40 | print(dev.to_legacy_str()) | ||
666 | 41 | |||
667 | 42 | if __name__ == '__main__': | ||
668 | 43 | main() | ||
669 | diff --git a/setup.py b/setup.py | |||
670 | index d5d4a59..75dbc11 100755 | |||
671 | --- a/setup.py | |||
672 | +++ b/setup.py | |||
673 | @@ -93,8 +93,6 @@ setup( | |||
674 | 93 | "checkbox_support.scripts.eddystone_scanner:main"), | 93 | "checkbox_support.scripts.eddystone_scanner:main"), |
675 | 94 | ("checkbox-support-lsusb=" | 94 | ("checkbox-support-lsusb=" |
676 | 95 | "checkbox_support.scripts.lsusb:main"), | 95 | "checkbox_support.scripts.lsusb:main"), |
677 | 96 | ("checkbox-support-lsusb3=" | ||
678 | 97 | "checkbox_support.scripts.lsusb3:main"), | ||
679 | 98 | ], | 96 | ], |
680 | 99 | }, | 97 | }, |
681 | 100 | ) | 98 | ) |
2020 !