pymobiledevice3 4.27.4__py3-none-any.whl → 5.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- misc/plist_sniffer.py +15 -15
- misc/remotexpc_sniffer.py +29 -28
- pymobiledevice3/__main__.py +123 -98
- pymobiledevice3/_version.py +2 -2
- pymobiledevice3/bonjour.py +351 -117
- pymobiledevice3/ca.py +32 -24
- pymobiledevice3/cli/activation.py +7 -7
- pymobiledevice3/cli/afc.py +19 -19
- pymobiledevice3/cli/amfi.py +4 -4
- pymobiledevice3/cli/apps.py +51 -39
- pymobiledevice3/cli/backup.py +58 -32
- pymobiledevice3/cli/bonjour.py +27 -20
- pymobiledevice3/cli/cli_common.py +112 -81
- pymobiledevice3/cli/companion_proxy.py +4 -4
- pymobiledevice3/cli/completions.py +10 -10
- pymobiledevice3/cli/crash.py +37 -31
- pymobiledevice3/cli/developer.py +601 -519
- pymobiledevice3/cli/diagnostics.py +38 -33
- pymobiledevice3/cli/lockdown.py +82 -72
- pymobiledevice3/cli/mounter.py +84 -67
- pymobiledevice3/cli/notification.py +10 -10
- pymobiledevice3/cli/pcap.py +19 -14
- pymobiledevice3/cli/power_assertion.py +12 -10
- pymobiledevice3/cli/processes.py +10 -10
- pymobiledevice3/cli/profile.py +88 -77
- pymobiledevice3/cli/provision.py +17 -17
- pymobiledevice3/cli/remote.py +188 -111
- pymobiledevice3/cli/restore.py +43 -40
- pymobiledevice3/cli/springboard.py +30 -28
- pymobiledevice3/cli/syslog.py +85 -58
- pymobiledevice3/cli/usbmux.py +21 -20
- pymobiledevice3/cli/version.py +3 -2
- pymobiledevice3/cli/webinspector.py +156 -78
- pymobiledevice3/common.py +1 -1
- pymobiledevice3/exceptions.py +154 -60
- pymobiledevice3/irecv.py +49 -53
- pymobiledevice3/irecv_devices.py +1489 -492
- pymobiledevice3/lockdown.py +400 -251
- pymobiledevice3/lockdown_service_provider.py +5 -7
- pymobiledevice3/osu/os_utils.py +18 -9
- pymobiledevice3/osu/posix_util.py +28 -15
- pymobiledevice3/osu/win_util.py +14 -8
- pymobiledevice3/pair_records.py +19 -19
- pymobiledevice3/remote/common.py +4 -4
- pymobiledevice3/remote/core_device/app_service.py +94 -67
- pymobiledevice3/remote/core_device/core_device_service.py +17 -14
- pymobiledevice3/remote/core_device/device_info.py +5 -5
- pymobiledevice3/remote/core_device/diagnostics_service.py +10 -8
- pymobiledevice3/remote/core_device/file_service.py +47 -33
- pymobiledevice3/remote/remote_service_discovery.py +53 -35
- pymobiledevice3/remote/remotexpc.py +64 -42
- pymobiledevice3/remote/tunnel_service.py +383 -297
- pymobiledevice3/remote/utils.py +14 -13
- pymobiledevice3/remote/xpc_message.py +145 -125
- pymobiledevice3/resources/dsc_uuid_map.py +19 -19
- pymobiledevice3/resources/firmware_notifications.py +16 -16
- pymobiledevice3/restore/asr.py +27 -27
- pymobiledevice3/restore/base_restore.py +90 -47
- pymobiledevice3/restore/consts.py +87 -66
- pymobiledevice3/restore/device.py +11 -11
- pymobiledevice3/restore/fdr.py +46 -46
- pymobiledevice3/restore/ftab.py +19 -19
- pymobiledevice3/restore/img4.py +130 -133
- pymobiledevice3/restore/mbn.py +587 -0
- pymobiledevice3/restore/recovery.py +125 -135
- pymobiledevice3/restore/restore.py +535 -523
- pymobiledevice3/restore/restore_options.py +122 -115
- pymobiledevice3/restore/restored_client.py +25 -22
- pymobiledevice3/restore/tss.py +378 -270
- pymobiledevice3/service_connection.py +50 -46
- pymobiledevice3/services/accessibilityaudit.py +137 -127
- pymobiledevice3/services/afc.py +352 -292
- pymobiledevice3/services/amfi.py +21 -18
- pymobiledevice3/services/companion.py +23 -19
- pymobiledevice3/services/crash_reports.py +61 -47
- pymobiledevice3/services/debugserver_applist.py +3 -3
- pymobiledevice3/services/device_arbitration.py +8 -8
- pymobiledevice3/services/device_link.py +56 -48
- pymobiledevice3/services/diagnostics.py +971 -968
- pymobiledevice3/services/dtfetchsymbols.py +8 -8
- pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
- pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
- pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
- pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
- pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
- pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +466 -384
- pymobiledevice3/services/dvt/instruments/device_info.py +11 -11
- pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
- pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
- pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
- pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
- pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
- pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
- pymobiledevice3/services/dvt/instruments/process_control.py +25 -10
- pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
- pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
- pymobiledevice3/services/dvt/testmanaged/xcuitest.py +42 -52
- pymobiledevice3/services/file_relay.py +10 -10
- pymobiledevice3/services/heartbeat.py +8 -7
- pymobiledevice3/services/house_arrest.py +12 -15
- pymobiledevice3/services/installation_proxy.py +119 -100
- pymobiledevice3/services/lockdown_service.py +12 -5
- pymobiledevice3/services/misagent.py +22 -19
- pymobiledevice3/services/mobile_activation.py +84 -72
- pymobiledevice3/services/mobile_config.py +331 -301
- pymobiledevice3/services/mobile_image_mounter.py +137 -116
- pymobiledevice3/services/mobilebackup2.py +188 -150
- pymobiledevice3/services/notification_proxy.py +11 -11
- pymobiledevice3/services/os_trace.py +128 -74
- pymobiledevice3/services/pcapd.py +306 -306
- pymobiledevice3/services/power_assertion.py +10 -9
- pymobiledevice3/services/preboard.py +4 -4
- pymobiledevice3/services/remote_fetch_symbols.py +16 -14
- pymobiledevice3/services/remote_server.py +176 -146
- pymobiledevice3/services/restore_service.py +16 -16
- pymobiledevice3/services/screenshot.py +13 -10
- pymobiledevice3/services/simulate_location.py +7 -7
- pymobiledevice3/services/springboard.py +15 -15
- pymobiledevice3/services/syslog.py +5 -5
- pymobiledevice3/services/web_protocol/alert.py +3 -3
- pymobiledevice3/services/web_protocol/automation_session.py +183 -179
- pymobiledevice3/services/web_protocol/cdp_screencast.py +44 -36
- pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
- pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
- pymobiledevice3/services/web_protocol/driver.py +47 -45
- pymobiledevice3/services/web_protocol/element.py +74 -63
- pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
- pymobiledevice3/services/web_protocol/selenium_api.py +3 -3
- pymobiledevice3/services/web_protocol/session_protocol.py +15 -10
- pymobiledevice3/services/web_protocol/switch_to.py +11 -12
- pymobiledevice3/services/webinspector.py +142 -116
- pymobiledevice3/tcp_forwarder.py +35 -22
- pymobiledevice3/tunneld/api.py +20 -15
- pymobiledevice3/tunneld/server.py +310 -193
- pymobiledevice3/usbmux.py +197 -148
- pymobiledevice3/utils.py +14 -11
- {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/METADATA +1 -2
- pymobiledevice3-5.1.2.dist-info/RECORD +173 -0
- pymobiledevice3-4.27.4.dist-info/RECORD +0 -172
- {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/WHEEL +0 -0
- {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/licenses/LICENSE +0 -0
- {pymobiledevice3-4.27.4.dist-info → pymobiledevice3-5.1.2.dist-info}/top_level.txt +0 -0
|
@@ -8,9 +8,9 @@ from pymobiledevice3.lockdown import LockdownClient
|
|
|
8
8
|
from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider
|
|
9
9
|
from pymobiledevice3.services.springboard import SpringBoardServicesService
|
|
10
10
|
|
|
11
|
-
SHELL_USAGE =
|
|
11
|
+
SHELL_USAGE = """
|
|
12
12
|
Use `service` to access the service features
|
|
13
|
-
|
|
13
|
+
"""
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
@click.group()
|
|
@@ -20,69 +20,71 @@ def cli():
|
|
|
20
20
|
|
|
21
21
|
@cli.group()
|
|
22
22
|
def springboard():
|
|
23
|
-
"""
|
|
23
|
+
"""Access device UI"""
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@springboard.group()
|
|
28
28
|
def state():
|
|
29
|
-
"""
|
|
29
|
+
"""icons state options"""
|
|
30
30
|
pass
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
@state.command(
|
|
33
|
+
@state.command("get", cls=Command)
|
|
34
34
|
def state_get(service_provider: LockdownClient):
|
|
35
|
-
"""
|
|
35
|
+
"""get icon state"""
|
|
36
36
|
print_json(SpringBoardServicesService(lockdown=service_provider).get_icon_state())
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
@springboard.command(
|
|
39
|
+
@springboard.command("shell", cls=Command)
|
|
40
40
|
def springboard_shell(service_provider: LockdownClient):
|
|
41
|
-
"""
|
|
41
|
+
"""open a shell to communicate with SpringBoardServicesService"""
|
|
42
42
|
service = SpringBoardServicesService(lockdown=service_provider)
|
|
43
43
|
IPython.embed(
|
|
44
44
|
header=SHELL_USAGE,
|
|
45
45
|
user_ns={
|
|
46
|
-
|
|
47
|
-
}
|
|
46
|
+
"service": service,
|
|
47
|
+
},
|
|
48
|
+
)
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
@springboard.command(
|
|
51
|
-
@click.argument(
|
|
52
|
-
@click.argument(
|
|
51
|
+
@springboard.command("icon", cls=Command)
|
|
52
|
+
@click.argument("bundle_id")
|
|
53
|
+
@click.argument("out", type=click.File("wb"))
|
|
53
54
|
def springboard_icon(service_provider: LockdownClient, bundle_id, out):
|
|
54
|
-
"""
|
|
55
|
+
"""get application's icon"""
|
|
55
56
|
out.write(SpringBoardServicesService(lockdown=service_provider).get_icon_pngdata(bundle_id))
|
|
56
57
|
|
|
57
58
|
|
|
58
|
-
@springboard.command(
|
|
59
|
+
@springboard.command("orientation", cls=Command)
|
|
59
60
|
def springboard_orientation(service_provider: LockdownClient):
|
|
60
|
-
"""
|
|
61
|
+
"""get screen orientation"""
|
|
61
62
|
print(SpringBoardServicesService(lockdown=service_provider).get_interface_orientation())
|
|
62
63
|
|
|
63
64
|
|
|
64
|
-
@springboard.command(
|
|
65
|
-
@click.argument(
|
|
65
|
+
@springboard.command("wallpaper-home-screen", cls=Command)
|
|
66
|
+
@click.argument("out", type=click.File("wb"))
|
|
66
67
|
def springboard_wallpaper_home_screen(service_provider: LockdownClient, out: IO) -> None:
|
|
67
|
-
"""
|
|
68
|
+
"""get homescreen wallpaper"""
|
|
68
69
|
out.write(SpringBoardServicesService(lockdown=service_provider).get_wallpaper_pngdata())
|
|
69
70
|
|
|
70
71
|
|
|
71
|
-
@springboard.command(
|
|
72
|
-
@click.argument(
|
|
73
|
-
@click.argument(
|
|
74
|
-
@click.option(
|
|
75
|
-
def springboard_wallpaper_preview_image(
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
@springboard.command("wallpaper-preview-image", cls=Command)
|
|
73
|
+
@click.argument("wallpaper-name", type=click.Choice(["homescreen", "lockscreen"]))
|
|
74
|
+
@click.argument("out", type=click.File("wb"))
|
|
75
|
+
@click.option("-r", "--reload", is_flag=True, help="reload icon state before fetching image")
|
|
76
|
+
def springboard_wallpaper_preview_image(
|
|
77
|
+
service_provider: LockdownClient, wallpaper_name: str, out: IO, reload: bool
|
|
78
|
+
) -> None:
|
|
79
|
+
"""get the preview image of either the homescreen or the lockscreen"""
|
|
78
80
|
with SpringBoardServicesService(lockdown=service_provider) as springboard_service:
|
|
79
81
|
if reload:
|
|
80
82
|
springboard_service.reload_icon_state()
|
|
81
83
|
out.write(springboard_service.get_wallpaper_preview_image(wallpaper_name))
|
|
82
84
|
|
|
83
85
|
|
|
84
|
-
@springboard.command(
|
|
86
|
+
@springboard.command("homescreen-icon-metrics", cls=Command)
|
|
85
87
|
def springboard_homescreen_icon_metrics(service_provider: LockdownServiceProvider) -> None:
|
|
86
|
-
"""
|
|
88
|
+
"""Get homescreen icon metrics"""
|
|
87
89
|
with SpringBoardServicesService(lockdown=service_provider) as springboard_service:
|
|
88
90
|
print_json(springboard_service.get_homescreen_icon_metrics())
|
pymobiledevice3/cli/syslog.py
CHANGED
|
@@ -22,25 +22,25 @@ def cli() -> None:
|
|
|
22
22
|
|
|
23
23
|
@cli.group()
|
|
24
24
|
def syslog() -> None:
|
|
25
|
-
"""
|
|
25
|
+
"""Watch syslog messages"""
|
|
26
26
|
pass
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
@syslog.command(
|
|
29
|
+
@syslog.command("live-old", cls=Command)
|
|
30
30
|
def syslog_live_old(service_provider: LockdownClient):
|
|
31
|
-
"""
|
|
31
|
+
"""view live syslog lines in raw bytes form from old relay"""
|
|
32
32
|
for line in SyslogService(service_provider=service_provider).watch():
|
|
33
33
|
print(line)
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def format_line(color, pid, syslog_entry, include_label):
|
|
37
37
|
log_level_colors = {
|
|
38
|
-
SyslogLogLevel.NOTICE.name:
|
|
39
|
-
SyslogLogLevel.INFO.name:
|
|
40
|
-
SyslogLogLevel.DEBUG.name:
|
|
41
|
-
SyslogLogLevel.ERROR.name:
|
|
42
|
-
SyslogLogLevel.FAULT.name:
|
|
43
|
-
SyslogLogLevel.USER_ACTION.name:
|
|
38
|
+
SyslogLogLevel.NOTICE.name: "white",
|
|
39
|
+
SyslogLogLevel.INFO.name: "white",
|
|
40
|
+
SyslogLogLevel.DEBUG.name: "green",
|
|
41
|
+
SyslogLogLevel.ERROR.name: "red",
|
|
42
|
+
SyslogLogLevel.FAULT.name: "red",
|
|
43
|
+
SyslogLogLevel.USER_ACTION.name: "white",
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
syslog_pid = syslog_entry.pid
|
|
@@ -50,42 +50,55 @@ def format_line(color, pid, syslog_entry, include_label):
|
|
|
50
50
|
image_name = posixpath.basename(syslog_entry.image_name)
|
|
51
51
|
message = syslog_entry.message
|
|
52
52
|
process_name = posixpath.basename(filename)
|
|
53
|
-
label =
|
|
53
|
+
label = ""
|
|
54
54
|
|
|
55
55
|
if (pid != -1) and (syslog_pid != pid):
|
|
56
56
|
return None
|
|
57
57
|
|
|
58
58
|
if syslog_entry.label is not None:
|
|
59
|
-
label = f
|
|
59
|
+
label = f"[{syslog_entry.label.subsystem}][{syslog_entry.label.category}]"
|
|
60
60
|
|
|
61
61
|
if color:
|
|
62
|
-
timestamp = click.style(str(timestamp),
|
|
63
|
-
process_name = click.style(process_name,
|
|
62
|
+
timestamp = click.style(str(timestamp), "green")
|
|
63
|
+
process_name = click.style(process_name, "magenta")
|
|
64
64
|
if len(image_name) > 0:
|
|
65
|
-
image_name = click.style(image_name,
|
|
66
|
-
syslog_pid = click.style(syslog_pid,
|
|
65
|
+
image_name = click.style(image_name, "magenta")
|
|
66
|
+
syslog_pid = click.style(syslog_pid, "cyan")
|
|
67
67
|
log_level_color = log_level_colors[level]
|
|
68
68
|
level = click.style(level, log_level_color)
|
|
69
|
-
label = click.style(label,
|
|
69
|
+
label = click.style(label, "cyan")
|
|
70
70
|
message = click.style(message, log_level_color)
|
|
71
71
|
|
|
72
|
-
line_format =
|
|
72
|
+
line_format = "{timestamp} {process_name}{{{image_name}}}[{pid}] <{level}>: {message}"
|
|
73
73
|
|
|
74
74
|
if include_label:
|
|
75
|
-
line_format += f
|
|
75
|
+
line_format += f" {label}"
|
|
76
76
|
|
|
77
|
-
line = line_format.format(
|
|
78
|
-
|
|
77
|
+
line = line_format.format(
|
|
78
|
+
timestamp=timestamp,
|
|
79
|
+
process_name=process_name,
|
|
80
|
+
image_name=image_name,
|
|
81
|
+
pid=syslog_pid,
|
|
82
|
+
level=level,
|
|
83
|
+
message=message,
|
|
84
|
+
)
|
|
79
85
|
|
|
80
86
|
return line
|
|
81
87
|
|
|
82
88
|
|
|
83
89
|
def syslog_live(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
service_provider: LockdownServiceProvider,
|
|
91
|
+
out: Optional[TextIO],
|
|
92
|
+
pid: Optional[int],
|
|
93
|
+
process_name: Optional[str],
|
|
94
|
+
match: list[str],
|
|
95
|
+
match_insensitive: list[str],
|
|
96
|
+
include_label: bool,
|
|
97
|
+
regex: list[str],
|
|
98
|
+
insensitive_regex: list[str],
|
|
99
|
+
) -> None:
|
|
100
|
+
match_regex = [re.compile(f".*({r}).*", re.DOTALL) for r in regex]
|
|
101
|
+
match_regex += [re.compile(f".*({r}).*", re.IGNORECASE | re.DOTALL) for r in insensitive_regex]
|
|
89
102
|
|
|
90
103
|
def replace(m):
|
|
91
104
|
if len(m.groups()):
|
|
@@ -93,9 +106,8 @@ def syslog_live(
|
|
|
93
106
|
return None
|
|
94
107
|
|
|
95
108
|
for syslog_entry in OsTraceService(lockdown=service_provider).syslog(pid=pid):
|
|
96
|
-
if process_name:
|
|
97
|
-
|
|
98
|
-
continue
|
|
109
|
+
if process_name and posixpath.basename(syslog_entry.filename) != process_name:
|
|
110
|
+
continue
|
|
99
111
|
|
|
100
112
|
line_no_style = format_line(False, pid, syslog_entry, include_label)
|
|
101
113
|
line = format_line(user_requested_colored_output(), pid, syslog_entry, include_label)
|
|
@@ -124,8 +136,12 @@ def syslog_live(
|
|
|
124
136
|
start = line.lower().index(m)
|
|
125
137
|
end = start + len(m)
|
|
126
138
|
last_color_formatting = get_last_used_terminal_formatting(line[:start])
|
|
127
|
-
line =
|
|
128
|
-
|
|
139
|
+
line = (
|
|
140
|
+
line[:start]
|
|
141
|
+
+ click.style(line[start:end], bold=True, underline=True)
|
|
142
|
+
+ last_color_formatting
|
|
143
|
+
+ line[end:]
|
|
144
|
+
)
|
|
129
145
|
|
|
130
146
|
if match_regex:
|
|
131
147
|
skip = True
|
|
@@ -147,30 +163,38 @@ def syslog_live(
|
|
|
147
163
|
print(line_no_style, file=out, flush=True)
|
|
148
164
|
|
|
149
165
|
|
|
150
|
-
@syslog.command(
|
|
151
|
-
@click.option(
|
|
152
|
-
@click.option(
|
|
153
|
-
@click.option(
|
|
154
|
-
@click.option(
|
|
155
|
-
@click.option(
|
|
156
|
-
@click.option(
|
|
157
|
-
@click.option(
|
|
158
|
-
@click.option(
|
|
166
|
+
@syslog.command("live", cls=Command)
|
|
167
|
+
@click.option("-o", "--out", type=click.File("wt"), help="log file")
|
|
168
|
+
@click.option("--pid", type=click.INT, default=-1, help="pid to filter. -1 for all")
|
|
169
|
+
@click.option("-pn", "--process-name", help="process name to filter")
|
|
170
|
+
@click.option("-m", "--match", multiple=True, help="match expression")
|
|
171
|
+
@click.option("-mi", "--match-insensitive", multiple=True, help="insensitive match expression")
|
|
172
|
+
@click.option("include_label", "--label", is_flag=True, help="should include label")
|
|
173
|
+
@click.option("-e", "--regex", multiple=True, help="filter only lines matching given regex")
|
|
174
|
+
@click.option("-ei", "--insensitive-regex", multiple=True, help="filter only lines matching given regex (insensitive)")
|
|
159
175
|
def cli_syslog_live(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
service_provider: LockdownServiceProvider,
|
|
177
|
+
out: Optional[TextIO],
|
|
178
|
+
pid: Optional[int],
|
|
179
|
+
process_name: Optional[str],
|
|
180
|
+
match: list[str],
|
|
181
|
+
match_insensitive: list[str],
|
|
182
|
+
include_label: bool,
|
|
183
|
+
regex: list[str],
|
|
184
|
+
insensitive_regex: list[str],
|
|
185
|
+
) -> None:
|
|
186
|
+
"""view live syslog lines"""
|
|
187
|
+
|
|
188
|
+
syslog_live(
|
|
189
|
+
service_provider, out, pid, process_name, match, match_insensitive, include_label, regex, insensitive_regex
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@syslog.command("collect", cls=Command)
|
|
194
|
+
@click.argument("out", type=click.Path(exists=False, dir_okay=True, file_okay=False))
|
|
195
|
+
@click.option("--size-limit", type=click.INT)
|
|
196
|
+
@click.option("--age-limit", type=click.INT)
|
|
197
|
+
@click.option("--start-time", type=click.INT)
|
|
174
198
|
def syslog_collect(service_provider: LockdownClient, out, size_limit, age_limit, start_time):
|
|
175
199
|
"""
|
|
176
200
|
Collect the system logs into a .logarchive that can be viewed later with tools such as log or Console.
|
|
@@ -179,9 +203,12 @@ def syslog_collect(service_provider: LockdownClient, out, size_limit, age_limit,
|
|
|
179
203
|
if not os.path.exists(out):
|
|
180
204
|
os.makedirs(out)
|
|
181
205
|
|
|
182
|
-
if not out.endswith(
|
|
183
|
-
logger.warning(
|
|
184
|
-
|
|
206
|
+
if not out.endswith(".logarchive"):
|
|
207
|
+
logger.warning(
|
|
208
|
+
"given out path doesn't end with a .logarchive - consider renaming to be able to view "
|
|
209
|
+
"the file with the likes of the Console.app and the `log show` utilities"
|
|
210
|
+
)
|
|
185
211
|
|
|
186
|
-
OsTraceService(lockdown=service_provider).collect(
|
|
187
|
-
|
|
212
|
+
OsTraceService(lockdown=service_provider).collect(
|
|
213
|
+
out, size_limit=size_limit, age_limit=age_limit, start_time=start_time
|
|
214
|
+
)
|
pymobiledevice3/cli/usbmux.py
CHANGED
|
@@ -16,41 +16,41 @@ def cli() -> None:
|
|
|
16
16
|
pass
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
@cli.group(
|
|
19
|
+
@cli.group("usbmux")
|
|
20
20
|
def usbmux_cli() -> None:
|
|
21
|
-
"""
|
|
21
|
+
"""List devices or forward a TCP port"""
|
|
22
22
|
pass
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
@usbmux_cli.command(
|
|
26
|
-
@click.option(
|
|
27
|
-
@click.argument(
|
|
28
|
-
@click.argument(
|
|
29
|
-
@click.option(
|
|
30
|
-
@click.option(
|
|
25
|
+
@usbmux_cli.command("forward", cls=BaseCommand)
|
|
26
|
+
@click.option("usbmux_address", "--usbmux", help=USBMUX_OPTION_HELP)
|
|
27
|
+
@click.argument("src_port", type=click.IntRange(1, 0xFFFF))
|
|
28
|
+
@click.argument("dst_port", type=click.IntRange(1, 0xFFFF))
|
|
29
|
+
@click.option("--serial", help="device serial number")
|
|
30
|
+
@click.option("-d", "--daemonize", is_flag=True)
|
|
31
31
|
def usbmux_forward(usbmux_address: str, src_port: int, dst_port: int, serial: str, daemonize: bool):
|
|
32
|
-
"""
|
|
32
|
+
"""forward tcp port"""
|
|
33
33
|
forwarder = UsbmuxTcpForwarder(serial, dst_port, src_port, usbmux_address=usbmux_address)
|
|
34
34
|
|
|
35
35
|
if daemonize:
|
|
36
36
|
try:
|
|
37
37
|
from daemonize import Daemonize
|
|
38
|
-
except ImportError:
|
|
39
|
-
raise NotImplementedError(
|
|
38
|
+
except ImportError as e:
|
|
39
|
+
raise NotImplementedError("daemonizing is only supported on unix platforms") from e
|
|
40
40
|
|
|
41
|
-
with tempfile.NamedTemporaryFile(
|
|
42
|
-
daemon = Daemonize(app=f
|
|
41
|
+
with tempfile.NamedTemporaryFile("wt") as pid_file:
|
|
42
|
+
daemon = Daemonize(app=f"forwarder {src_port}->{dst_port}", pid=pid_file.name, action=forwarder.start)
|
|
43
43
|
daemon.start()
|
|
44
44
|
else:
|
|
45
45
|
forwarder.start()
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
@usbmux_cli.command(
|
|
49
|
-
@click.option(
|
|
50
|
-
@click.option(
|
|
51
|
-
@click.option(
|
|
48
|
+
@usbmux_cli.command("list", cls=BaseCommand)
|
|
49
|
+
@click.option("usbmux_address", "--usbmux", help=USBMUX_OPTION_HELP)
|
|
50
|
+
@click.option("-u", "--usb", is_flag=True, help="show only usb devices")
|
|
51
|
+
@click.option("-n", "--network", is_flag=True, help="show only network devices")
|
|
52
52
|
def usbmux_list(usbmux_address: str, usb: bool, network: bool) -> None:
|
|
53
|
-
"""
|
|
53
|
+
"""list connected devices"""
|
|
54
54
|
connected_devices = []
|
|
55
55
|
for device in usbmux.list_devices(usbmux_address=usbmux_address):
|
|
56
56
|
udid = device.serial
|
|
@@ -61,8 +61,9 @@ def usbmux_list(usbmux_address: str, usb: bool, network: bool) -> None:
|
|
|
61
61
|
if network and not device.is_network:
|
|
62
62
|
continue
|
|
63
63
|
|
|
64
|
-
lockdown = create_using_usbmux(
|
|
65
|
-
|
|
64
|
+
lockdown = create_using_usbmux(
|
|
65
|
+
udid, autopair=False, connection_type=device.connection_type, usbmux_address=usbmux_address
|
|
66
|
+
)
|
|
66
67
|
connected_devices.append(lockdown.short_info)
|
|
67
68
|
|
|
68
69
|
print_json(connected_devices)
|
pymobiledevice3/cli/version.py
CHANGED
|
@@ -8,9 +8,10 @@ def cli() -> None:
|
|
|
8
8
|
|
|
9
9
|
@cli.command()
|
|
10
10
|
def version() -> None:
|
|
11
|
-
"""
|
|
11
|
+
"""Query pymobiledevice3 version"""
|
|
12
12
|
try:
|
|
13
13
|
from pymobiledevice3._version import __version__
|
|
14
|
+
|
|
14
15
|
print(__version__)
|
|
15
16
|
except ImportError:
|
|
16
|
-
print(
|
|
17
|
+
print("version could not be determined. please first install/build the package")
|