dscl: Directory Service command line utility

"""
Run the macOS dscl commmand to get a list of all the users.
Print out detailed information about the one user whose real name is specified.
Display a jpg image of that user, too.
"""

import sys
import os          #operating system
import tkinter

import plistlib    #property list files
import binascii    #convert ASCII hex digits to binary
import PIL.ImageTk #Python Imaging Library

#Directory Service command line
command = "dscl -plist /Local/Default -readall /Users"
realName = "Mark Meretzky"

infile = os.popen(command)  #pipe open
s = infile.read()           #s is a string
exitStatus = infile.close() #returns the exit status of dscl

if exitStatus is not None:  #None indicates successful termination.
    if exitStatus >= 0:
        print(f"dscl exit status = {exitStatus >> 8}")  #right shift
    else:
        print(f"dscl was terminated by signal number {-exitStatus}.")
    sys.exit(1)

#plistlib no longer has the function readPlistFromString.
#users is a list of dictionaries.
users = plistlib.loads(s.encode(), fmt = plistlib.FMT_XML)

for user in users:
    if user["dsAttrTypeStandard:RealName"] != [realName]:
        continue
    for i, (key, value) in enumerate(user.items(), start = 1):
        print(i, key)
        if key == "dsAttrTypeStandard:JPEGPhoto":
            stringOfChars = value[0].replace(" ", "")   #hex digits
            sequenceOfBytes = binascii.a2b_hex(stringOfChars)
            value = [f"{len(sequenceOfBytes):,} bytes"]
        for v in value:
            print(f"\t{v}")

#Display the dsAttrTypeStandard:JPEGPhoto in a tkinter Canvas.
root = tkinter.Tk()

try:
    image = PIL.ImageTk.PhotoImage(data = sequenceOfBytes)
except:
    print(f"Can't create PhotoImage: {sys.exc_info()}")
    sys.exit(1)

width = image.width()
height = image.height()
root.geometry(f"{width}x{height}")
root.title("dsAttrTypeStandard:JPEGPhoto")

#Put the center of the image at the center of the canvas.
canvas = tkinter.Canvas(root, highlightthickness = 0)
canvas.create_image(width / 2, height / 2, image = image)
canvas.pack(expand = tkinter.YES, fill = "both")

root.mainloop()