Add support for adding a new feed in a specific folder for FreshRSS and Nextcloud News

This commit is contained in:
Shinokuni 2024-11-11 21:33:28 +01:00
parent 7dcb2cbb29
commit c7b26a65b1
7 changed files with 62 additions and 21 deletions

View File

@ -105,12 +105,13 @@ class FreshRSSDataSource(private val service: FreshRSSService) {
} }
} }
suspend fun createFeed(token: String, feedUrl: String) { suspend fun createFeed(token: String, feedUrl: String, folderId: String?) {
service.createOrDeleteFeed(token, FEED_PREFIX + feedUrl, "subscribe") // no feed here of the folder prefix for the folder id
service.createOrDeleteFeed(token, FEED_PREFIX + feedUrl, "subscribe", folderId)
} }
suspend fun deleteFeed(token: String, feedUrl: String) { suspend fun deleteFeed(token: String, feedUrl: String) {
service.createOrDeleteFeed(token, FEED_PREFIX + feedUrl, "unsubscribe") service.createOrDeleteFeed(token, FEED_PREFIX + feedUrl, "unsubscribe", null)
} }
suspend fun updateFeed(token: String, feedUrl: String, title: String, folderId: String) { suspend fun updateFeed(token: String, feedUrl: String, title: String, folderId: String) {

View File

@ -31,29 +31,49 @@ interface FreshRSSService {
suspend fun getFolders(): List<Folder> suspend fun getFolders(): List<Folder>
@GET("reader/api/0/stream/contents/user/-/state/com.google/reading-list") @GET("reader/api/0/stream/contents/user/-/state/com.google/reading-list")
suspend fun getItems(@Query("xt") excludeTarget: List<String>?, @Query("n") max: Int, suspend fun getItems(
@Query("ot") lastModified: Long?): List<Item> @Query("xt") excludeTarget: List<String>?,
@Query("n") max: Int,
@Query("ot") lastModified: Long?
): List<Item>
@GET("reader/api/0/stream/contents/user/-/state/com.google/starred") @GET("reader/api/0/stream/contents/user/-/state/com.google/starred")
suspend fun getStarredItems(@Query("n") max: Int): List<Item> suspend fun getStarredItems(@Query("n") max: Int): List<Item>
@GET("reader/api/0/stream/items/ids") @GET("reader/api/0/stream/items/ids")
suspend fun getItemsIds(@Query("xt") excludeTarget: String?, @Query("s") includeTarget: String?, suspend fun getItemsIds(
@Query("n") max: Int): List<String> @Query("xt") excludeTarget: String?,
@Query("s") includeTarget: String?,
@Query("n") max: Int
): List<String>
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/edit-tag") @POST("reader/api/0/edit-tag")
suspend fun setItemsState(@Field("T") token: String, @Field("a") addAction: String?, suspend fun setItemsState(
@Field("r") removeAction: String?, @Field("i") itemIds: List<String>) @Field("T") token: String,
@Field("a") addAction: String?,
@Field("r") removeAction: String?,
@Field("i") itemIds: List<String>
)
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/subscription/edit") @POST("reader/api/0/subscription/edit")
suspend fun createOrDeleteFeed(@Field("T") token: String, @Field("s") feedUrl: String, @Field("ac") action: String) suspend fun createOrDeleteFeed(
@Field("T") token: String,
@Field("s") feedUrl: String,
@Field("ac") action: String,
@Field("a") folderId: String?
)
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/subscription/edit") @POST("reader/api/0/subscription/edit")
suspend fun updateFeed(@Field("T") token: String, @Field("s") feedUrl: String, @Field("t") title: String, suspend fun updateFeed(
@Field("a") folderId: String, @Field("ac") action: String) @Field("T") token: String,
@Field("s") feedUrl: String,
@Field("t") title: String,
@Field("a") folderId: String,
@Field("ac") action: String
)
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/edit-tag") @POST("reader/api/0/edit-tag")
@ -61,7 +81,11 @@ interface FreshRSSService {
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/rename-tag") @POST("reader/api/0/rename-tag")
suspend fun updateFolder(@Field("T") token: String, @Field("s") folderId: String, @Field("dest") newFolderId: String) suspend fun updateFolder(
@Field("T") token: String,
@Field("s") folderId: String,
@Field("dest") newFolderId: String
)
@FormUrlEncoded @FormUrlEncoded
@POST("reader/api/0/disable-tag") @POST("reader/api/0/disable-tag")

View File

@ -179,11 +179,12 @@ class FreshRSSDataSourceTest : KoinTest {
fun createFeedTest() = runTest { fun createFeedTest() = runTest {
mockServer.enqueueOK() mockServer.enqueueOK()
freshRSSDataSource.createFeed("token", "https://feed.url") freshRSSDataSource.createFeed("token", "https://feed.url", "feed/1")
val request = mockServer.takeRequest() val request = mockServer.takeRequest()
with(request.body.readUtf8()) { with(request.body.readUtf8()) {
assertTrue { contains("T=token") } assertTrue { contains("T=token") }
assertTrue { contains("a=feed%2F1") }
assertTrue { assertTrue {
contains( contains(
"s=${ "s=${

View File

@ -136,13 +136,13 @@ class NextcloudNewsDataSourceTest : KoinTest {
val stream = TestUtils.loadResource("services/nextcloudnews/adapters/feeds.json") val stream = TestUtils.loadResource("services/nextcloudnews/adapters/feeds.json")
mockServer.enqueueOKStream(stream) mockServer.enqueueOKStream(stream)
val feeds = nextcloudNewsDataSource.createFeed("https://news.ycombinator.com/rss", null) val feeds = nextcloudNewsDataSource.createFeed("https://news.ycombinator.com/rss", 100)
val request = mockServer.takeRequest() val request = mockServer.takeRequest()
assertTrue { feeds.isNotEmpty() } assertTrue { feeds.isNotEmpty() }
with(request.requestUrl!!) { with(request.requestUrl!!) {
assertEquals("https://news.ycombinator.com/rss", queryParameter("url")) assertEquals("https://news.ycombinator.com/rss", queryParameter("url"))
assertEquals(null, queryParameter("folderId")) assertEquals("100", queryParameter("folderId"))
} }
} }

View File

@ -101,7 +101,13 @@ class NewFeedScreenModel(
screenModelScope.launch(dispatcher) { screenModelScope.launch(dispatcher) {
insertFeeds(state.value.parsingResults insertFeeds(state.value.parsingResults
.filter { it.isSelected } .filter { it.isSelected }
.map { Feed(url = it.url, folderId = it.folderId) }) .map {
Feed(
url = it.url,
folderId = it.folderId,
remoteFolderId = it.folder?.remoteId
)
})
} }
} else { } else {
when { when {
@ -131,7 +137,15 @@ class NewFeedScreenModel(
try { try {
if (dataSource.isUrlRSSResource(url)) { if (dataSource.isUrlRSSResource(url)) {
insertFeeds(listOf(Feed(url = url, folderId = state.value.folderId))) insertFeeds(
listOf(
Feed(
url = url,
folderId = state.value.folderId,
remoteFolderId = state.value.selectedFolder?.remoteId
)
)
)
} else { } else {
val rssUrls = HtmlParser.getFeedLink(url, get()) val rssUrls = HtmlParser.getFeedLink(url, get())
@ -144,7 +158,8 @@ class NewFeedScreenModel(
listOf( listOf(
Feed( Feed(
url = rssUrls.first().url, url = rssUrls.first().url,
folderId = state.value.folderId folderId = state.value.folderId,
remoteFolderId = state.value.selectedFolder?.remoteId
) )
) )
) )

View File

@ -95,7 +95,7 @@ class FreshRSSRepository(
onUpdate(newFeed) onUpdate(newFeed)
try { try {
dataSource.createFeed(account.writeToken!!, newFeed.url!!) dataSource.createFeed(account.writeToken!!, newFeed.url!!, newFeed.remoteFolderId)
} catch (e: Exception) { } catch (e: Exception) {
errors[newFeed] = e errors[newFeed] = e
} }

View File

@ -94,7 +94,7 @@ class NextcloudNewsRepository(
onUpdate(newFeed) onUpdate(newFeed)
try { try {
val feeds = dataSource.createFeed(newFeed.url!!, null) val feeds = dataSource.createFeed(newFeed.url!!, newFeed.remoteFolderId?.toInt())
insertFeeds(feeds) insertFeeds(feeds)
} catch (e: Exception) { } catch (e: Exception) {
errors[newFeed] = e errors[newFeed] = e