Skip to content

Instantly share code, notes, and snippets.

@joxl
Created June 4, 2020 23:01
Show Gist options
  • Save joxl/4fc43703e15597a3abce5173121a428b to your computer and use it in GitHub Desktop.
Save joxl/4fc43703e15597a3abce5173121a428b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import argparse
import json
import sys
from textwrap import indent
from subprocess import PIPE, Popen
class Grid(object):
def __init__(self, header):
self.grid = []
self.header = []
self.widths = []
for col in header:
col = col.strip()
self.header.append(col)
self.widths.append(0) #len(col))
def append_row(self, items):
row = []
for item in items:
row.append(str(item).strip())
cols = len(self.header)
if len(row) != cols:
raise TypeError("wrong number of items (expected {}): {!s}".format(cols, row))
for index, item in enumerate(row):
self.widths[index] = max(self.widths[index], len(item))
self.grid.append(row)
def print(self, print_header=True, pad=True, delim=" "):
if print_header:
grid = [self.header] + self.grid
widths = []
for index, width in enumerate(self.widths):
widths.append(max(len(self.header[index]), width))
else:
grid = self.grid
widths = self.widths
for row in grid:
items = []
if pad:
for index, item in enumerate(row):
items.append(item.ljust(widths[index]))
else:
items = row
print(delim.join(items))
def logerr(text):
sys.stderr.write(text)
def main(opts):
command = ["/usr/sbin/system_profiler", "-json", "SPDisplaysDataType"]
proc = Popen(command, stdout=PIPE, stderr=PIPE)
stdout, stderr = proc.communicate()
stderr = stderr.strip()
if proc.returncode != 0 or stderr:
logerr("command {!r} exited with code: {}\n".format(command[0], \
proc.returncode))
if stderr:
logerr("STDERR:\n{!s}\n".format(indent(stderr.decode('utf-8'), " ")))
try:
response = json.loads(stdout)
gpus = response["SPDisplaysDataType"]
except (ValueError, KeyError) as exc:
logerr("invalid JSON: {!s}\n".format(exc))
return 1
grid = Grid(["GPU", "Display", "Resolution", "S/N"])
for gind, gpu in enumerate(gpus):
gpuname = gpu.get("sppci_model", "<GPU {}>".format(gind))
displays = gpu.get("spdisplays_ndrvs", [])
if not displays and opts.all_gpus:
grid.append_row([gpuname, "<None>"] + ["--"] * 2)
continue
for dind, display in enumerate(displays):
dsp = display.get("_name", "<Display {}>".format(dind))
res = display.get("_spdisplays_resolution", "n/a")
sno = display.get("spdisplays_display-serial-number", "")
grid.append_row([gpuname, dsp, res, sno])
header = not opts.no_header
pad = not opts.no_padding
grid.print(header, pad, opts.delim)
return 0
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--all-gpus", action="store_true", default=False,
help="print a line for every GPU, even those without displays")
parser.add_argument("-H", "--no-header", action="store_true", default=False,
help="do not print header row")
parser.add_argument("-P", "--no-padding", action="store_true", default=False,
help="do not whitespace-pad columns")
parser.add_argument("-d", "--delim", default=" ",
help="column delimiter (default=%(default)r)")
opts = parser.parse_args()
sys.exit(main(opts))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment