mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-02-28 00:22:41 -08:00
251 lines
6.6 KiB
Python
251 lines
6.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
iOS Status Bar Controller
|
|
|
|
Override simulator status bar for clean screenshots and testing.
|
|
Control time, network, wifi, battery display.
|
|
|
|
Usage: python scripts/status_bar.py --preset clean
|
|
"""
|
|
|
|
import argparse
|
|
import subprocess
|
|
import sys
|
|
|
|
from common import resolve_udid
|
|
|
|
|
|
class StatusBarController:
|
|
"""Controls iOS simulator status bar appearance."""
|
|
|
|
# Preset configurations
|
|
PRESETS = {
|
|
"clean": {
|
|
"time": "9:41",
|
|
"data_network": "5g",
|
|
"wifi_mode": "active",
|
|
"battery_state": "charged",
|
|
"battery_level": 100,
|
|
},
|
|
"testing": {
|
|
"time": "11:11",
|
|
"data_network": "4g",
|
|
"wifi_mode": "active",
|
|
"battery_state": "discharging",
|
|
"battery_level": 50,
|
|
},
|
|
"low_battery": {
|
|
"time": "9:41",
|
|
"data_network": "5g",
|
|
"wifi_mode": "active",
|
|
"battery_state": "discharging",
|
|
"battery_level": 20,
|
|
},
|
|
"airplane": {
|
|
"time": "9:41",
|
|
"data_network": "none",
|
|
"wifi_mode": "failed",
|
|
"battery_state": "charged",
|
|
"battery_level": 100,
|
|
},
|
|
}
|
|
|
|
def __init__(self, udid: str | None = None):
|
|
"""Initialize status bar controller.
|
|
|
|
Args:
|
|
udid: Optional device UDID (auto-detects booted simulator if None)
|
|
"""
|
|
self.udid = udid
|
|
|
|
def override(
|
|
self,
|
|
time: str | None = None,
|
|
data_network: str | None = None,
|
|
wifi_mode: str | None = None,
|
|
battery_state: str | None = None,
|
|
battery_level: int | None = None,
|
|
) -> bool:
|
|
"""
|
|
Override status bar appearance.
|
|
|
|
Args:
|
|
time: Time in HH:MM format (e.g., "9:41")
|
|
data_network: Network type (none, 1x, 3g, 4g, 5g, lte, lte-a)
|
|
wifi_mode: WiFi state (active, searching, failed)
|
|
battery_state: Battery state (charging, charged, discharging)
|
|
battery_level: Battery percentage (0-100)
|
|
|
|
Returns:
|
|
Success status
|
|
"""
|
|
cmd = ["xcrun", "simctl", "status_bar"]
|
|
|
|
if self.udid:
|
|
cmd.append(self.udid)
|
|
else:
|
|
cmd.append("booted")
|
|
|
|
cmd.append("override")
|
|
|
|
# Add parameters if provided
|
|
if time:
|
|
cmd.extend(["--time", time])
|
|
if data_network:
|
|
cmd.extend(["--dataNetwork", data_network])
|
|
if wifi_mode:
|
|
cmd.extend(["--wifiMode", wifi_mode])
|
|
if battery_state:
|
|
cmd.extend(["--batteryState", battery_state])
|
|
if battery_level is not None:
|
|
cmd.extend(["--batteryLevel", str(battery_level)])
|
|
|
|
try:
|
|
subprocess.run(cmd, capture_output=True, check=True)
|
|
return True
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
|
|
def clear(self) -> bool:
|
|
"""
|
|
Clear status bar override and restore defaults.
|
|
|
|
Returns:
|
|
Success status
|
|
"""
|
|
cmd = ["xcrun", "simctl", "status_bar"]
|
|
|
|
if self.udid:
|
|
cmd.append(self.udid)
|
|
else:
|
|
cmd.append("booted")
|
|
|
|
cmd.append("clear")
|
|
|
|
try:
|
|
subprocess.run(cmd, capture_output=True, check=True)
|
|
return True
|
|
except subprocess.CalledProcessError:
|
|
return False
|
|
|
|
|
|
def main():
|
|
"""Main entry point."""
|
|
parser = argparse.ArgumentParser(
|
|
description="Override iOS simulator status bar for screenshots and testing"
|
|
)
|
|
|
|
# Preset option
|
|
parser.add_argument(
|
|
"--preset",
|
|
choices=list(StatusBarController.PRESETS.keys()),
|
|
help="Use preset configuration (clean, testing, low-battery, airplane)",
|
|
)
|
|
|
|
# Custom options
|
|
parser.add_argument(
|
|
"--time",
|
|
help="Override time (HH:MM format, e.g., '9:41')",
|
|
)
|
|
parser.add_argument(
|
|
"--data-network",
|
|
choices=["none", "1x", "3g", "4g", "5g", "lte", "lte-a"],
|
|
help="Data network type",
|
|
)
|
|
parser.add_argument(
|
|
"--wifi-mode",
|
|
choices=["active", "searching", "failed"],
|
|
help="WiFi state",
|
|
)
|
|
parser.add_argument(
|
|
"--battery-state",
|
|
choices=["charging", "charged", "discharging"],
|
|
help="Battery state",
|
|
)
|
|
parser.add_argument(
|
|
"--battery-level",
|
|
type=int,
|
|
help="Battery level 0-100",
|
|
)
|
|
|
|
# Other options
|
|
parser.add_argument(
|
|
"--clear",
|
|
action="store_true",
|
|
help="Clear status bar override and restore defaults",
|
|
)
|
|
parser.add_argument(
|
|
"--udid",
|
|
help="Device UDID (auto-detects booted simulator if not provided)",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Resolve UDID with auto-detection
|
|
try:
|
|
udid = resolve_udid(args.udid)
|
|
except RuntimeError as e:
|
|
print(f"Error: {e}")
|
|
sys.exit(1)
|
|
|
|
controller = StatusBarController(udid=udid)
|
|
|
|
# Clear mode
|
|
if args.clear:
|
|
if controller.clear():
|
|
print("Status bar override cleared - defaults restored")
|
|
else:
|
|
print("Failed to clear status bar override")
|
|
sys.exit(1)
|
|
|
|
# Preset mode
|
|
elif args.preset:
|
|
preset = StatusBarController.PRESETS[args.preset]
|
|
if controller.override(**preset):
|
|
print(f"Status bar: {args.preset} preset applied")
|
|
print(
|
|
f" Time: {preset['time']}, "
|
|
f"Network: {preset['data_network']}, "
|
|
f"Battery: {preset['battery_level']}%"
|
|
)
|
|
else:
|
|
print(f"Failed to apply {args.preset} preset")
|
|
sys.exit(1)
|
|
|
|
# Custom mode
|
|
elif any(
|
|
[
|
|
args.time,
|
|
args.data_network,
|
|
args.wifi_mode,
|
|
args.battery_state,
|
|
args.battery_level is not None,
|
|
]
|
|
):
|
|
if controller.override(
|
|
time=args.time,
|
|
data_network=args.data_network,
|
|
wifi_mode=args.wifi_mode,
|
|
battery_state=args.battery_state,
|
|
battery_level=args.battery_level,
|
|
):
|
|
output = "Status bar override applied:"
|
|
if args.time:
|
|
output += f" Time={args.time}"
|
|
if args.data_network:
|
|
output += f" Network={args.data_network}"
|
|
if args.battery_level is not None:
|
|
output += f" Battery={args.battery_level}%"
|
|
print(output)
|
|
else:
|
|
print("Failed to override status bar")
|
|
sys.exit(1)
|
|
|
|
else:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|