mirror of
https://github.com/etesync/android
synced 2025-07-04 13:52:40 +00:00
142 lines
6.3 KiB
Kotlin
142 lines
6.3 KiB
Kotlin
/*
|
||
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||
* All rights reserved. This program and the accompanying materials
|
||
* are made available under the terms of the GNU Public License v3.0
|
||
* which accompanies this distribution, and is available at
|
||
* http://www.gnu.org/licenses/gpl.html
|
||
*/
|
||
package com.etesync.syncadapter.syncadapter
|
||
|
||
import android.accounts.Account
|
||
import android.content.*
|
||
import android.os.Bundle
|
||
import android.provider.CalendarContract
|
||
import at.bitfire.ical4android.AndroidCalendar
|
||
import at.bitfire.ical4android.CalendarStorageException
|
||
import com.etesync.syncadapter.*
|
||
import com.etesync.syncadapter.log.Logger
|
||
import com.etesync.syncadapter.model.CollectionInfo
|
||
import com.etesync.syncadapter.model.JournalEntity
|
||
import com.etesync.syncadapter.model.JournalModel
|
||
import com.etesync.syncadapter.resource.LocalCalendar
|
||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||
import java.util.*
|
||
|
||
class CalendarsSyncAdapterService : SyncAdapterService() {
|
||
override fun syncAdapter(): AbstractThreadedSyncAdapter {
|
||
return SyncAdapter(this)
|
||
}
|
||
|
||
|
||
private class SyncAdapter(context: Context) : SyncAdapterService.SyncAdapter(context) {
|
||
override fun onPerformSyncDo(account: Account, extras: Bundle, authority: String, provider: ContentProviderClient, syncResult: SyncResult) {
|
||
val settings = AccountSettings(context, account)
|
||
if (!extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL) && !checkSyncConditions(settings))
|
||
return
|
||
|
||
RefreshCollections(account, CollectionInfo.Type.CALENDAR).run()
|
||
|
||
if (settings.isLegacy) {
|
||
legacyUpdateLocalCalendars(provider, account, settings)
|
||
} else {
|
||
updateLocalCalendars(provider, account, settings)
|
||
}
|
||
|
||
val principal = settings.uri?.toHttpUrlOrNull()!!
|
||
|
||
for (calendar in AndroidCalendar.find(account, provider, LocalCalendar.Factory, CalendarContract.Calendars.SYNC_EVENTS + "!=0", null)) {
|
||
Logger.log.info("Synchronizing calendar #" + calendar.id + ", URL: " + calendar.name)
|
||
CalendarSyncManager(context, account, settings, extras, authority, syncResult, calendar, principal).use {
|
||
it.performSync()
|
||
}
|
||
}
|
||
|
||
Logger.log.info("Calendar sync complete")
|
||
}
|
||
|
||
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.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)
|
||
|
||
val remote = HashMap<String, JournalEntity>()
|
||
val remoteJournals = JournalEntity.getJournals(data, service)
|
||
for (journalEntity in remoteJournals) {
|
||
remote[journalEntity.uid] = journalEntity
|
||
}
|
||
|
||
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 journalEntity = remote[url]
|
||
if (journalEntity == 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 with $journalEntity")
|
||
calendar.update(journalEntity, 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 journalEntity = remote[url]!!
|
||
Logger.log.info("Adding local calendar list $journalEntity")
|
||
LocalCalendar.create(account, provider, journalEntity)
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|