#!/usr/bin/env python3 """Install the local app and two login jobs. Run once after the preview works.""" import os from pathlib import Path import plistlib import re import shutil import subprocess import sys ROOT = Path(__file__).resolve().parent HOME_DIR = Path.home() APP = HOME_DIR / 'Applications' / 'Divoom Usage.app' AGENTS = HOME_DIR / 'Library' / 'LaunchAgents' STATE = ROOT / 'state' LABELS = ['local.divoom-usage.collector', 'local.divoom-usage.display'] if len(sys.argv) != 2 or not re.fullmatch(r'(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}', sys.argv[1]): sys.exit('Usage: python install_login.py YOUR_BLUETOOTH_ADDRESS') address = sys.argv[1].replace('-', ':').upper() config_value = os.environ.get('CLIPROXY_CONFIG') if not config_value: sys.exit('Set CLIPROXY_CONFIG to your CLIProxyAPI config path first.') config = Path(config_value).expanduser().resolve() for required in [config, ROOT/'display', ROOT/'usage_display.py', ROOT/'.venv/bin/python', STATE/'display.bin']: if not required.exists(): sys.exit(f'Missing required file: {required}') for target in [APP, *(AGENTS/f'{label}.plist' for label in LABELS)]: if target.exists(): sys.exit(f'Already exists: {target}. Stop here if you already installed this monitor.') os.umask(0o077) (APP/'Contents/MacOS').mkdir(parents=True) AGENTS.mkdir(parents=True, exist_ok=True) shutil.copy2(ROOT/'display', APP/'Contents/MacOS/display') info = { 'CFBundleExecutable': 'display', 'CFBundleIdentifier': 'local.divoom-usage.app', 'CFBundleName': 'Divoom Usage', 'CFBundlePackageType': 'APPL', 'CFBundleShortVersionString': '1.0', 'CFBundleVersion': '1', 'LSUIElement': True, 'NSBluetoothAlwaysUsageDescription': 'Send account quota cards to your Divoom MiniToo.', 'NSBluetoothPeripheralUsageDescription': 'Send account quota cards to your Divoom MiniToo.', } (APP/'Contents/Info.plist').write_bytes(plistlib.dumps(info)) subprocess.run(['/usr/bin/codesign', '--force', '--sign', '-', str(APP)], check=True) commands = [ [str(ROOT/'.venv/bin/python'), str(ROOT/'usage_display.py'), '--watch'], ['/usr/bin/open', '-g', '-W', str(APP), '--args', address, str(STATE/'display.bin')], ] for label, command in zip(LABELS, commands): name = label.rsplit('.', 1)[1] job = { 'Label': label, 'ProgramArguments': command, 'WorkingDirectory': str(ROOT), 'EnvironmentVariables': {'CLIPROXY_CONFIG': str(config)}, 'RunAtLoad': True, 'KeepAlive': True, 'ThrottleInterval': 30, 'ProcessType': 'Background', 'StandardOutPath': str(STATE/f'{name}.log'), 'StandardErrorPath': str(STATE/f'{name}.error.log'), } path = AGENTS/f'{label}.plist' path.write_bytes(plistlib.dumps(job)) subprocess.run(['/bin/launchctl', 'bootstrap', f'gui/{os.getuid()}', str(path)], check=True) print('Installed. Allow Bluetooth access for Divoom Usage when macOS asks.') print(f'Check transfer results in {STATE / "transport.log"}')