1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
# -*- coding: utf-8 -*-
import os
import re
import subprocess as sp
from time import sleep
from DisplayCAL.meta import name as appname
from DisplayCAL.options import verbose
def get_osascript_args(applescript):
"""Return arguments ready to use for osascript"""
if isinstance(applescript, str):
applescript = applescript.splitlines()
args = []
for line in applescript:
args.extend(["-e", line])
return args
def get_osascript_args_or_run(applescript, run=True):
"""Return arguments ready to use for osascript or run the AppleScript"""
if run:
return osascript(applescript)
else:
return get_osascript_args(applescript)
def mac_app_activate(delay=0, mac_app_name="Finder"):
"""Activate (show & bring to front) an application if it is running."""
applescript = [
'if app "%s" is running then' % mac_app_name,
# Use 'run script' to prevent the app activating upon script
# compilation even if not running
r'run script "tell app \"%s\" to activate"' % mac_app_name,
"end if",
]
if delay:
sleep(delay)
return osascript(applescript)
def mac_terminal_do_script(script=None, do=True):
"""Run a script in Terminal."""
applescript = [
'if app "Terminal" is running then',
'tell app "Terminal"',
"activate",
'do script ""', # Terminal is already running, open a new
# window to make sure it is not blocked by
# another process
"end tell",
"else",
'tell app "Terminal" to activate', # Terminal is not yet running,
# launch & use first window
"end if",
]
if script:
applescript.extend(
[
'tell app "Terminal"',
'do script "%s" in first window' % script.replace('"', '\\"'),
"end tell",
]
)
return get_osascript_args_or_run(applescript, script and do)
def mac_terminal_set_colors(
background="black", cursor="gray", text="gray", text_bold="gray", do=True
):
"""Set Terminal colors."""
applescript = [
'tell app "Terminal"',
'set background color of first window to "%s"' % background,
'set cursor color of first window to "%s"' % cursor,
'set normal text color of first window to "%s"' % text,
'set bold text color of first window to "%s"' % text_bold,
"end tell",
]
return get_osascript_args_or_run(applescript, do)
def osascript(applescript):
"""Run AppleScript with the 'osascript' command
Return osascript's exit code.
"""
args = get_osascript_args(applescript)
p = sp.Popen(["osascript"] + args, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
output, errors = p.communicate()
retcode = p.wait()
return retcode, output, errors
def get_model_code(serial=None):
"""Given a mac serial number, return the model code
If serial is None, this mac's serial number is used.
"""
if not serial:
serial = get_serial()
if serial:
if "serial" in serial.lower():
# Workaround for machines with dummy serial numbers
return None
if len(serial) in (12, 13) and serial.startswith("S"):
# Remove prefix from scanned codes
serial = serial[1:]
if len(serial) in (11, 12):
return serial[8:]
return None
def get_serial():
"""Return this mac's serial number"""
try:
p = sp.Popen(
["ioreg", "-c", "IOPlatformExpertDevice", "-d", "2"],
stdin=sp.PIPE,
stdout=sp.PIPE,
stderr=sp.PIPE,
)
output, errors = p.communicate()
except Exception:
return None
match = re.search(r'"IOPlatformSerialNumber"\s*=\s*"([^"]*)"', output.decode())
if match:
return match.group(1)
def get_model_id():
"""Return this mac's model id"""
try:
p = sp.Popen(
["sysctl", "hw.model"], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE
)
output, errors = p.communicate()
except BaseException:
return None
if isinstance(output, bytes):
output = output.decode("utf-8")
return "".join(output).split(None, 1)[-1].strip()
def get_machine_attributes(model_id=None):
"""Given a mac model ID, return the machine attributes
If model_code is None, this mac's model code is used.
"""
if not model_id:
model_id = get_model_id()
if not model_id:
return None
pf = "/System/Library/PrivateFrameworks"
f = ".framework/Versions/A/Resources/English.lproj"
sk = "%s/ServerKit%s/XSMachineAttributes" % (pf, f)
si = "%s/ServerInformation%s/SIMachineAttributes" % (pf, f)
if os.path.isfile(si + ".plist"):
# Mac OS X 10.8 or newer
filename = si
else:
# Mac OS X 10.6/10.7
filename = sk
try:
p = sp.Popen(
["defaults", "read", filename, model_id],
stdin=sp.PIPE,
stdout=sp.PIPE,
stderr=sp.PIPE,
)
output, errors = p.communicate()
except Exception:
return None
attrs = {}
for line in output.splitlines():
match = re.search(r'(\w+)\s*=\s*"?(.*?)"?\s*;', line.decode())
if match:
# Need to double unescape backslashes
attrs[match.group(1)] = (
match.group(2).decode("string_escape").decode("string_escape")
)
return attrs
|