pymobiledevice3 4.14.6__py3-none-any.whl → 7.0.6__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
- misc/understanding_idevice_protocol_layers.md +15 -10
- pymobiledevice3/__main__.py +317 -127
- pymobiledevice3/_version.py +22 -4
- pymobiledevice3/bonjour.py +358 -113
- pymobiledevice3/ca.py +253 -16
- pymobiledevice3/cli/activation.py +31 -23
- pymobiledevice3/cli/afc.py +49 -40
- pymobiledevice3/cli/amfi.py +16 -21
- pymobiledevice3/cli/apps.py +87 -42
- pymobiledevice3/cli/backup.py +160 -90
- pymobiledevice3/cli/bonjour.py +44 -40
- pymobiledevice3/cli/cli_common.py +204 -198
- pymobiledevice3/cli/companion_proxy.py +14 -14
- pymobiledevice3/cli/crash.py +105 -56
- pymobiledevice3/cli/developer/__init__.py +62 -0
- pymobiledevice3/cli/developer/accessibility/__init__.py +65 -0
- pymobiledevice3/cli/developer/accessibility/settings.py +43 -0
- pymobiledevice3/cli/developer/arbitration.py +50 -0
- pymobiledevice3/cli/developer/condition.py +33 -0
- pymobiledevice3/cli/developer/core_device.py +294 -0
- pymobiledevice3/cli/developer/debugserver.py +244 -0
- pymobiledevice3/cli/developer/dvt/__init__.py +438 -0
- pymobiledevice3/cli/developer/dvt/core_profile_session.py +295 -0
- pymobiledevice3/cli/developer/dvt/simulate_location.py +56 -0
- pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +69 -0
- pymobiledevice3/cli/developer/dvt/sysmon/process.py +188 -0
- pymobiledevice3/cli/developer/fetch_symbols.py +108 -0
- pymobiledevice3/cli/developer/simulate_location.py +51 -0
- pymobiledevice3/cli/diagnostics/__init__.py +75 -0
- pymobiledevice3/cli/diagnostics/battery.py +47 -0
- pymobiledevice3/cli/idam.py +42 -0
- pymobiledevice3/cli/lockdown.py +108 -103
- pymobiledevice3/cli/mounter.py +158 -99
- pymobiledevice3/cli/notification.py +38 -26
- pymobiledevice3/cli/pcap.py +45 -24
- pymobiledevice3/cli/power_assertion.py +18 -17
- pymobiledevice3/cli/processes.py +17 -23
- pymobiledevice3/cli/profile.py +165 -109
- pymobiledevice3/cli/provision.py +35 -34
- pymobiledevice3/cli/remote.py +217 -129
- pymobiledevice3/cli/restore.py +159 -143
- pymobiledevice3/cli/springboard.py +63 -53
- pymobiledevice3/cli/syslog.py +193 -86
- pymobiledevice3/cli/usbmux.py +73 -33
- pymobiledevice3/cli/version.py +5 -7
- pymobiledevice3/cli/webinspector.py +376 -214
- pymobiledevice3/common.py +3 -1
- pymobiledevice3/exceptions.py +182 -58
- pymobiledevice3/irecv.py +52 -53
- pymobiledevice3/irecv_devices.py +1489 -464
- pymobiledevice3/lockdown.py +473 -275
- pymobiledevice3/lockdown_service_provider.py +15 -8
- pymobiledevice3/osu/os_utils.py +27 -9
- pymobiledevice3/osu/posix_util.py +34 -15
- pymobiledevice3/osu/win_util.py +14 -8
- pymobiledevice3/pair_records.py +102 -21
- pymobiledevice3/remote/common.py +8 -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 +19 -4
- pymobiledevice3/remote/core_device/file_service.py +53 -23
- pymobiledevice3/remote/remote_service_discovery.py +79 -45
- pymobiledevice3/remote/remotexpc.py +73 -44
- pymobiledevice3/remote/tunnel_service.py +442 -317
- 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 +20 -16
- pymobiledevice3/resources/notifications.txt +144 -0
- pymobiledevice3/restore/asr.py +27 -27
- pymobiledevice3/restore/base_restore.py +110 -21
- pymobiledevice3/restore/consts.py +87 -66
- pymobiledevice3/restore/device.py +59 -12
- pymobiledevice3/restore/fdr.py +46 -48
- pymobiledevice3/restore/ftab.py +19 -19
- pymobiledevice3/restore/img4.py +163 -0
- pymobiledevice3/restore/mbn.py +587 -0
- pymobiledevice3/restore/recovery.py +151 -151
- pymobiledevice3/restore/restore.py +562 -544
- pymobiledevice3/restore/restore_options.py +131 -110
- pymobiledevice3/restore/restored_client.py +51 -31
- pymobiledevice3/restore/tss.py +385 -267
- pymobiledevice3/service_connection.py +252 -59
- pymobiledevice3/services/accessibilityaudit.py +202 -120
- pymobiledevice3/services/afc.py +962 -365
- pymobiledevice3/services/amfi.py +24 -30
- pymobiledevice3/services/companion.py +23 -19
- pymobiledevice3/services/crash_reports.py +71 -47
- pymobiledevice3/services/debugserver_applist.py +3 -3
- pymobiledevice3/services/device_arbitration.py +8 -8
- pymobiledevice3/services/device_link.py +101 -79
- pymobiledevice3/services/diagnostics.py +973 -967
- 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 +20 -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 +35 -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 +9 -8
- pymobiledevice3/services/house_arrest.py +16 -15
- pymobiledevice3/services/idam.py +20 -0
- pymobiledevice3/services/installation_proxy.py +173 -81
- pymobiledevice3/services/lockdown_service.py +20 -10
- pymobiledevice3/services/misagent.py +22 -19
- pymobiledevice3/services/mobile_activation.py +147 -64
- pymobiledevice3/services/mobile_config.py +331 -294
- pymobiledevice3/services/mobile_image_mounter.py +141 -113
- pymobiledevice3/services/mobilebackup2.py +203 -145
- pymobiledevice3/services/notification_proxy.py +11 -11
- pymobiledevice3/services/os_trace.py +134 -74
- pymobiledevice3/services/pcapd.py +314 -302
- pymobiledevice3/services/power_assertion.py +10 -9
- pymobiledevice3/services/preboard.py +4 -4
- pymobiledevice3/services/remote_fetch_symbols.py +21 -14
- pymobiledevice3/services/remote_server.py +176 -146
- pymobiledevice3/services/restore_service.py +16 -16
- pymobiledevice3/services/screenshot.py +15 -12
- 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 +11 -11
- pymobiledevice3/services/web_protocol/automation_session.py +251 -239
- pymobiledevice3/services/web_protocol/cdp_screencast.py +46 -37
- pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
- pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
- pymobiledevice3/services/web_protocol/driver.py +114 -111
- pymobiledevice3/services/web_protocol/element.py +124 -111
- pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
- pymobiledevice3/services/web_protocol/selenium_api.py +49 -49
- pymobiledevice3/services/web_protocol/session_protocol.py +18 -12
- pymobiledevice3/services/web_protocol/switch_to.py +30 -27
- pymobiledevice3/services/webinspector.py +189 -155
- pymobiledevice3/tcp_forwarder.py +87 -69
- pymobiledevice3/tunneld/__init__.py +0 -0
- pymobiledevice3/tunneld/api.py +63 -0
- pymobiledevice3/tunneld/server.py +603 -0
- pymobiledevice3/usbmux.py +198 -147
- pymobiledevice3/utils.py +14 -11
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/METADATA +55 -28
- pymobiledevice3-7.0.6.dist-info/RECORD +188 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/WHEEL +1 -1
- pymobiledevice3/cli/developer.py +0 -1215
- pymobiledevice3/cli/diagnostics.py +0 -99
- pymobiledevice3/tunneld.py +0 -524
- pymobiledevice3-4.14.6.dist-info/RECORD +0 -168
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info/licenses}/LICENSE +0 -0
- {pymobiledevice3-4.14.6.dist-info → pymobiledevice3-7.0.6.dist-info}/top_level.txt +0 -0
|
@@ -3,17 +3,20 @@ import datetime
|
|
|
3
3
|
import shutil
|
|
4
4
|
import struct
|
|
5
5
|
import warnings
|
|
6
|
+
from collections.abc import Iterable, Mapping, Sequence
|
|
6
7
|
from pathlib import Path
|
|
8
|
+
from typing import Any, Callable, Optional, cast
|
|
7
9
|
|
|
8
10
|
from pymobiledevice3.exceptions import NotEnoughDiskSpaceError, PyMobileDevice3Exception
|
|
11
|
+
from pymobiledevice3.service_connection import ServiceConnection
|
|
9
12
|
|
|
10
|
-
SIZE_FORMAT =
|
|
11
|
-
CODE_FORMAT =
|
|
12
|
-
CODE_FILE_DATA =
|
|
13
|
-
CODE_ERROR_REMOTE =
|
|
13
|
+
SIZE_FORMAT = ">I"
|
|
14
|
+
CODE_FORMAT = ">B"
|
|
15
|
+
CODE_FILE_DATA = 0xC
|
|
16
|
+
CODE_ERROR_REMOTE = 0xB
|
|
14
17
|
CODE_ERROR_LOCAL = 0x6
|
|
15
18
|
CODE_SUCCESS = 0
|
|
16
|
-
FILE_TRANSFER_TERMINATOR = b
|
|
19
|
+
FILE_TRANSFER_TERMINATOR = b"\x00\x00\x00\x00"
|
|
17
20
|
BULK_OPERATION_ERROR = -13
|
|
18
21
|
APPLE_EPOCH = 978307200
|
|
19
22
|
ERRNO_TO_DEVICE_ERROR = {
|
|
@@ -26,55 +29,70 @@ ERRNO_TO_DEVICE_ERROR = {
|
|
|
26
29
|
28: -15,
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
DLMessage = Sequence[Any]
|
|
33
|
+
ProgressCallback = Callable[[Any], None]
|
|
34
|
+
DLHandler = Callable[[DLMessage], None]
|
|
35
|
+
|
|
29
36
|
|
|
30
37
|
class DeviceLink:
|
|
31
|
-
def __init__(self, service, root_path: Path):
|
|
32
|
-
self.service = service
|
|
33
|
-
self.root_path = root_path
|
|
34
|
-
self._dl_handlers = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
def __init__(self, service: ServiceConnection, root_path: Path) -> None:
|
|
39
|
+
self.service: ServiceConnection = service
|
|
40
|
+
self.root_path: Path = root_path
|
|
41
|
+
self._dl_handlers: dict[str, DLHandler] = {
|
|
42
|
+
"DLMessageCreateDirectory": self.create_directory,
|
|
43
|
+
"DLMessageUploadFiles": self.upload_files,
|
|
44
|
+
"DLMessageGetFreeDiskSpace": self.get_free_disk_space,
|
|
45
|
+
"DLMessageMoveItems": self.move_items,
|
|
46
|
+
"DLMessageRemoveItems": self.remove_items,
|
|
47
|
+
"DLMessageDownloadFiles": self.download_files,
|
|
48
|
+
"DLContentsOfDirectory": self.contents_of_directory,
|
|
49
|
+
"DLMessageCopyItem": self.copy_item,
|
|
50
|
+
"DLMessagePurgeDiskSpace": self.purge_disk_space,
|
|
44
51
|
}
|
|
45
52
|
|
|
46
|
-
def dl_loop(self, progress_callback=
|
|
53
|
+
def dl_loop(self, progress_callback: Optional[ProgressCallback] = None) -> Any:
|
|
54
|
+
def _noop(_: Any) -> None:
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
callback: ProgressCallback = progress_callback if progress_callback is not None else _noop
|
|
58
|
+
|
|
47
59
|
while True:
|
|
48
60
|
message = self.receive_message()
|
|
49
61
|
command = message[0]
|
|
50
62
|
|
|
51
|
-
if command in (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
if command in (
|
|
64
|
+
"DLMessageDownloadFiles",
|
|
65
|
+
"DLMessageMoveFiles",
|
|
66
|
+
"DLMessageMoveItems",
|
|
67
|
+
"DLMessageRemoveFiles",
|
|
68
|
+
"DLMessageRemoveItems",
|
|
69
|
+
):
|
|
70
|
+
callback(message[3])
|
|
71
|
+
elif command == "DLMessageUploadFiles":
|
|
72
|
+
callback(message[2])
|
|
73
|
+
|
|
74
|
+
if command == "DLMessageProcessMessage":
|
|
75
|
+
if not message[1]["ErrorCode"]:
|
|
76
|
+
return message[1].get("Content")
|
|
60
77
|
else:
|
|
61
|
-
raise PyMobileDevice3Exception(f
|
|
78
|
+
raise PyMobileDevice3Exception(f"Device link error: {message[1]}")
|
|
62
79
|
self._dl_handlers[command](message)
|
|
63
80
|
|
|
64
|
-
def version_exchange(self):
|
|
81
|
+
def version_exchange(self) -> None:
|
|
65
82
|
dl_message_version_exchange = self.receive_message()
|
|
66
83
|
version_major = dl_message_version_exchange[1]
|
|
67
|
-
self.service.send_plist([
|
|
84
|
+
self.service.send_plist(["DLMessageVersionExchange", "DLVersionsOk", version_major])
|
|
68
85
|
dl_message_device_ready = self.receive_message()
|
|
69
|
-
if dl_message_device_ready[0] !=
|
|
70
|
-
raise PyMobileDevice3Exception(
|
|
86
|
+
if dl_message_device_ready[0] != "DLMessageDeviceReady":
|
|
87
|
+
raise PyMobileDevice3Exception("Device link didn't return ready state")
|
|
71
88
|
|
|
72
|
-
def send_process_message(self, message):
|
|
73
|
-
self.service.send_plist([
|
|
89
|
+
def send_process_message(self, message: Mapping[str, Any]) -> None:
|
|
90
|
+
self.service.send_plist(["DLMessageProcessMessage", message])
|
|
74
91
|
|
|
75
|
-
def download_files(self, message):
|
|
76
|
-
status = {}
|
|
77
|
-
|
|
92
|
+
def download_files(self, message: DLMessage) -> None:
|
|
93
|
+
status: dict[str, dict[str, Any]] = {}
|
|
94
|
+
files = cast(Iterable[str], message[1])
|
|
95
|
+
for file in files:
|
|
78
96
|
self.service.sendall(struct.pack(SIZE_FORMAT, len(file)))
|
|
79
97
|
self.service.sendall(file.encode())
|
|
80
98
|
|
|
@@ -85,7 +103,7 @@ class DeviceLink:
|
|
|
85
103
|
# https://github.com/doronz88/pymobiledevice3/issues/1165#issuecomment-2376815692
|
|
86
104
|
chunk_size = 128 * 1024 * 1024 # 128 MB
|
|
87
105
|
|
|
88
|
-
with file_path.open(
|
|
106
|
+
with file_path.open("rb") as file_handle:
|
|
89
107
|
while True:
|
|
90
108
|
chunk_data = file_handle.read(chunk_size)
|
|
91
109
|
if not chunk_data:
|
|
@@ -95,76 +113,79 @@ class DeviceLink:
|
|
|
95
113
|
|
|
96
114
|
buffer = struct.pack(SIZE_FORMAT, struct.calcsize(CODE_FORMAT)) + struct.pack(CODE_FORMAT, CODE_SUCCESS)
|
|
97
115
|
self.service.sendall(buffer)
|
|
98
|
-
except
|
|
116
|
+
except OSError as e:
|
|
99
117
|
status[file] = {
|
|
100
|
-
|
|
101
|
-
|
|
118
|
+
"DLFileErrorString": e.strerror,
|
|
119
|
+
"DLFileErrorCode": ctypes.c_uint64(ERRNO_TO_DEVICE_ERROR[e.errno]).value,
|
|
102
120
|
}
|
|
103
121
|
self.service.sendall(struct.pack(SIZE_FORMAT, len(e.strerror) + struct.calcsize(CODE_FORMAT)))
|
|
104
122
|
self.service.sendall(struct.pack(CODE_FORMAT, CODE_ERROR_LOCAL) + e.strerror.encode())
|
|
105
123
|
|
|
106
124
|
self.service.sendall(FILE_TRANSFER_TERMINATOR)
|
|
107
125
|
if status:
|
|
108
|
-
self.status_response(BULK_OPERATION_ERROR,
|
|
126
|
+
self.status_response(BULK_OPERATION_ERROR, "Multi status", status)
|
|
109
127
|
else:
|
|
110
128
|
self.status_response(0)
|
|
111
129
|
|
|
112
|
-
def contents_of_directory(self, message):
|
|
130
|
+
def contents_of_directory(self, message: DLMessage) -> None:
|
|
113
131
|
data = {}
|
|
114
|
-
path = self.root_path / message[1]
|
|
132
|
+
path = self.root_path / cast(str, message[1])
|
|
115
133
|
for file in path.iterdir():
|
|
116
|
-
ftype =
|
|
134
|
+
ftype = "DLFileTypeUnknown"
|
|
117
135
|
if file.is_dir():
|
|
118
|
-
ftype =
|
|
136
|
+
ftype = "DLFileTypeDirectory"
|
|
119
137
|
if file.is_file():
|
|
120
|
-
ftype =
|
|
138
|
+
ftype = "DLFileTypeRegular"
|
|
121
139
|
modifications_data = datetime.datetime.fromtimestamp(file.stat().st_mtime - APPLE_EPOCH)
|
|
122
140
|
modifications_data = modifications_data.replace(tzinfo=None)
|
|
123
141
|
data[file.name] = {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
142
|
+
"DLFileType": ftype,
|
|
143
|
+
"DLFileSize": file.stat().st_size,
|
|
144
|
+
"DLFileModificationDate": modifications_data,
|
|
127
145
|
}
|
|
128
146
|
self.status_response(0, status_dict=data)
|
|
129
147
|
|
|
130
|
-
def upload_files(self,
|
|
148
|
+
def upload_files(self, _message: DLMessage) -> None:
|
|
131
149
|
while True:
|
|
132
150
|
device_name = self._prefixed_recv()
|
|
133
151
|
if not device_name:
|
|
134
152
|
break
|
|
135
153
|
file_name = self._prefixed_recv()
|
|
136
|
-
size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
137
|
-
code, = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
|
|
154
|
+
(size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
155
|
+
(code,) = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
|
|
138
156
|
size -= struct.calcsize(CODE_FORMAT)
|
|
139
|
-
with open(self.root_path / file_name,
|
|
157
|
+
with open(self.root_path / file_name, "wb") as fd:
|
|
140
158
|
while size and code == CODE_FILE_DATA:
|
|
141
159
|
fd.write(self.service.recvall(size))
|
|
142
|
-
size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
143
|
-
code, = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
|
|
160
|
+
(size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
161
|
+
(code,) = struct.unpack(CODE_FORMAT, self.service.recvall(struct.calcsize(CODE_FORMAT)))
|
|
144
162
|
size -= struct.calcsize(CODE_FORMAT)
|
|
145
163
|
if code == CODE_ERROR_REMOTE:
|
|
146
164
|
# iOS 17 beta devices give this error for: backup_manifest.db
|
|
147
165
|
error_message = self.service.recvall(size).decode()
|
|
148
|
-
warnings.warn(
|
|
149
|
-
|
|
166
|
+
warnings.warn(
|
|
167
|
+
f"Failed to fully upload: {file_name}. Device file name: {device_name}. Reason: {error_message}",
|
|
168
|
+
stacklevel=2,
|
|
169
|
+
)
|
|
150
170
|
continue
|
|
151
171
|
assert code == CODE_SUCCESS
|
|
152
172
|
self.status_response(0)
|
|
153
173
|
|
|
154
|
-
def get_free_disk_space(self,
|
|
174
|
+
def get_free_disk_space(self, _message: DLMessage) -> None:
|
|
155
175
|
freespace = shutil.disk_usage(self.root_path).free
|
|
156
176
|
self.status_response(0, status_dict=freespace)
|
|
157
177
|
|
|
158
|
-
def move_items(self, message):
|
|
159
|
-
|
|
178
|
+
def move_items(self, message: DLMessage) -> None:
|
|
179
|
+
items = cast(Mapping[str, str], message[1])
|
|
180
|
+
for src, dst in items.items():
|
|
160
181
|
dest = self.root_path / dst
|
|
161
182
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
162
183
|
shutil.move(self.root_path / src, dest)
|
|
163
184
|
self.status_response(0)
|
|
164
185
|
|
|
165
|
-
def copy_item(self, message):
|
|
166
|
-
src = self.root_path / message[1]
|
|
167
|
-
dest = self.root_path / message[2]
|
|
186
|
+
def copy_item(self, message: DLMessage) -> None:
|
|
187
|
+
src = self.root_path / cast(str, message[1])
|
|
188
|
+
dest = self.root_path / cast(str, message[2])
|
|
168
189
|
dest.parent.mkdir(parents=True, exist_ok=True)
|
|
169
190
|
if src.is_dir():
|
|
170
191
|
shutil.copytree(src, dest)
|
|
@@ -172,11 +193,11 @@ class DeviceLink:
|
|
|
172
193
|
shutil.copy(src, dest)
|
|
173
194
|
self.status_response(0)
|
|
174
195
|
|
|
175
|
-
def purge_disk_space(self,
|
|
196
|
+
def purge_disk_space(self, _message: DLMessage) -> None:
|
|
176
197
|
raise NotEnoughDiskSpaceError()
|
|
177
198
|
|
|
178
|
-
def remove_items(self, message):
|
|
179
|
-
for path in message[1]:
|
|
199
|
+
def remove_items(self, message: DLMessage) -> None:
|
|
200
|
+
for path in cast(Iterable[str], message[1]):
|
|
180
201
|
rm_path = self.root_path / path
|
|
181
202
|
if rm_path.is_dir():
|
|
182
203
|
shutil.rmtree(rm_path)
|
|
@@ -184,24 +205,25 @@ class DeviceLink:
|
|
|
184
205
|
rm_path.unlink(missing_ok=True)
|
|
185
206
|
self.status_response(0)
|
|
186
207
|
|
|
187
|
-
def create_directory(self, message):
|
|
188
|
-
path = message[1]
|
|
208
|
+
def create_directory(self, message: DLMessage) -> None:
|
|
209
|
+
path = cast(str, message[1])
|
|
189
210
|
(self.root_path / path).mkdir(parents=True, exist_ok=True)
|
|
190
211
|
self.status_response(0)
|
|
191
212
|
|
|
192
|
-
def status_response(self, status_code, status_str=
|
|
213
|
+
def status_response(self, status_code: int, status_str: str = "", status_dict: Any = None) -> None:
|
|
193
214
|
self.service.send_plist([
|
|
194
|
-
|
|
195
|
-
|
|
215
|
+
"DLMessageStatusResponse",
|
|
216
|
+
ctypes.c_uint64(status_code).value,
|
|
217
|
+
status_str if status_str else "___EmptyParameterString___",
|
|
196
218
|
status_dict if status_dict is not None else {},
|
|
197
219
|
])
|
|
198
220
|
|
|
199
|
-
def receive_message(self):
|
|
200
|
-
return self.service.recv_plist()
|
|
221
|
+
def receive_message(self) -> DLMessage:
|
|
222
|
+
return cast(DLMessage, self.service.recv_plist())
|
|
201
223
|
|
|
202
|
-
def disconnect(self):
|
|
203
|
-
self.service.send_plist([
|
|
224
|
+
def disconnect(self) -> None:
|
|
225
|
+
self.service.send_plist(["DLMessageDisconnect", "___EmptyParameterString___"])
|
|
204
226
|
|
|
205
|
-
def _prefixed_recv(self):
|
|
206
|
-
size, = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
227
|
+
def _prefixed_recv(self) -> str:
|
|
228
|
+
(size,) = struct.unpack(SIZE_FORMAT, self.service.recvall(struct.calcsize(SIZE_FORMAT)))
|
|
207
229
|
return self.service.recvall(size).decode()
|