From 608f1ff37180c57d423b5609774aaecd68f73c14 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 25 Aug 2020 18:51:57 +0300 Subject: [PATCH] Sync collections and show them in the account page. --- .../etesync/syncadapter/EtebaseLocalCache.kt | 8 +-- .../syncadapter/SyncAdapterService.kt | 66 ++++++++++++++----- .../etesync/syncadapter/ui/AccountActivity.kt | 11 ++-- 3 files changed, 59 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/etesync/syncadapter/EtebaseLocalCache.kt b/app/src/main/java/com/etesync/syncadapter/EtebaseLocalCache.kt index c214a090..8eb762d9 100644 --- a/app/src/main/java/com/etesync/syncadapter/EtebaseLocalCache.kt +++ b/app/src/main/java/com/etesync/syncadapter/EtebaseLocalCache.kt @@ -51,13 +51,13 @@ class EtebaseLocalCache private constructor(context: Context, username: String) return if (stokenFile.exists()) stokenFile.readText() else null } - fun collectionList(colMgr: CollectionManager): List { + fun collectionList(colMgr: CollectionManager, withDeleted: Boolean = false): List { return colsDir.list().map { val colDir = File(colsDir, it) val colFile = File(colDir, "col") val content = colFile.readBytes() colMgr.cacheLoad(content) - } + }.filter { withDeleted || !it.isDeleted } } fun collectionSet(colMgr: CollectionManager, collection: Collection) { @@ -74,13 +74,13 @@ class EtebaseLocalCache private constructor(context: Context, username: String) colDir.deleteRecursively() } - fun itemList(itemMgr: ItemManager, colUid: String): List { + fun itemList(itemMgr: ItemManager, colUid: String, withDeleted: Boolean = false): List { val itemsDir = getCollectionItemsDir(colUid) return itemsDir.list().map { val itemFile = File(itemsDir, it) val content = itemFile.readBytes() itemMgr.cacheLoad(content) - } + }.filter { withDeleted || !it.isDeleted } } fun itemSet(itemMgr: ItemManager, colUid: String, item: Item) { diff --git a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt index 45c228d2..ecc1bd6e 100644 --- a/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt +++ b/app/src/main/java/com/etesync/syncadapter/syncadapter/SyncAdapterService.kt @@ -22,6 +22,7 @@ import androidx.core.app.NotificationManagerCompat import androidx.core.util.Pair import at.bitfire.ical4android.CalendarStorageException import at.bitfire.vcard4android.ContactsStorageException +import com.etebase.client.FetchOptions import com.etesync.syncadapter.* import com.etesync.journalmanager.Crypto import com.etesync.journalmanager.Exceptions @@ -208,30 +209,59 @@ abstract class SyncAdapterService : Service() { val settings = AccountSettings(context, account) val httpClient = HttpClient.Builder(context, settings).setForeground(false).build() - val journalsManager = JournalManager(httpClient.okHttpClient, settings.uri?.toHttpUrlOrNull()!!) - - var journals = journalFetcher.list(journalsManager, settings, serviceType) - - if (journals.isEmpty()) { - journals = LinkedList() - try { - val info = CollectionInfo.defaultForServiceType(serviceType) - val uid = JournalManager.Journal.genUid() - info.uid = uid - val crypto = Crypto.CryptoManager(info.version, settings.password(), uid) - val journal = JournalManager.Journal(crypto, info.toJson(), uid) - journalsManager.create(journal) - journals.add(Pair(journal, info)) - } catch (e: Exceptions.AssociateNotAllowedException) { - // Skip for now + if (settings.isLegacy) { + val journalsManager = JournalManager(httpClient.okHttpClient, settings.uri?.toHttpUrlOrNull()!!) + + var journals = journalFetcher.list(journalsManager, settings, serviceType) + + if (journals.isEmpty()) { + journals = LinkedList() + try { + val info = CollectionInfo.defaultForServiceType(serviceType) + val uid = JournalManager.Journal.genUid() + info.uid = uid + val crypto = Crypto.CryptoManager(info.version, settings.password(), uid) + val journal = JournalManager.Journal(crypto, info.toJson(), uid) + journalsManager.create(journal) + journals.add(Pair(journal, info)) + } catch (e: Exceptions.AssociateNotAllowedException) { + // Skip for now + } + } + + legacySaveCollections(journals) + + httpClient.close() + return + } + + + val etebaseLocalCache = EtebaseLocalCache.getInstance(context, account.name) + synchronized(etebaseLocalCache) { + val etebase = EtebaseLocalCache.getEtebase(context, httpClient.okHttpClient, settings) + val colMgr = etebase.collectionManager + var stoken = etebaseLocalCache.loadStoken() + var done = false + while (!done) { + val colList = colMgr.list(FetchOptions().stoken(stoken)) + for (col in colList.data) { + etebaseLocalCache.collectionSet(colMgr, col) + } + + for (col in colList.removedMemberships) { + etebaseLocalCache.collectionUnset(colMgr, col.uid()) + } + + stoken = colList.stoken + done = colList.isDone + etebaseLocalCache.saveStoken(stoken!!) } } - saveCollections(journals) httpClient.close() } - private fun saveCollections(journals: Iterable>) { + private fun legacySaveCollections(journals: Iterable>) { val data = (context.applicationContext as App).data val service = JournalModel.Service.fetchOrCreate(data, account.name, serviceType) diff --git a/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt b/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt index 0afb770b..cfcde47a 100644 --- a/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt +++ b/app/src/main/java/com/etesync/syncadapter/ui/AccountActivity.kt @@ -373,7 +373,9 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe val isReadOnly = accessLevel == "ro" val isAdmin = accessLevel == "adm" - CollectionListItemInfo(it.uid, type, meta.name, meta.description ?: "", parseColor(meta.color), isReadOnly, isAdmin, null) + val metaColor = meta.color + val color = if (metaColor != null && metaColor != "") parseColor(metaColor) else null + CollectionListItemInfo(it.uid, type, meta.name, meta.description ?: "", color, isReadOnly, isAdmin, null) }.filterNotNull() } @@ -423,12 +425,13 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe } val etebaseLocalCache = EtebaseLocalCache.getInstance(context, account.name) - val etebase = EtebaseLocalCache.getEtebase(context, settings) + val httpClient = HttpClient.Builder(context).build().okHttpClient + val etebase = EtebaseLocalCache.getEtebase(context, httpClient, settings) val colMgr = etebase.collectionManager info.carddav = AccountInfo.ServiceInfo() info.carddav!!.refreshing = ContentResolver.isSyncActive(account, App.addressBooksAuthority) - info.carddav!!.infos = getCollections(etebaseLocalCache, colMgr, CollectionInfo.Type.TASKS) + info.carddav!!.infos = getCollections(etebaseLocalCache, colMgr, CollectionInfo.Type.ADDRESS_BOOK) val accountManager = AccountManager.get(context) for (addrBookAccount in accountManager.getAccountsByType(App.addressBookAccountType)) { @@ -443,7 +446,7 @@ class AccountActivity : BaseActivity(), Toolbar.OnMenuItemClickListener, PopupMe info.caldav = AccountInfo.ServiceInfo() info.caldav!!.refreshing = ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) - info.caldav!!.infos = getCollections(etebaseLocalCache, colMgr, CollectionInfo.Type.TASKS) + info.caldav!!.infos = getCollections(etebaseLocalCache, colMgr, CollectionInfo.Type.CALENDAR) info.taskdav = AccountInfo.ServiceInfo() info.taskdav!!.refreshing = OPENTASK_PROVIDERS.any {