mirror of
https://github.com/etesync/android
synced 2024-11-15 20:38:58 +00:00
CalendarSyncAdapter: implement syncing etebase calendars.
This commit is contained in:
parent
2069e9b215
commit
1c284bce91
@ -13,11 +13,13 @@ import android.content.ContentProviderClient
|
||||
import android.content.ContentProviderOperation
|
||||
import android.content.ContentUris
|
||||
import android.content.ContentValues
|
||||
import android.graphics.Color.parseColor
|
||||
import android.net.Uri
|
||||
import android.os.RemoteException
|
||||
import android.provider.CalendarContract
|
||||
import android.provider.CalendarContract.*
|
||||
import at.bitfire.ical4android.*
|
||||
import com.etesync.syncadapter.CachedCollection
|
||||
import com.etesync.syncadapter.log.Logger
|
||||
import com.etesync.syncadapter.model.JournalEntity
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
@ -50,6 +52,21 @@ class LocalCalendar private constructor(
|
||||
return AndroidCalendar.create(account, provider, values)
|
||||
}
|
||||
|
||||
fun create(account: Account, provider: ContentProviderClient, cachedCollection: CachedCollection): Uri {
|
||||
val values = valuesFromCachedCollection(cachedCollection, true)
|
||||
|
||||
// ACCOUNT_NAME and ACCOUNT_TYPE are required (see docs)! If it's missing, other apps will crash.
|
||||
values.put(Calendars.ACCOUNT_NAME, account.name)
|
||||
values.put(Calendars.ACCOUNT_TYPE, account.type)
|
||||
values.put(Calendars.OWNER_ACCOUNT, account.name)
|
||||
|
||||
// flag as visible & synchronizable at creation, might be changed by user at any time
|
||||
values.put(Calendars.VISIBLE, 1)
|
||||
values.put(Calendars.SYNC_EVENTS, 1)
|
||||
|
||||
return AndroidCalendar.create(account, provider, values)
|
||||
}
|
||||
|
||||
fun findByName(account: Account, provider: ContentProviderClient, factory: Factory, name: String): LocalCalendar?
|
||||
= AndroidCalendar.find(account, provider, factory, Calendars.NAME + "==?", arrayOf(name)).firstOrNull()
|
||||
|
||||
@ -85,6 +102,30 @@ class LocalCalendar private constructor(
|
||||
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(intArrayOf(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE), ", "))
|
||||
return values
|
||||
}
|
||||
|
||||
private fun valuesFromCachedCollection(cachedCollection: CachedCollection, withColor: Boolean): ContentValues {
|
||||
val values = ContentValues()
|
||||
val col = cachedCollection.col
|
||||
val meta = cachedCollection.meta
|
||||
values.put(Calendars.NAME, col.uid)
|
||||
values.put(Calendars.CALENDAR_DISPLAY_NAME, meta.name)
|
||||
|
||||
if (withColor)
|
||||
values.put(Calendars.CALENDAR_COLOR, if (!meta.color.isNullOrBlank()) parseColor(meta.color) else defaultColor)
|
||||
|
||||
if (col.accessLevel == "ro")
|
||||
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ)
|
||||
else {
|
||||
values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER)
|
||||
values.put(Calendars.CAN_MODIFY_TIME_ZONE, 1)
|
||||
values.put(Calendars.CAN_ORGANIZER_RESPOND, 1)
|
||||
}
|
||||
|
||||
values.put(Calendars.ALLOWED_REMINDERS, Reminders.METHOD_ALERT)
|
||||
values.put(Calendars.ALLOWED_AVAILABILITY, StringUtils.join(intArrayOf(Reminders.AVAILABILITY_TENTATIVE, Reminders.AVAILABILITY_FREE, Reminders.AVAILABILITY_BUSY), ","))
|
||||
values.put(Calendars.ALLOWED_ATTENDEE_TYPES, StringUtils.join(intArrayOf(CalendarContract.Attendees.TYPE_OPTIONAL, CalendarContract.Attendees.TYPE_REQUIRED, CalendarContract.Attendees.TYPE_RESOURCE), ", "))
|
||||
return values
|
||||
}
|
||||
}
|
||||
|
||||
override val url: String?
|
||||
@ -93,6 +134,9 @@ class LocalCalendar private constructor(
|
||||
fun update(journalEntity: JournalEntity, updateColor: Boolean) =
|
||||
update(valuesFromCollectionInfo(journalEntity, updateColor))
|
||||
|
||||
fun update(cachedCollection: CachedCollection, updateColor: Boolean) =
|
||||
update(valuesFromCachedCollection(cachedCollection, updateColor))
|
||||
|
||||
|
||||
override fun findDeleted() =
|
||||
queryEvents("${Events.DELETED}!=0 AND ${Events.ORIGINAL_ID} IS NULL", null)
|
||||
|
@ -13,10 +13,7 @@ import android.os.Bundle
|
||||
import android.provider.CalendarContract
|
||||
import at.bitfire.ical4android.AndroidCalendar
|
||||
import at.bitfire.ical4android.CalendarStorageException
|
||||
import com.etesync.syncadapter.AccountSettings
|
||||
import com.etesync.syncadapter.App
|
||||
import com.etesync.syncadapter.Constants
|
||||
import com.etesync.syncadapter.R
|
||||
import com.etesync.syncadapter.*
|
||||
import com.etesync.syncadapter.log.Logger
|
||||
import com.etesync.syncadapter.model.CollectionInfo
|
||||
import com.etesync.syncadapter.model.JournalEntity
|
||||
@ -42,7 +39,11 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
|
||||
|
||||
RefreshCollections(account, CollectionInfo.Type.CALENDAR).run()
|
||||
|
||||
updateLocalCalendars(provider, account, settings)
|
||||
if (settings.isLegacy) {
|
||||
legacyUpdateLocalCalendars(provider, account, settings)
|
||||
} else {
|
||||
updateLocalCalendars(provider, account, settings)
|
||||
}
|
||||
|
||||
val principal = settings.uri?.toHttpUrlOrNull()!!
|
||||
|
||||
@ -56,8 +57,52 @@ class CalendarsSyncAdapterService : SyncAdapterService() {
|
||||
Logger.log.info("Calendar sync complete")
|
||||
}
|
||||
|
||||
@Throws(CalendarStorageException::class)
|
||||
private fun updateLocalCalendars(provider: ContentProviderClient, account: Account, settings: AccountSettings) {
|
||||
val remote = HashMap<String, CachedCollection>()
|
||||
val etebaseLocalCache = EtebaseLocalCache.getInstance(context, account.name)
|
||||
val collections: List<CachedCollection>
|
||||
synchronized(etebaseLocalCache) {
|
||||
val httpClient = HttpClient.Builder(context, settings).setForeground(false).build()
|
||||
val etebase = EtebaseLocalCache.getEtebase(context, httpClient.okHttpClient, settings)
|
||||
val colMgr = etebase.collectionManager
|
||||
|
||||
collections = etebaseLocalCache.collectionList(colMgr).filter { it.meta.collectionType == Constants.ETEBASE_TYPE_CALENDAR }
|
||||
}
|
||||
|
||||
for (collection in collections) {
|
||||
remote[collection.col.uid] = collection
|
||||
}
|
||||
|
||||
val local = AndroidCalendar.find(account, provider, LocalCalendar.Factory, null, null)
|
||||
|
||||
val updateColors = settings.manageCalendarColors
|
||||
|
||||
// delete obsolete local calendar
|
||||
for (calendar in local) {
|
||||
val url = calendar.name
|
||||
val collection = remote[url]
|
||||
if (collection == null) {
|
||||
Logger.log.fine("Deleting obsolete local calendar $url")
|
||||
calendar.delete()
|
||||
} else {
|
||||
// remote CollectionInfo found for this local collection, update data
|
||||
Logger.log.fine("Updating local calendar $url")
|
||||
calendar.update(collection, updateColors)
|
||||
// we already have a local calendar for this remote collection, don't take into consideration anymore
|
||||
remote.remove(url)
|
||||
}
|
||||
}
|
||||
|
||||
// create new local calendars
|
||||
for (url in remote.keys) {
|
||||
val cachedCollection = remote[url]!!
|
||||
Logger.log.info("Adding local calendar list $cachedCollection")
|
||||
LocalCalendar.create(account, provider, cachedCollection)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(CalendarStorageException::class)
|
||||
private fun legacyUpdateLocalCalendars(provider: ContentProviderClient, account: Account, settings: AccountSettings) {
|
||||
val data = (context.applicationContext as App).data
|
||||
val service = JournalModel.Service.fetchOrCreate(data, account.name, CollectionInfo.Type.CALENDAR)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user