4. Synchronization

There are two methods to follow changes to certain server contents. The first, ICS (incremental change synchronization) allows for state-based synchronization. The other, notifications, provides real-time updates whenever something changes.

4.1. ICS

Based on a given state, ICS exports all subsequent changes and when there are no more changes, returns the new state. Changes are communicated to a call-back object, with the following (optional) methods:

class Importer:
    def update(self, obj, flags=None):
        print('new or updated:', obj, flags)

    def delete(self, obj, flags=None):
        print('deleted:', obj, flags)

    def read(self, obj, status): # items only
        print('read state change:', obj, status)

Using this, we can synchronize the items of a specific folder:

folder.sync(Importer(), state)

Or even all item changes for an entire Kopano server (system-wide ICS):

server.sync(Importer(), state)

In the folder case, we can omit the state, in which case the entire folder is synchronized.

We can also synchronize the sub-folder hierarchy for a given folder (usually subtree):

store.subtree.sync_hierarchy(Importer(), state)

Finally, we can also synchronize the addressbook as follows:

server.sync_gab(Importer(), state)

Note that on deletion, the actual object is gone when the call-back happens. For items and folders only obj.sourcekey remains, and for users only obj.userid.

Note also that old changes are not kept in the system, so intermediate changes are never exported.

4.2. Notifications

Notifications provide real-time tracking of specific classes of changes. Similar to ICS, a call-back object receives the changes:

class Sink:
    def update(self, notification):
        print('changed:',
            notification.object,
            notification.object_type,
            notification.event_type)

Now, to subscribe to all changes to a specific folder:

folder.subscribe(Sink())

To only receive changes to the folder items themselves, specify object type (folder or item):

folder.subscribe(Sink(), object_types=['item'])

To only receive certain event types for these items (created, updated, deleted):

folder.subscribe(Sink(), object_types=['item'], event_types=['created', 'deleted'])

To subscribe to all changes to a given store:

store.subscribe(Sink())

To only receive changes to folders, specify object type (folder or item):

store.subscribe(Sink(), object_types=['folder'])