mirror of
https://github.com/etesync/android
synced 2024-11-22 16:08:13 +00:00
snap
This commit is contained in:
parent
b90d2714a9
commit
467701047f
@ -133,7 +133,7 @@ class LocalGroup : AndroidGroup, LocalAddress {
|
|||||||
constructor(addressBook: AndroidAddressBook<out AndroidContact, LocalGroup>, values: ContentValues)
|
constructor(addressBook: AndroidAddressBook<out AndroidContact, LocalGroup>, values: ContentValues)
|
||||||
: super(addressBook, values) {}
|
: 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) {}
|
: super(addressBook, contact, fileName, eTag) {}
|
||||||
|
|
||||||
override fun contentValues(): ContentValues {
|
override fun contentValues(): ContentValues {
|
||||||
|
@ -227,7 +227,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
|
|
||||||
val startDate = event.dtStart?.date
|
val startDate = event.dtStart?.date
|
||||||
val endDate = event.getEndDate(true)!!.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 cal1 = Calendar.getInstance()
|
||||||
val cal2 = Calendar.getInstance()
|
val cal2 = Calendar.getInstance()
|
||||||
|
@ -17,6 +17,7 @@ import android.content.SyncResult
|
|||||||
import android.database.sqlite.SQLiteException
|
import android.database.sqlite.SQLiteException
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
|
import at.bitfire.ical4android.AndroidCalendar
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings
|
import com.etesync.syncadapter.AccountSettings
|
||||||
import com.etesync.syncadapter.App
|
import com.etesync.syncadapter.App
|
||||||
@ -67,7 +68,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
|
|||||||
|
|
||||||
val principal = HttpUrl.get(settings.uri!!)!!
|
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)
|
App.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name)
|
||||||
val syncManager = CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal)
|
val syncManager = CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal)
|
||||||
syncManager.performSync()
|
syncManager.performSync()
|
||||||
@ -95,10 +96,6 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
|
|||||||
|
|
||||||
notificationManager.notify(title, context.getString(syncPhase))
|
notificationManager.notify(title, context.getString(syncPhase))
|
||||||
} catch (e: OutOfMemoryError) {
|
} 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 syncPhase = R.string.sync_phase_journals
|
||||||
val title = context.getString(R.string.sync_error_calendar, account.name)
|
val title = context.getString(R.string.sync_error_calendar, account.name)
|
||||||
notificationManager.setThrowable(e)
|
notificationManager.setThrowable(e)
|
||||||
@ -121,7 +118,7 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
|
|||||||
remote[journalEntity.uid] = journalEntity
|
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
|
val updateColors = settings.manageCalendarColors
|
||||||
|
|
||||||
|
@ -29,14 +29,9 @@ import com.etesync.syncadapter.journalmanager.Exceptions
|
|||||||
import com.etesync.syncadapter.journalmanager.JournalEntryManager
|
import com.etesync.syncadapter.journalmanager.JournalEntryManager
|
||||||
import com.etesync.syncadapter.model.CollectionInfo
|
import com.etesync.syncadapter.model.CollectionInfo
|
||||||
import com.etesync.syncadapter.model.SyncEntry
|
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.codec.Charsets
|
||||||
import org.apache.commons.collections4.SetUtils
|
import org.apache.commons.collections4.SetUtils
|
||||||
import org.apache.commons.io.IOUtils
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
@ -47,15 +42,17 @@ import at.bitfire.ical4android.CalendarStorageException
|
|||||||
import at.bitfire.vcard4android.BatchOperation
|
import at.bitfire.vcard4android.BatchOperation
|
||||||
import at.bitfire.vcard4android.Contact
|
import at.bitfire.vcard4android.Contact
|
||||||
import at.bitfire.vcard4android.ContactsStorageException
|
import at.bitfire.vcard4android.ContactsStorageException
|
||||||
|
import com.etesync.syncadapter.resource.*
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
import java.io.StringReader
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Synchronization manager for CardDAV collections; handles contacts and groups.
|
* Synchronization manager for CardDAV collections; handles contacts and groups.
|
||||||
*/
|
*/
|
||||||
class ContactsSyncManager @Throws(Exceptions.IntegrityException::class, Exceptions.GenericCryptoException::class, ContactsStorageException::class)
|
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
|
protected override val syncErrorTitle: String
|
||||||
get() = context.getString(R.string.sync_error_contacts, account.name)
|
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) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
|
// workaround for Android 7 which sets DIRTY flag when only meta-data is changed
|
||||||
val reallyDirty = localAddressBook.verifyDirty()
|
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) {
|
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")
|
App.log.info("This sync was called to up-sync dirty/deleted contacts, but no contacts have been changed")
|
||||||
return false
|
return false
|
||||||
@ -92,7 +89,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
val values = ContentValues(2)
|
val values = ContentValues(2)
|
||||||
values.put(ContactsContract.Settings.SHOULD_SYNC, 1)
|
values.put(ContactsContract.Settings.SHOULD_SYNC, 1)
|
||||||
values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1)
|
values.put(ContactsContract.Settings.UNGROUPED_VISIBLE, 1)
|
||||||
localAddressBook.updateSettings(values)
|
localAddressBook.settings.putAll(values)
|
||||||
|
|
||||||
journal = JournalEntryManager(httpClient, remote, localAddressBook.url!!)
|
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 */
|
/* groups as separate VCards: there are group contacts and individual contacts */
|
||||||
|
|
||||||
// mark groups with changed members as dirty
|
// mark groups with changed members as dirty
|
||||||
val batch = BatchOperation(addressBook.provider)
|
val batch = BatchOperation(addressBook.provider!!)
|
||||||
for (contact in addressBook.dirtyContacts) {
|
for (contact in addressBook.findDirtyContacts()) {
|
||||||
try {
|
try {
|
||||||
App.log.fine("Looking for changed group memberships of contact " + contact.fileName)
|
App.log.fine("Looking for changed group memberships of contact " + contact.fileName)
|
||||||
val cachedGroups = contact.cachedGroupMemberships
|
val cachedGroups = contact.cachedGroupMemberships
|
||||||
@ -148,10 +145,10 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
|
|
||||||
@Throws(IOException::class, ContactsStorageException::class, CalendarStorageException::class)
|
@Throws(IOException::class, ContactsStorageException::class, CalendarStorageException::class)
|
||||||
override fun processSyncEntry(cEntry: SyncEntry) {
|
override fun processSyncEntry(cEntry: SyncEntry) {
|
||||||
val `is` = ByteArrayInputStream(cEntry.content.toByteArray(Charsets.UTF_8))
|
val inputReader = StringReader(cEntry.content)
|
||||||
val downloader = ResourceDownloader(context)
|
val downloader = ResourceDownloader(context)
|
||||||
|
|
||||||
val contacts = Contact.fromStream(`is`, Charsets.UTF_8, downloader)
|
val contacts = Contact.fromReader(inputReader, downloader)
|
||||||
if (contacts.size == 0) {
|
if (contacts.size == 0) {
|
||||||
App.log.warning("Received VCard without data, ignoring")
|
App.log.warning("Received VCard without data, ignoring")
|
||||||
return
|
return
|
||||||
@ -159,14 +156,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
App.log.warning("Received multiple VCards, using first one")
|
App.log.warning("Received multiple VCards, using first one")
|
||||||
|
|
||||||
val contact = contacts[0]
|
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)) {
|
if (cEntry.isAction(SyncEntry.Actions.ADD) || cEntry.isAction(SyncEntry.Actions.CHANGE)) {
|
||||||
processContact(contact, local)
|
processContact(contact, local)
|
||||||
} else {
|
} else {
|
||||||
if (local != null) {
|
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()
|
local.delete()
|
||||||
} else {
|
} else {
|
||||||
App.log.warning("Tried deleting a non-existent record: " + contact.uid)
|
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)
|
@Throws(IOException::class, ContactsStorageException::class)
|
||||||
private fun processContact(newData: Contact, local: LocalResource?): LocalResource {
|
private fun processContact(newData: Contact, local: LocalAddress?): LocalAddress {
|
||||||
var local = local
|
var local = local
|
||||||
val uuid = newData.uid
|
val uuid = newData.uid
|
||||||
// update local contact, if it exists
|
// update local contact, if it exists
|
||||||
@ -184,14 +180,14 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
|
|
||||||
if (local is LocalGroup && newData.group) {
|
if (local is LocalGroup && newData.group) {
|
||||||
// update group
|
// update group
|
||||||
val group = local as LocalGroup?
|
val group: LocalGroup = local
|
||||||
group!!.eTag = uuid
|
group!!.eTag = uuid
|
||||||
group.updateFromServer(newData)
|
group.update(newData)
|
||||||
syncResult.stats.numUpdates++
|
syncResult.stats.numUpdates++
|
||||||
|
|
||||||
} else if (local is LocalContact && !newData.group) {
|
} else if (local is LocalContact && !newData.group) {
|
||||||
// update contact
|
// update contact
|
||||||
val contact = local as LocalContact?
|
val contact: LocalContact = local
|
||||||
contact!!.eTag = uuid
|
contact!!.eTag = uuid
|
||||||
contact.update(newData)
|
contact.update(newData)
|
||||||
syncResult.stats.numUpdates++
|
syncResult.stats.numUpdates++
|
||||||
@ -212,13 +208,13 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
if (newData.group) {
|
if (newData.group) {
|
||||||
App.log.log(Level.INFO, "Creating local group", newData.uid)
|
App.log.log(Level.INFO, "Creating local group", newData.uid)
|
||||||
val group = LocalGroup(localAddressBook(), newData, uuid, uuid)
|
val group = LocalGroup(localAddressBook(), newData, uuid, uuid)
|
||||||
group.create()
|
group.add()
|
||||||
|
|
||||||
local = group
|
local = group
|
||||||
} else {
|
} else {
|
||||||
App.log.log(Level.INFO, "Creating local contact", newData.uid)
|
App.log.log(Level.INFO, "Creating local contact", newData.uid)
|
||||||
val contact = LocalContact(localAddressBook(), newData, uuid, uuid)
|
val contact = LocalContact(localAddressBook(), newData, uuid, uuid)
|
||||||
contact.create()
|
contact.add()
|
||||||
|
|
||||||
local = contact
|
local = contact
|
||||||
}
|
}
|
||||||
@ -268,15 +264,7 @@ constructor(context: Context, account: Account, settings: AccountSettings, extra
|
|||||||
|
|
||||||
val body = response.body()
|
val body = response.body()
|
||||||
if (body != null) {
|
if (body != null) {
|
||||||
val stream = body.byteStream()
|
return body.bytes()
|
||||||
try {
|
|
||||||
if (response.isSuccessful && stream != null) {
|
|
||||||
return IOUtils.toByteArray(stream)
|
|
||||||
} else
|
|
||||||
App.log.severe("Couldn't download external resource")
|
|
||||||
} finally {
|
|
||||||
stream?.close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
App.log.log(Level.SEVERE, "Couldn't download external resource", e)
|
App.log.log(Level.SEVERE, "Couldn't download external resource", e)
|
||||||
|
Loading…
Reference in New Issue
Block a user