From 5bff505fc3b6809386110a5ace21b7b0b4ace2e0 Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Sun, 16 Jun 2024 13:22:19 +0200 Subject: [PATCH] Add Nextcloud initial synchronization --- .../nextcloudnews/NextNewsCredentials.kt | 6 +- .../repositories/NextcloudNewsRepository.kt | 57 +++++++++++++++++-- .../com/readrops/db/dao/newdao/NewItemDao.kt | 6 ++ 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsCredentials.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsCredentials.kt index 21c86283..5c969f4c 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsCredentials.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextNewsCredentials.kt @@ -3,6 +3,6 @@ package com.readrops.api.services.nextcloudnews import com.readrops.api.services.Credentials class NextNewsCredentials(login: String?, password: String?, url: String): - Credentials((login != null && password != null).let { - okhttp3.Credentials.basic(login!!, password!!) - }, url) \ No newline at end of file + Credentials(if (login != null && password != null) { + okhttp3.Credentials.basic(login, password) + } else null, url) \ No newline at end of file diff --git a/appcompose/src/main/java/com/readrops/app/compose/repositories/NextcloudNewsRepository.kt b/appcompose/src/main/java/com/readrops/app/compose/repositories/NextcloudNewsRepository.kt index a3a92a76..8cea4ec1 100644 --- a/appcompose/src/main/java/com/readrops/app/compose/repositories/NextcloudNewsRepository.kt +++ b/appcompose/src/main/java/com/readrops/app/compose/repositories/NextcloudNewsRepository.kt @@ -2,10 +2,15 @@ package com.readrops.app.compose.repositories import com.readrops.api.services.Credentials import com.readrops.api.services.SyncResult +import com.readrops.api.services.SyncType import com.readrops.api.services.nextcloudnews.NewNextcloudNewsDataSource +import com.readrops.api.services.nextcloudnews.NextcloudNewsSyncData import com.readrops.api.utils.AuthInterceptor +import com.readrops.app.compose.util.Utils import com.readrops.db.Database import com.readrops.db.entities.Feed +import com.readrops.db.entities.Folder +import com.readrops.db.entities.Item import com.readrops.db.entities.account.Account import org.koin.core.component.KoinComponent import org.koin.core.component.get @@ -27,12 +32,15 @@ class NextcloudNewsRepository( override suspend fun synchronize( selectedFeeds: List, onUpdate: (Feed) -> Unit - ): Pair { - TODO("Not yet implemented") - } + ): Pair = throw NotImplementedError("This method can't be called here") override suspend fun synchronize(): SyncResult { - TODO("Not yet implemented") + return dataSource.synchronize(SyncType.INITIAL_SYNC, NextcloudNewsSyncData()).apply { + insertFolders(folders) + insertFeeds(feeds) + + insertItems(items, true) + } } override suspend fun insertNewFeeds( @@ -41,4 +49,45 @@ class NextcloudNewsRepository( ): ErrorResult { TODO("Not yet implemented") } + + private suspend fun insertFolders(folders: List) { + folders.forEach { it.accountId = account.id } + database.newFolderDao().upsertFolders(folders, account) + } + + private suspend fun insertFeeds(feeds: List): List { + feeds.forEach { it.accountId = account.id } + return database.newFeedDao().upsertFeeds(feeds, account) + } + + private suspend fun insertItems(items: List, initialSync: Boolean) { + val itemsToInsert = arrayListOf() + val itemsFeedsIds = mutableMapOf() + + for (item in items) { + val feedId: Int + if (itemsFeedsIds.containsKey(item.feedRemoteId)) { + feedId = itemsFeedsIds.getValue(item.feedRemoteId) + } else { + feedId = + database.newFeedDao().selectRemoteFeedLocalId(item.feedRemoteId!!, account.id) + itemsFeedsIds[item.feedRemoteId] = feedId + } + + if (!initialSync && feedId > 0 && database.newItemDao() + .itemExists(item.remoteId!!, feedId) + ) { + database.newItemDao() + .updateReadAndStarState(item.remoteId!!, item.isRead, item.isStarred) + } + + item.feedId = feedId + item.readTime = Utils.readTimeFromString(item.content.orEmpty()) + itemsToInsert += item + } + + if (itemsToInsert.isNotEmpty()) { + database.newItemDao().insert(itemsToInsert) + } + } } \ No newline at end of file diff --git a/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt b/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt index 9c04f24e..99f9d62b 100644 --- a/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt +++ b/db/src/main/java/com/readrops/db/dao/newdao/NewItemDao.kt @@ -28,6 +28,9 @@ abstract class NewItemDao : NewBaseDao { @Query("Update Item Set starred = :starred Where id = :itemId") abstract suspend fun updateStarState(itemId: Int, starred: Boolean) + @Query("Update Item set read = :read, starred = :starred Where remoteId = :remoteId") + abstract suspend fun updateReadAndStarState(remoteId: String, read: Boolean, starred: Boolean) + @Query("Update Item set read = 1 Where feed_id IN (Select id From Feed Where account_id = :accountId)") abstract suspend fun setAllItemsRead(accountId: Int) @@ -54,4 +57,7 @@ abstract class NewItemDao : NewBaseDao { @RawQuery(observedEntities = [Item::class]) abstract fun selectFeedUnreadItemsCount(query: SupportSQLiteQuery): Flow> + + @Query("Select case When :guid In (Select guid From Item Inner Join Feed on Item.feed_id = Feed.id and account_id = :accountId) Then 1 else 0 end") + abstract suspend fun itemExists(guid: String, accountId: Int): Boolean } \ No newline at end of file