Tom Hacohen 5 years ago
parent b90d2714a9
commit 467701047f

@ -133,7 +133,7 @@ class LocalGroup : AndroidGroup, LocalAddress {
constructor(addressBook: AndroidAddressBook<out AndroidContact, LocalGroup>, values: ContentValues)
: super(addressBook, values) {}
constructor(addressBook: AndroidAddressBook<out AndroidContact, LocalGroup>, contact: Contact, fileName: String?, eTag: String?, flags: Int)
constructor(addressBook: AndroidAddressBook<out AndroidContact, LocalGroup>, contact: Contact, fileName: String?, eTag: String?)
: super(addressBook, contact, fileName, eTag) {}
override fun contentValues(): ContentValues {

@ -227,7 +227,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val startDate = event.dtStart?.date
val endDate = event.getEndDate(true)!!.date
val tzName = timezone.getDisplayName(timezone?.inDaylightTime(startDate)!!, TimeZone.SHORT)
val tzName = timezone?.getDisplayName(timezone?.inDaylightTime(startDate)!!, TimeZone.SHORT)
val cal1 = Calendar.getInstance()
val cal2 = Calendar.getInstance()

@ -17,6 +17,7 @@ import android.content.SyncResult
import android.database.sqlite.SQLiteException
import android.os.Bundle
import android.provider.CalendarContract
import at.bitfire.ical4android.AndroidCalendar
import com.etesync.syncadapter.AccountSettings
import com.etesync.syncadapter.App
@ -67,7 +68,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
val principal = HttpUrl.get(settings.uri!!)!!
for (calendar in LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null) as Array<LocalCalendar>) {
for (calendar in AndroidCalendar.find(account, provider, LocalCalendar.Factory, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null) as Array<LocalCalendar>) {
App.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name)
val syncManager = CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal)
syncManager.performSync()
@ -95,10 +96,6 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
notificationManager.notify(title, context.getString(syncPhase))
} catch (e: OutOfMemoryError) {
if (e is CalendarStorageException || e is SQLiteException) {
App.log.log(Level.SEVERE, "Couldn't prepare local calendars", e)
syncResult.databaseError = true
}
val syncPhase = R.string.sync_phase_journals
val title = context.getString(R.string.sync_error_calendar, account.name)
notificationManager.setThrowable(e)
@ -121,7 +118,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
remote[journalEntity.uid] = journalEntity
}
val local = LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null) as Array<LocalCalendar>
val local = AndroidCalendar.find(account, provider, LocalCalendar.Factory, null, null) as Array<LocalCalendar>
val updateColors = settings.manageCalendarColors

@ -29,14 +29,9 @@ import com.etesync.syncadapter.journalmanager.Exceptions
import com.etesync.syncadapter.journalmanager.JournalEntryManager
import com.etesync.syncadapter.model.CollectionInfo
import com.etesync.syncadapter.model.SyncEntry
import com.etesync.syncadapter.resource.LocalAddressBook
import com.etesync.syncadapter.resource.LocalContact
import com.etesync.syncadapter.resource.LocalGroup
import com.etesync.syncadapter.resource.LocalResource
import org.apache.commons.codec.Charsets
import org.apache.commons.collections4.SetUtils
import org.apache.commons.io.IOUtils
import java.io.ByteArrayInputStream
import java.io.FileNotFoundException
@ -47,15 +42,17 @@ import at.bitfire.ical4android.CalendarStorageException
import at.bitfire.vcard4android.BatchOperation
import at.bitfire.vcard4android.Contact
import at.bitfire.vcard4android.ContactsStorageException
import com.etesync.syncadapter.resource.*
import okhttp3.HttpUrl
import okhttp3.Request
import java.io.StringReader
/**
*
* Synchronization manager for CardDAV collections; handles contacts and groups.
*/
class ContactsSyncManager @Throws(Exceptions.IntegrityException::class, Exceptions.GenericCryptoException::class, ContactsStorageException::class)
constructor(context: Context, account: Account, settings: AccountSettings, extras: Bundle, authority: String, private val provider: ContentProviderClient, result: SyncResult, localAddressBook: LocalAddressBook, private val remote: HttpUrl) : SyncManager(context, account, settings, extras, authority, result, localAddressBook.url!!, CollectionInfo.Type.ADDRESS_BOOK, localAddressBook.mainAccount.name) {
constructor(context: Context, account: Account, settings: AccountSettings, extras: Bundle, authority: String, private val provider: ContentProviderClient, result: SyncResult, localAddressBook: LocalAddressBook, private val remote: HttpUrl) : SyncManager<LocalAddress>(context, account, settings, extras, authority, result, localAddressBook.url!!, CollectionInfo.Type.ADDRESS_BOOK, localAddressBook.mainAccount.name) {
protected override val syncErrorTitle: String
get() = context.getString(R.string.sync_error_contacts, account.name)
@ -81,7 +78,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
val reallyDirty = localAddressBook.verifyDirty()
val deleted = localAddressBook.deleted.size
val deleted = localAddressBook.findDeleted().size
if (extras.containsKey(ContentResolver.SYNC_EXTRAS_UPLOAD) && reallyDirty == 0 && deleted == 0) {
App.log.info("This sync was called to up-sync dirty/deleted contacts, but no contacts have been changed")
return false
@ -92,7 +89,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val values = ContentValues(2)
values.put(ContactsContract.Settings.SHOULD_SYNC, 1)
values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1)
localAddressBook.updateSettings(values)
localAddressBook.settings.putAll(values)
journal = JournalEntryManager(httpClient, remote, localAddressBook.url!!)
@ -110,8 +107,8 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
/* groups as separate VCards: there are group contacts and individual contacts */
// mark groups with changed members as dirty
val batch = BatchOperation(addressBook.provider)
for (contact in addressBook.dirtyContacts) {
val batch = BatchOperation(addressBook.provider!!)
for (contact in addressBook.findDirtyContacts()) {
try {
App.log.fine("Looking for changed group memberships of contact " + contact.fileName)
val cachedGroups = contact.cachedGroupMemberships
@ -148,10 +145,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
@Throws(IOException::class, ContactsStorageException::class, CalendarStorageException::class)
override fun processSyncEntry(cEntry: SyncEntry) {
val `is` = ByteArrayInputStream(cEntry.content.toByteArray(Charsets.UTF_8))
val inputReader = StringReader(cEntry.content)
val downloader = ResourceDownloader(context)
val contacts = Contact.fromStream(`is`, Charsets.UTF_8, downloader)
val contacts = Contact.fromReader(inputReader, downloader)
if (contacts.size == 0) {
App.log.warning("Received VCard without data, ignoring")
return
@ -159,14 +156,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
App.log.warning("Received multiple VCards, using first one")
val contact = contacts[0]
val local = localCollection!!.findByUid(contact.uid) as LocalResource?
val local = localCollection!!.findByUid(contact.uid!!)
if (cEntry.isAction(SyncEntry.Actions.ADD) || cEntry.isAction(SyncEntry.Actions.CHANGE)) {
processContact(contact, local)
} else {
if (local != null) {
App.log.info("Removing local record #" + local.id + " which has been deleted on the server")
App.log.info("Removing local record which has been deleted on the server")
local.delete()
} else {
App.log.warning("Tried deleting a non-existent record: " + contact.uid)
@ -175,7 +171,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
}
@Throws(IOException::class, ContactsStorageException::class)
private fun processContact(newData: Contact, local: LocalResource?): LocalResource {
private fun processContact(newData: Contact, local: LocalAddress?): LocalAddress {
var local = local
val uuid = newData.uid
// update local contact, if it exists
@ -184,14 +180,14 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
if (local is LocalGroup && newData.group) {
// update group
val group = local as LocalGroup?
val group: LocalGroup = local
group!!.eTag = uuid
group.updateFromServer(newData)
group.update(newData)
syncResult.stats.numUpdates++
} else if (local is LocalContact && !newData.group) {
// update contact
val contact = local as LocalContact?
val contact: LocalContact = local
contact!!.eTag = uuid
contact.update(newData)
syncResult.stats.numUpdates++
@ -212,13 +208,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
if (newData.group) {
App.log.log(Level.INFO, "Creating local group", newData.uid)
val group = LocalGroup(localAddressBook(), newData, uuid, uuid)
group.create()
group.add()
local = group
} else {
App.log.log(Level.INFO, "Creating local contact", newData.uid)
val contact = LocalContact(localAddressBook(), newData, uuid, uuid)
contact.create()
contact.add()
local = contact
}
@ -268,15 +264,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
val body = response.body()
if (body != null) {
val stream = body.byteStream()
try {
if (response.isSuccessful && stream != null) {
return IOUtils.toByteArray(stream)
} else
App.log.severe("Couldn't download external resource")
} finally {
stream?.close()
}
return body.bytes()
}
} catch (e: IOException) {
App.log.log(Level.SEVERE, "Couldn't download external resource", e)

Loading…
Cancel
Save