diff options
Diffstat (limited to 'cython/installation_proxy.pxi')
-rw-r--r-- | cython/installation_proxy.pxi | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/cython/installation_proxy.pxi b/cython/installation_proxy.pxi new file mode 100644 index 0000000..1d3e323 --- /dev/null +++ b/cython/installation_proxy.pxi | |||
@@ -0,0 +1,304 @@ | |||
1 | cdef extern from "libimobiledevice/installation_proxy.h": | ||
2 | cdef struct instproxy_client_private: | ||
3 | pass | ||
4 | ctypedef instproxy_client_private *instproxy_client_t | ||
5 | ctypedef void (*instproxy_status_cb_t) (plist.plist_t command, plist.plist_t status, void *user_data) | ||
6 | |||
7 | ctypedef enum instproxy_error_t: | ||
8 | INSTPROXY_E_SUCCESS = 0 | ||
9 | INSTPROXY_E_INVALID_ARG = -1 | ||
10 | INSTPROXY_E_PLIST_ERROR = -2 | ||
11 | INSTPROXY_E_CONN_FAILED = -3 | ||
12 | INSTPROXY_E_OP_IN_PROGRESS = -4 | ||
13 | INSTPROXY_E_OP_FAILED = -5 | ||
14 | INSTPROXY_E_UNKNOWN_ERROR = -256 | ||
15 | |||
16 | instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, instproxy_client_t *client) | ||
17 | instproxy_error_t instproxy_client_free(instproxy_client_t client) | ||
18 | instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path) | ||
19 | |||
20 | instproxy_error_t instproxy_browse(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result) | ||
21 | instproxy_error_t instproxy_install(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
22 | instproxy_error_t instproxy_upgrade(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
23 | instproxy_error_t instproxy_uninstall(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
24 | |||
25 | instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result) | ||
26 | instproxy_error_t instproxy_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
27 | instproxy_error_t instproxy_restore(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
28 | instproxy_error_t instproxy_remove_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data) | ||
29 | |||
30 | cdef void instproxy_notify_cb(plist.plist_t command, plist.plist_t status, void *py_callback) noexcept: | ||
31 | (<object>py_callback)(plist.plist_t_to_node(command, False), plist.plist_t_to_node(status, False)) | ||
32 | |||
33 | cdef class InstallationProxyError(BaseError): | ||
34 | def __init__(self, *args, **kwargs): | ||
35 | self._lookup_table = { | ||
36 | INSTPROXY_E_SUCCESS: "Success", | ||
37 | INSTPROXY_E_INVALID_ARG: "Invalid argument", | ||
38 | INSTPROXY_E_PLIST_ERROR: "Property list error", | ||
39 | INSTPROXY_E_CONN_FAILED: "Connection failed", | ||
40 | INSTPROXY_E_OP_IN_PROGRESS: "Operation in progress", | ||
41 | INSTPROXY_E_OP_FAILED: "Operation failed", | ||
42 | INSTPROXY_E_UNKNOWN_ERROR: "Unknown error" | ||
43 | } | ||
44 | BaseError.__init__(self, *args, **kwargs) | ||
45 | |||
46 | cdef class InstallationProxyClient(PropertyListService): | ||
47 | __service_name__ = "com.apple.mobile.installation_proxy" | ||
48 | cdef instproxy_client_t _c_client | ||
49 | |||
50 | def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs): | ||
51 | cdef: | ||
52 | iDevice dev = device | ||
53 | instproxy_error_t err | ||
54 | err = instproxy_client_new(dev._c_dev, descriptor._c_service_descriptor, &self._c_client) | ||
55 | self.handle_error(err) | ||
56 | |||
57 | def __dealloc__(self): | ||
58 | cdef instproxy_error_t err | ||
59 | if self._c_client is not NULL: | ||
60 | err = instproxy_client_free(self._c_client) | ||
61 | self.handle_error(err) | ||
62 | |||
63 | cpdef get_path_for_bundle_identifier(self, bytes bundle_id): | ||
64 | cdef: | ||
65 | char* c_bundle_id = bundle_id | ||
66 | char* c_path = NULL | ||
67 | bytes result | ||
68 | |||
69 | try: | ||
70 | self.handle_error(instproxy_client_get_path_for_bundle_identifier(self._c_client, c_bundle_id, &c_path)) | ||
71 | if c_path != NULL: | ||
72 | result = c_path | ||
73 | return result | ||
74 | else: | ||
75 | return None | ||
76 | except BaseError, e: | ||
77 | raise | ||
78 | finally: | ||
79 | free(c_path) | ||
80 | |||
81 | cpdef plist.Node browse(self, object client_options): | ||
82 | cdef: | ||
83 | plist.Node options | ||
84 | plist.plist_t c_options | ||
85 | plist.plist_t c_result = NULL | ||
86 | bint free_options = False | ||
87 | instproxy_error_t err | ||
88 | if isinstance(client_options, plist.Dict): | ||
89 | options = client_options | ||
90 | c_options = options._c_node | ||
91 | elif isinstance(client_options, dict): | ||
92 | c_options = plist.native_to_plist_t(client_options) | ||
93 | free_options = True | ||
94 | else: | ||
95 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
96 | err = instproxy_browse(self._c_client, c_options, &c_result) | ||
97 | |||
98 | try: | ||
99 | self.handle_error(err) | ||
100 | return plist.plist_t_to_node(c_result) | ||
101 | except Exception, e: | ||
102 | if c_result != NULL: | ||
103 | plist.plist_free(c_result) | ||
104 | raise | ||
105 | finally: | ||
106 | if free_options: | ||
107 | plist.plist_free(c_options) | ||
108 | |||
109 | cpdef install(self, bytes pkg_path, object client_options, object callback=None): | ||
110 | cdef: | ||
111 | plist.Node options | ||
112 | plist.plist_t c_options | ||
113 | bint free_options = False | ||
114 | instproxy_error_t err | ||
115 | if isinstance(client_options, plist.Dict): | ||
116 | options = client_options | ||
117 | c_options = options._c_node | ||
118 | elif isinstance(client_options, dict): | ||
119 | c_options = plist.native_to_plist_t(client_options) | ||
120 | free_options = True | ||
121 | else: | ||
122 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
123 | if callback is None: | ||
124 | err = instproxy_install(self._c_client, pkg_path, c_options, NULL, NULL) | ||
125 | else: | ||
126 | err = instproxy_install(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback) | ||
127 | |||
128 | try: | ||
129 | self.handle_error(err) | ||
130 | except Exception, e: | ||
131 | raise | ||
132 | finally: | ||
133 | if free_options: | ||
134 | plist.plist_free(c_options) | ||
135 | |||
136 | cpdef upgrade(self, bytes pkg_path, object client_options, object callback=None): | ||
137 | cdef: | ||
138 | plist.Node options | ||
139 | plist.plist_t c_options | ||
140 | bint free_options = False | ||
141 | instproxy_error_t err | ||
142 | if isinstance(client_options, plist.Dict): | ||
143 | options = client_options | ||
144 | c_options = options._c_node | ||
145 | elif isinstance(client_options, dict): | ||
146 | c_options = plist.native_to_plist_t(client_options) | ||
147 | free_options = True | ||
148 | else: | ||
149 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
150 | if callback is None: | ||
151 | err = instproxy_upgrade(self._c_client, pkg_path, c_options, NULL, NULL) | ||
152 | else: | ||
153 | err = instproxy_upgrade(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback) | ||
154 | try: | ||
155 | self.handle_error(err) | ||
156 | except Exception, e: | ||
157 | raise | ||
158 | finally: | ||
159 | if free_options: | ||
160 | plist.plist_free(c_options) | ||
161 | |||
162 | cpdef uninstall(self, bytes appid, object client_options, object callback=None): | ||
163 | cdef: | ||
164 | plist.Node options | ||
165 | plist.plist_t c_options | ||
166 | instproxy_error_t err | ||
167 | bint free_options = False | ||
168 | if isinstance(client_options, plist.Dict): | ||
169 | options = client_options | ||
170 | c_options = options._c_node | ||
171 | elif isinstance(client_options, dict): | ||
172 | c_options = plist.native_to_plist_t(client_options) | ||
173 | free_options = True | ||
174 | else: | ||
175 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
176 | |||
177 | if callback is None: | ||
178 | err = instproxy_uninstall(self._c_client, appid, c_options, NULL, NULL) | ||
179 | else: | ||
180 | err = instproxy_uninstall(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
181 | |||
182 | try: | ||
183 | self.handle_error(err) | ||
184 | except Exception, e: | ||
185 | raise | ||
186 | finally: | ||
187 | if free_options: | ||
188 | plist.plist_free(c_options) | ||
189 | |||
190 | cpdef plist.Node lookup_archives(self, object client_options): | ||
191 | cdef: | ||
192 | plist.Node options | ||
193 | plist.plist_t c_options | ||
194 | plist.plist_t c_node = NULL | ||
195 | instproxy_error_t err | ||
196 | bint free_options = False | ||
197 | if isinstance(client_options, plist.Dict): | ||
198 | options = client_options | ||
199 | c_options = options._c_node | ||
200 | elif isinstance(client_options, dict): | ||
201 | c_options = plist.native_to_plist_t(client_options) | ||
202 | free_options = True | ||
203 | else: | ||
204 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
205 | |||
206 | err = instproxy_lookup_archives(self._c_client, c_options, &c_node) | ||
207 | |||
208 | try: | ||
209 | self.handle_error(err) | ||
210 | return plist.plist_t_to_node(c_node) | ||
211 | except Exception, e: | ||
212 | if c_node != NULL: | ||
213 | plist.plist_free(c_node) | ||
214 | raise | ||
215 | finally: | ||
216 | if free_options: | ||
217 | plist.plist_free(c_options) | ||
218 | |||
219 | cpdef archive(self, bytes appid, object client_options, object callback=None): | ||
220 | cdef: | ||
221 | plist.Node options | ||
222 | plist.plist_t c_options | ||
223 | bint free_options = False | ||
224 | instproxy_error_t err | ||
225 | if isinstance(client_options, plist.Dict): | ||
226 | options = client_options | ||
227 | c_options = options._c_node | ||
228 | elif isinstance(client_options, dict): | ||
229 | c_options = plist.native_to_plist_t(client_options) | ||
230 | free_options = True | ||
231 | else: | ||
232 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
233 | |||
234 | if callback is None: | ||
235 | err = instproxy_archive(self._c_client, appid, c_options, NULL, NULL) | ||
236 | else: | ||
237 | err = instproxy_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
238 | |||
239 | try: | ||
240 | self.handle_error(err) | ||
241 | except Exception, e: | ||
242 | raise | ||
243 | finally: | ||
244 | if free_options: | ||
245 | plist.plist_free(c_options) | ||
246 | |||
247 | cpdef restore(self, bytes appid, object client_options, object callback=None): | ||
248 | cdef: | ||
249 | plist.Node options | ||
250 | plist.plist_t c_options | ||
251 | bint free_options = False | ||
252 | instproxy_error_t err | ||
253 | if isinstance(client_options, plist.Dict): | ||
254 | options = client_options | ||
255 | c_options = options._c_node | ||
256 | elif isinstance(client_options, dict): | ||
257 | c_options = plist.native_to_plist_t(client_options) | ||
258 | free_options = True | ||
259 | else: | ||
260 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
261 | |||
262 | if callback is None: | ||
263 | err = instproxy_restore(self._c_client, appid, c_options, NULL, NULL) | ||
264 | else: | ||
265 | err = instproxy_restore(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
266 | |||
267 | try: | ||
268 | self.handle_error(err) | ||
269 | except Exception, e: | ||
270 | raise | ||
271 | finally: | ||
272 | if free_options: | ||
273 | plist.plist_free(c_options) | ||
274 | |||
275 | cpdef remove_archive(self, bytes appid, object client_options, object callback=None): | ||
276 | cdef: | ||
277 | plist.Node options | ||
278 | plist.plist_t c_options | ||
279 | bint free_options = False | ||
280 | instproxy_error_t err | ||
281 | if isinstance(client_options, plist.Dict): | ||
282 | options = client_options | ||
283 | c_options = options._c_node | ||
284 | elif isinstance(client_options, dict): | ||
285 | c_options = plist.native_to_plist_t(client_options) | ||
286 | free_options = True | ||
287 | else: | ||
288 | raise InstallationProxyError(INSTPROXY_E_INVALID_ARG) | ||
289 | |||
290 | if callback is None: | ||
291 | err = instproxy_remove_archive(self._c_client, appid, c_options, NULL, NULL) | ||
292 | else: | ||
293 | err = instproxy_remove_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback) | ||
294 | |||
295 | try: | ||
296 | self.handle_error(err) | ||
297 | except Exception, e: | ||
298 | raise | ||
299 | finally: | ||
300 | if free_options: | ||
301 | plist.plist_free(c_options) | ||
302 | |||
303 | cdef inline BaseError _error(self, int16_t ret): | ||
304 | return InstallationProxyError(ret) | ||