Skip to content

Commit 5355115

Browse files
authored
fix: simplify usb listing (#1402)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Improved USB device detection for increased reliability and performance. - Device names are now displayed based on basic device information, with unnamed devices labeled appropriately. - GUID generation for devices is simplified and more robust. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210189043307638
1 parent 881f1e0 commit 5355115

File tree

1 file changed

+36
-66
lines changed
  • api/src/graphql/resolvers/query

1 file changed

+36
-66
lines changed

api/src/graphql/resolvers/query/info.ts

Lines changed: 36 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -325,86 +325,56 @@ export const generateDevices = async (): Promise<Devices> => {
325325
};
326326
};
327327

328-
const parseDeviceLine = (line: Readonly<string>): { value: string; string: string } => {
329-
const emptyLine = { value: '', string: '' };
330-
331-
// If the line is blank return nothing
332-
if (!line) {
333-
return emptyLine;
334-
}
335-
336-
// Parse the line
337-
const [, _] = line.split(/[ \t]{2,}/).filter(Boolean);
338-
339-
const match = _.match(/^(\S+)\s(.*)/)?.slice(1);
340-
341-
// If there's no match return nothing
342-
if (!match) {
343-
return emptyLine;
344-
}
345-
346-
return {
347-
value: match[0],
348-
string: match[1],
349-
};
350-
};
351-
352-
// Add extra fields to device
353-
const parseDevice = (device: Readonly<PciDevice>) => {
328+
// Simplified basic device parsing without verbose details
329+
const parseBasicDevice = async (device: PciDevice): Promise<PciDevice> => {
354330
const modifiedDevice: PciDevice = {
355331
...device,
356332
};
357-
const info = execaCommandSync(`lsusb -d ${device.id} -v`).stdout.split('\n');
358-
const deviceName = device.name.trim();
359-
const iSerial = parseDeviceLine(info.filter((line) => line.includes('iSerial'))[0]);
360-
const iProduct = parseDeviceLine(info.filter((line) => line.includes('iProduct'))[0]);
361-
const iManufacturer = parseDeviceLine(
362-
info.filter((line) => line.includes('iManufacturer'))[0]
363-
);
364-
const idProduct = parseDeviceLine(info.filter((line) => line.includes('idProduct'))[0]);
365-
const idVendor = parseDeviceLine(info.filter((line) => line.includes('idVendor'))[0]);
366-
const serial = `${iSerial.string.slice(8).slice(0, 4)}-${iSerial.string
367-
.slice(8)
368-
.slice(4)}`;
369-
const guid = `${idVendor.value.slice(2)}-${idProduct.value.slice(2)}-${serial}`;
370-
371-
modifiedDevice.serial = iSerial.string;
372-
modifiedDevice.product = iProduct.string;
373-
modifiedDevice.manufacturer = iManufacturer.string;
374-
modifiedDevice.guid = guid;
375-
376-
// Set name if missing
377-
if (deviceName === '') {
378-
modifiedDevice.name = `${iProduct.string} ${iManufacturer.string}`.trim();
379-
}
380333

381-
// Name still blank? Replace using fallback default
382-
if (deviceName === '') {
383-
modifiedDevice.name = '[unnamed device]';
334+
// Use a simplified GUID generation instead of calling lsusb -v
335+
const idParts = device.id.split(':');
336+
if (idParts.length === 2) {
337+
const [vendorId, productId] = idParts;
338+
modifiedDevice.guid = `${vendorId}-${productId}-basic`;
339+
} else {
340+
modifiedDevice.guid = `unknown-${Math.random().toString(36).substring(7)}`;
384341
}
385342

386-
// Ensure name is trimmed
387-
modifiedDevice.name = device.name.trim();
343+
// Use the name from basic lsusb output
344+
const deviceName = device.name?.trim() || '';
345+
modifiedDevice.name = deviceName || '[unnamed device]';
388346

389347
return modifiedDevice;
390348
};
391349

392-
const parseUsbDevices = (stdout: string) =>
393-
stdout.split('\n').map((line) => {
394-
const regex = new RegExp(/^.+: ID (?<id>\S+)(?<name>.*)$/);
395-
const result = regex.exec(line);
396-
return result?.groups as unknown as PciDevice;
397-
}) ?? [];
350+
const parseUsbDevices = (stdout: string): PciDevice[] =>
351+
stdout
352+
.split('\n')
353+
.map((line) => {
354+
const regex = new RegExp(/^.+: ID (?<id>\S+)(?<n>.*)$/);
355+
const result = regex.exec(line);
356+
if (!result?.groups) return null;
357+
358+
// Extract name from the line if available
359+
const name = result.groups.n?.trim() || '';
360+
return {
361+
...result.groups,
362+
name,
363+
} as unknown as PciDevice;
364+
})
365+
.filter((device): device is PciDevice => device !== null) ?? [];
398366

399-
// Get all usb devices
367+
// Get all usb devices with basic listing only
400368
const usbDevices = await execa('lsusb')
401-
.then(async ({ stdout }) =>
402-
parseUsbDevices(stdout)
403-
.map(parseDevice)
369+
.then(async ({ stdout }) => {
370+
const devices = parseUsbDevices(stdout);
371+
// Process devices in parallel
372+
const processedDevices = await Promise.all(devices.map(parseBasicDevice));
373+
return processedDevices
404374
.filter(filterBootDrive)
405375
.filter(filterUsbHubs)
406-
.map(sanitizeVendorName)
407-
)
376+
.map(sanitizeVendorName);
377+
})
408378
.catch(() => []);
409379

410380
return usbDevices;

0 commit comments

Comments
 (0)