From 932e739255dff83ff1d2812134f37c77b1839b58 Mon Sep 17 00:00:00 2001 From: InsanePrawn Date: Mon, 2 Jan 2023 03:54:31 +0100 Subject: [PATCH] devices/cli: add --json parameter --- devices/cli.py | 10 +++++++++- devices/device.py | 47 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/devices/cli.py b/devices/cli.py index aa6189d..6ccfc27 100644 --- a/devices/cli.py +++ b/devices/cli.py @@ -1,4 +1,5 @@ import click +from json import dumps as json_dump import logging from config.state import config @@ -7,7 +8,8 @@ from .device import get_devices, get_profile_device @click.command(name='devices') -def cmd_devices(): +@click.option('--json', is_flag=True, help='output machine-parsable JSON format') +def cmd_devices(json: bool = False): 'list the available devices and descriptions' devices = get_devices() if not devices: @@ -20,6 +22,7 @@ def cmd_devices(): except Exception as ex: logging.debug(f"Failed to get profile device for visual highlighting, not a problem: {ex}") output = [''] + json_output = {} for name in sorted(devices.keys()): prefix = '' suffix = '' @@ -29,6 +32,9 @@ def cmd_devices(): device.parse_deviceinfo(try_download=False) except Exception as ex: logging.debug(f"Failed to parse deviceinfo for extended description, not a problem: {ex}") + if json: + json_output[name] = device.get_summary().toDict() + continue if profile_device and profile_device.name == device.name: prefix = '>>> ' suffix = f'\n\nCurrently selected by profile "{config.file.profiles.current}"' @@ -36,5 +42,7 @@ def cmd_devices(): # prefix each line in the snippet snippet = '\n'.join([f'{prefix}{line}' for line in snippet.split('\n')]) output.append(f"{snippet}\n") + if json: + output = ['\n' + json_dump(json_output, indent=4)] for line in output: print(line) diff --git a/devices/device.py b/devices/device.py index bc90da3..02c25af 100644 --- a/devices/device.py +++ b/devices/device.py @@ -22,6 +22,25 @@ DEVICE_DEPRECATIONS = { } +class DeviceSummary(DataClass): + name: str + description: str + arch: str + package_name: Optional[str] + package_path: Optional[str] + + def nice_str(self, newlines: bool = False): + separator = '\n' if newlines else ', ' + return separator.join([ + f'Device: {self.name}', + 'Description: ' + + (self.description or f"[no package {'description' if self.package_name else 'associated (?!)'} and deviceinfo not parsed]"), + f'Architecture: {self.arch}', + 'Package Name: ' + + (f"{self.package_name}{separator}Package Path: {self.package_path}" if self.package_name else "no package associated. PROBABLY A BUG!"), + ]) + + @munchclass() class Device(DataClass): name: str @@ -33,21 +52,21 @@ class Device(DataClass): return f'Device<{self.name},{self.arch},{self.package.path if self.package else "[no package]"}>' def __str__(self): - return self.get_summary_str(newlines=True) + return self.nice_str(newlines=True) - def get_summary_str(self, newlines: bool = False): - separator = '\n' if newlines else ', ' - description = ( - (self.package.description if self.package else "").strip() or - (self.deviceinfo.get("name", "[No name in deviceinfo]") if self.deviceinfo else "") - ).strip() - description = description or f"[no package {'description' if self.package else 'associated (?!)'} and deviceinfo not parsed]" - return separator.join([ - f'Device: {self.name}', - f'Description: {description}', - f'Architecture: {self.arch}', - 'Package Name: ' + (f"{self.package.name}{separator}Package Path: {self.package.path}" if self.package else "??? PROBABLY A BUG!"), - ]) + def nice_str(self, *args, **kwargs) -> str: + return self.get_summary().nice_str(*args, **kwargs) + + def get_summary(self) -> DeviceSummary: + result: dict[str, Optional[str]] = {} + description = ((self.package.description if self.package else "").strip() or + (self.deviceinfo.get("name", "[No name in deviceinfo]") if self.deviceinfo else "")).strip() + result["name"] = self.name + result["description"] = description + result["arch"] = self.arch + result["package_name"] = self.package.name if self.package else None + result["package_path"] = self.package.path if self.package else None + return DeviceSummary(result) def parse_deviceinfo(self, try_download: bool = True, lazy: bool = True): if not lazy or 'deviceinfo' not in self or self.deviceinfo is None: