nemomobile/buteo-sync-plugin-caldav — pull request #25 by sdrave (2014-08-31 23:11:21+00:00)
Title: Various improvements 

Hi!

Since I ran into various issues when syncing my Jolla device to an owncloud server, I started hacking a bit on the caldav sync plugin. Along the way I fixed several problems:

- In general, there is no correlation between the uid of an incidence and its uri. This is explicitly stated in the documentation of sabredav (http://sabre.io/dav/building-a-caldav-client/) which owncloud uses. As Reader::hrefToUid is used at several places in the sync code, this causes several problems. (For instance: incidences which have been initially received from the server and have been deleted locally, will reappear after the sync due to the use of hrefToUid in Report::processETags.)

- Owncloud does not return etags after successful PUT requests. As a result, the old etag is still in the database during the next sync. Therefore, the updated incidence will be detected as having changed on the server and any local changes after the last sync will be overwritten. (Server always wins.)

- If you fetch an incidence from the server an delete it locally after synchronization, the storage backend will not report this incidence as deleted as the creation date is after the beginning of the last sync. (The backend only returns incidences which have been deleted after, but created before a given date.)

- The storage backend deletes all custom properties of deleted incidences. Therefore customProperty("buteo", "uri") cannot be used to determine the uri of the incidence. (And the fallback of using the uid to derive the uri cannot be used either ..)

To resolve these issues, I mainly made the following changes:

- Immediately parse the received iCalData to have the true uid of the received incidence available. (I added this to Reader, although a different place might be better.) Then use the true uid instead of using hrefToUid.

- If no etag is returned after a PUT request, the corresponding incidence is reloaded in an additional REPORT request. (For this I refactored the Report class to make reusing the code easier.)

- Go through the list of incidences which have been inserted during the last sync and check if they have vanished from the local storage. If so, add them to the list of local deletions.

- If a locally deleted incidence is still on the server, it will have been reloaded during the initial REPORT request. Therefore we can determine the uri of a locally deleted incidence by scanning through the list of received incidences. (A cleaner solution might be to store the mapping between uid and uri in an additional database table.)

I should note that I didn't heavily test the code, but it seems to work for me ..

Cheers,
Stephan