From 7d4a26663a812c383738fc6390759266851cf953 Mon Sep 17 00:00:00 2001 From: Bryan Forbes Date: Thu, 13 May 2010 09:41:12 -0500 Subject: Python bindings for new sync interface. --- cython/imobiledevice.pxd | 1 + cython/lockdown.pxi | 23 +++++++++++ cython/mobilesync.pxi | 104 ++++++++++++++++++++++++++++++++++++++++++++++- cython/stdint.pxi | 6 +++ 4 files changed, 133 insertions(+), 1 deletion(-) (limited to 'cython') diff --git a/cython/imobiledevice.pxd b/cython/imobiledevice.pxd index a699138..048f226 100644 --- a/cython/imobiledevice.pxd +++ b/cython/imobiledevice.pxd @@ -89,3 +89,4 @@ cdef class LockdownClient(PropertyListService): cpdef deactivate(self) cpdef enter_recovery(self) cpdef goodbye(self) + cpdef list get_sync_data_classes(self) diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi index a904d12..8463738 100644 --- a/cython/lockdown.pxi +++ b/cython/lockdown.pxi @@ -41,6 +41,8 @@ cdef extern from "libimobiledevice/lockdown.h": lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client) lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client) lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client) + lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count) + lockdownd_error_t lockdownd_data_classes_free(char **classes) cdef class LockdownError(BaseError): def __init__(self, *args, **kwargs): @@ -245,6 +247,27 @@ cdef class LockdownClient(PropertyListService): cpdef goodbye(self): self.handle_error(lockdownd_goodbye(self._c_client)) + cpdef list get_sync_data_classes(self): + cdef: + char **classes = NULL + int count = 0 + list result = [] + bytes data_class + + try: + self.handle_error(lockdownd_get_sync_data_classes(self._c_client, &classes, &count)) + + for i from 0 <= i < count: + data_class = classes[i] + result.append(data_class) + + return result + except Exception, e: + raise + finally: + if classes != NULL: + lockdownd_data_classes_free(classes) + cdef inline int16_t _send(self, plist.plist_t node): return lockdownd_send(self._c_client, node) diff --git a/cython/mobilesync.pxi b/cython/mobilesync.pxi index 00b511f..843700b 100644 --- a/cython/mobilesync.pxi +++ b/cython/mobilesync.pxi @@ -2,20 +2,54 @@ cdef extern from "libimobiledevice/mobilesync.h": cdef struct mobilesync_client_private: pass ctypedef mobilesync_client_private *mobilesync_client_t - ctypedef enum mobilesync_error_t: MOBILESYNC_E_SUCCESS = 0 MOBILESYNC_E_INVALID_ARG = -1 MOBILESYNC_E_PLIST_ERROR = -2 MOBILESYNC_E_MUX_ERROR = -3 MOBILESYNC_E_BAD_VERSION = -4 + MOBILESYNC_E_SYNC_REFUSED = -5 + MOBILESYNC_E_CANCELLED = -6 + MOBILESYNC_E_WRONG_DIRECTION = -7 + MOBILESYNC_E_NOT_READY = -8 MOBILESYNC_E_UNKNOWN_ERROR = -256 + ctypedef enum mobilesync_sync_type_t: + MOBILESYNC_SYNC_TYPE_FAST + MOBILESYNC_SYNC_TYPE_SLOW + MOBILESYNC_SYNC_TYPE_RESET + + ctypedef struct mobilesync_anchors: + char *device_anchor + char *host_anchor + ctypedef mobilesync_anchors *mobilesync_anchors_t + mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, mobilesync_client_t * client) mobilesync_error_t mobilesync_client_free(mobilesync_client_t client) mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist.plist_t *plist) mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist.plist_t plist) + mobilesync_error_t mobilesync_session_start(mobilesync_client_t client, char *data_class, mobilesync_anchors_t anchors, mobilesync_sync_type_t *sync_type, uint64_t *data_class_version) + mobilesync_error_t mobilesync_session_cancel(mobilesync_client_t client, char* reason) + mobilesync_error_t mobilesync_session_finish(mobilesync_client_t client) + + mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client) + mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client) + mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist.plist_t *entities, uint8_t *is_last_record) + mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client) + + mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client) + mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist.plist_t changes, uint8_t is_last_record, plist.plist_t actions) + mobilesync_error_t mobilesync_receive_remapping(mobilesync_client_t client, plist.plist_t *remapping) + + + mobilesync_anchors_t mobilesync_anchors_new(char *device_anchor, char *computer_anchor) + void mobilesync_anchors_free(mobilesync_anchors_t anchors) + +SYNC_TYPE_FAST = MOBILESYNC_SYNC_TYPE_FAST +SYNC_TYPE_SLOW = MOBILESYNC_SYNC_TYPE_SLOW +SYNC_TYPE_RESET = MOBILESYNC_SYNC_TYPE_RESET + cdef class MobileSyncError(BaseError): def __init__(self, *args, **kwargs): self._lookup_table = { @@ -24,6 +58,10 @@ cdef class MobileSyncError(BaseError): MOBILESYNC_E_PLIST_ERROR: "Property list error", MOBILESYNC_E_MUX_ERROR: "MUX error", MOBILESYNC_E_BAD_VERSION: "Bad version", + MOBILESYNC_E_SYNC_REFUSED: "Sync refused", + MOBILESYNC_E_CANCELLED: "Sync cancelled", + MOBILESYNC_E_WRONG_DIRECTION: "Wrong sync direction", + MOBILESYNC_E_NOT_READY: "Not ready to receive changes", MOBILESYNC_E_UNKNOWN_ERROR: "Unknown error" } BaseError.__init__(self, *args, **kwargs) @@ -40,6 +78,70 @@ cdef class MobileSyncClient(DeviceLinkService): if self._c_client is not NULL: err = mobilesync_client_free(self._c_client) self.handle_error(err) + + cpdef tuple session_start(self, bytes data_class, bytes last_sync_time, bytes current_time): + cdef: + mobilesync_anchors_t anchors = NULL + mobilesync_sync_type_t sync_type + uint64_t data_class_version + + if last_sync_time is None: + anchors = mobilesync_anchors_new(NULL, current_time) + else: + anchors = mobilesync_anchors_new(last_sync_time, current_time) + + try: + self.handle_error(mobilesync_session_start(self._c_client, data_class, anchors, &sync_type, &data_class_version)) + return (sync_type, data_class_version) + except Exception, e: + raise + finally: + mobilesync_anchors_free(anchors) + + cpdef session_finish(self): + self.handle_error(mobilesync_session_finish(self._c_client)) + + cpdef session_cancel(self, bytes reason): + self.handle_error(mobilesync_session_cancel(self._c_client, reason)) + + cpdef get_all_records_from_device(self): + self.handle_error(mobilesync_get_all_records_from_device(self._c_client)) + + cpdef get_changes_from_device(self): + self.handle_error(mobilesync_get_changes_from_device(self._c_client)) + + cpdef tuple receive_changes(self): + cdef: + plist.plist_t entities = NULL + uint8_t is_last_record = 0 + + try: + self.handle_error(mobilesync_receive_changes(self._c_client, &entities, &is_last_record)) + return (plist.plist_t_to_node(entities), is_last_record) + except Exception, e: + if entities != NULL: + plist.plist_free(entities) + raise + + cpdef acknowledge_changes_from_device(self): + self.handle_error(mobilesync_acknowledge_changes_from_device(self._c_client)) + + cpdef ready_to_send_changes_from_computer(self): + self.handle_error(mobilesync_ready_to_send_changes_from_computer(self._c_client)) + + cpdef send_changes(self, plist.Node changes, bint is_last_record, plist.Node actions): + self.handle_error(mobilesync_send_changes(self._c_client, changes._c_node, is_last_record, actions._c_node)) + + cpdef receive_remapping(self): + cdef plist.plist_t remapping = NULL + + try: + self.handle_error(mobilesync_receive_remapping(self._c_client, &remapping)) + return plist.plist_t_to_node(remapping) + except Exception, e: + if remapping != NULL: + plist.plist_free(remapping) + raise cdef inline int16_t _send(self, plist.plist_t node): return mobilesync_send(self._c_client, node) diff --git a/cython/stdint.pxi b/cython/stdint.pxi index 2617dec..f9e5e95 100644 --- a/cython/stdint.pxi +++ b/cython/stdint.pxi @@ -4,9 +4,15 @@ cdef extern from *: ctypedef unsigned short int uint16_t ctypedef unsigned int uint32_t ctypedef int int32_t + ctypedef long int time_t IF UNAME_MACHINE == 'x86_64': ctypedef long int int64_t ctypedef unsigned long int uint64_t ELSE: ctypedef long long int int64_t ctypedef unsigned long long int uint64_t + +cdef extern from "time.h": + cdef struct timeval: + time_t tv_sec + time_t tv_usec -- cgit v1.1-32-gdbae