From 3f43d2219c645da016b2ad00dd1d8f0640636fd6 Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Sun, 30 Jun 2024 19:50:31 +0200 Subject: [PATCH] Migrate Nextcloud News API to v1.3 --- .../com/readrops/api/services/Credentials.kt | 8 ++-- .../NewNextcloudNewsDataSource.kt | 32 +++++++-------- .../nextcloudnews/NewNextcloudNewsService.kt | 8 ++-- .../nextcloudnews/NextcloudNewsSyncData.kt | 6 +-- .../NextcloudNewsDataSourceTest.kt | 41 +++++-------------- .../repositories/NextcloudNewsRepository.kt | 11 ++--- .../com/readrops/db/dao/newdao/NewItemDao.kt | 4 -- 7 files changed, 38 insertions(+), 72 deletions(-) diff --git a/api/src/main/java/com/readrops/api/services/Credentials.kt b/api/src/main/java/com/readrops/api/services/Credentials.kt index a20eacb7..33026006 100644 --- a/api/src/main/java/com/readrops/api/services/Credentials.kt +++ b/api/src/main/java/com/readrops/api/services/Credentials.kt @@ -1,9 +1,9 @@ package com.readrops.api.services import com.readrops.api.services.freshrss.FreshRSSCredentials -import com.readrops.api.services.freshrss.FreshRSSService +import com.readrops.api.services.freshrss.NewFreshRSSService +import com.readrops.api.services.nextcloudnews.NewNextcloudNewsService import com.readrops.api.services.nextcloudnews.NextNewsCredentials -import com.readrops.api.services.nextcloudnews.NextNewsService import com.readrops.db.entities.account.Account import com.readrops.db.entities.account.AccountType @@ -23,8 +23,8 @@ abstract class Credentials(val authorization: String?, val url: String) { private fun getEndPoint(accountType: AccountType): String { return when (accountType) { - AccountType.FRESHRSS -> FreshRSSService.END_POINT - AccountType.NEXTCLOUD_NEWS -> NextNewsService.END_POINT + AccountType.FRESHRSS -> NewFreshRSSService.END_POINT + AccountType.NEXTCLOUD_NEWS -> NewNextcloudNewsService.END_POINT else -> throw IllegalArgumentException("Unknown account type") } } diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsDataSource.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsDataSource.kt index d8607cda..38857cc5 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsDataSource.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsDataSource.kt @@ -8,7 +8,6 @@ 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 com.readrops.db.pojo.StarItem import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -50,8 +49,7 @@ class NewNextcloudNewsDataSource(private val service: NewNextcloudNewsService) { } else { listOf( async { setItemsReadState(syncData) }, - async { setItemsStarState(StateType.STAR, syncData.starredIds) }, - async { setItemsStarState(StateType.UNSTAR, syncData.unstarredIds) } + async { setItemsStarState(syncData) }, ).awaitAll() SyncResult().apply { @@ -108,32 +106,30 @@ class NewNextcloudNewsDataSource(private val service: NewNextcloudNewsService) { if (unreadIds.isNotEmpty()) { service.setReadState( StateType.UNREAD.name.lowercase(), - mapOf("items" to unreadIds) + mapOf("itemIds" to unreadIds) ) } if (readIds.isNotEmpty()) { service.setReadState( StateType.READ.name.lowercase(), - mapOf("items" to readIds) + mapOf("itemIds" to readIds) ) } } - suspend fun setItemsStarState(stateType: StateType, itemIds: List) { - if (itemIds.isNotEmpty()) { - val body = arrayListOf>() - - for (item in itemIds) { - body += mapOf( - "feedId" to item.feedRemoteId, - "guidHash" to item.guidHash - ) - } - + suspend fun setItemsStarState(syncData: NextcloudNewsSyncData) = with(syncData) { + if (starredIds.isNotEmpty()) { service.setStarState( - stateType.name.lowercase(), - mapOf("items" to body) + StateType.STAR.name.lowercase(), + mapOf("itemIds" to starredIds) + ) + } + + if (unstarredIds.isNotEmpty()) { + service.setStarState( + StateType.UNSTAR.name.lowercase(), + mapOf("itemIds" to unstarredIds) ) } } diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsService.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsService.kt index da99abb5..5b725f5a 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsService.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NewNextcloudNewsService.kt @@ -32,18 +32,18 @@ interface NewNextcloudNewsService { @Query("type") type: Int ): List - @PUT("items/{stateType}/multiple") + @POST("items/{stateType}/multiple") @JvmSuppressWildcards suspend fun setReadState( @Path("stateType") stateType: String, @Body itemIdsMap: Map> ) - @PUT("items/{starType}/multiple") + @POST("items/{starType}/multiple") @JvmSuppressWildcards suspend fun setStarState( @Path("starType") starType: String?, - @Body body: Map>> + @Body body: Map> ) @POST("feeds") @@ -68,6 +68,6 @@ interface NewNextcloudNewsService { suspend fun renameFolder(@Path("folderId") folderId: Int, @Body folderName: Map) companion object { - const val END_POINT = "/index.php/apps/news/api/v1-2/" + const val END_POINT = "/index.php/apps/news/api/v1-3/" } } \ No newline at end of file diff --git a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsSyncData.kt b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsSyncData.kt index 24a4b41b..98a5c269 100644 --- a/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsSyncData.kt +++ b/api/src/main/java/com/readrops/api/services/nextcloudnews/NextcloudNewsSyncData.kt @@ -1,11 +1,9 @@ package com.readrops.api.services.nextcloudnews -import com.readrops.db.pojo.StarItem - data class NextcloudNewsSyncData( val lastModified: Long = 0, val readIds: List = listOf(), val unreadIds: List = listOf(), - val starredIds: List = listOf(), - val unstarredIds: List = listOf(), + val starredIds: List = listOf(), + val unstarredIds: List = listOf(), ) \ No newline at end of file diff --git a/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt b/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt index 04d2f646..02942a0b 100644 --- a/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt +++ b/api/src/test/java/com/readrops/api/services/nextcloudnews/NextcloudNewsDataSourceTest.kt @@ -6,7 +6,6 @@ import com.readrops.api.enqueueOK import com.readrops.api.enqueueStream import com.readrops.api.services.nextcloudnews.NextNewsDataSource.ItemQueryType import com.readrops.db.entities.account.Account -import com.readrops.db.pojo.StarItem import com.squareup.moshi.Moshi import com.squareup.moshi.Types import kotlinx.coroutines.test.runTest @@ -251,8 +250,8 @@ class NextcloudNewsDataSourceTest : KoinTest { val unreadBody = adapter.fromJson(unreadRequest.body)!! val readBody = adapter.fromJson(readRequest.body)!! - assertEquals(data.readIds, readBody["items"]) - assertEquals(data.unreadIds, unreadBody["items"]) + assertEquals(data.readIds, readBody["itemIds"]) + assertEquals(data.unreadIds, unreadBody["itemIds"]) } @Test @@ -260,47 +259,27 @@ class NextcloudNewsDataSourceTest : KoinTest { mockServer.enqueueOK() mockServer.enqueueOK() - val starList = listOf( - StarItem("remote1", "guid1"), - StarItem("remote2", "guid2") - ) - nextcloudNewsDataSource.setItemsStarState( - NewNextcloudNewsDataSource.StateType.STAR, - starList + val data = NextcloudNewsSyncData( + starredIds = listOf(15, 16, 17), + unstarredIds = listOf(18, 19, 20) ) + nextcloudNewsDataSource.setItemsStarState(data) val starRequest = mockServer.takeRequest() - - val unstarList = listOf( - StarItem("remote3", "guid3"), - StarItem("remote4", "guid4") - ) - nextcloudNewsDataSource.setItemsStarState( - NewNextcloudNewsDataSource.StateType.UNSTAR, - unstarList - ) - val unstarRequest = mockServer.takeRequest() val type = Types.newParameterizedType( Map::class.java, String::class.java, - Types.newParameterizedType( - List::class.java, - Types.newParameterizedType( - Map::class.java, - String::class.java, - String::class.java - ) - ) + Types.newParameterizedType(List::class.java, Int::class.javaObjectType) ) - val adapter = moshi.adapter>>>(type) + val adapter = moshi.adapter>>(type) val starBody = adapter.fromJson(starRequest.body)!! val unstarBody = adapter.fromJson(unstarRequest.body)!! - assertEquals(starList[0].feedRemoteId, starBody.values.first().first()["feedId"]) - assertEquals(unstarList[0].feedRemoteId, unstarBody.values.first().first()["feedId"]) + assertEquals(data.starredIds, starBody["itemIds"]) + assertEquals(data.unstarredIds, unstarBody["itemIds"]) } } \ 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 3d97f4aa..f60d888e 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 @@ -40,19 +40,16 @@ class NextcloudNewsRepository( val itemStateChanges = database.newItemStateChangeDao() .selectItemStateChanges(account.id) - val starredIds = itemStateChanges.filter { it.starChange && it.starred } - .map { it.remoteId } - val unstarredIds = itemStateChanges.filter { it.starChange && !it.starred } - .map { it.remoteId } - val syncData = NextcloudNewsSyncData( lastModified = account.lastModified, readIds = itemStateChanges.filter { it.readChange && it.read } .map { it.remoteId.toInt() }, unreadIds = itemStateChanges.filter { it.readChange && !it.read } .map { it.remoteId.toInt() }, - starredIds = database.newItemDao().selectStarChanges(starredIds, account.id), - unstarredIds = database.newItemDao().selectStarChanges(unstarredIds, account.id) + starredIds = itemStateChanges.filter { it.starChange && it.starred } + .map { it.remoteId.toInt() }, + unstarredIds = itemStateChanges.filter { it.starChange && !it.starred } + .map { it.remoteId.toInt() } ) val syncType = if (account.lastModified != 0L) { 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 b74b2f0e..9ecaf196 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 @@ -11,7 +11,6 @@ import com.readrops.db.entities.Folder import com.readrops.db.entities.Item import com.readrops.db.entities.ItemState import com.readrops.db.pojo.ItemWithFeed -import com.readrops.db.pojo.StarItem import kotlinx.coroutines.flow.Flow @Dao @@ -67,7 +66,4 @@ abstract class NewItemDao : NewBaseDao { @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 - - @Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where Item.remoteId In (:remoteIds) And account_id = :accountId") - abstract suspend fun selectStarChanges(remoteIds: List, accountId: Int): List } \ No newline at end of file