Skip to content

Commit 57a344c

Browse files
committed
Only fetch 10k articles at most from categories
- On refresh for a feed or folder in FreshRSS, cap the fetch count to 10,000 - Once collected, only fetch the articles that are missing from the database.
1 parent 45692e2 commit 57a344c

File tree

7 files changed

+31
-14
lines changed

7 files changed

+31
-14
lines changed

capy/src/main/java/com/jocmp/capy/accounts/reader/ReaderAccountDelegate.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ internal class ReaderAccountDelegate(
5353
} else {
5454
refreshCategoryArticles(filter)
5555
}
56+
57+
fetchMissingArticles()
5658
}
5759
}
5860

@@ -206,7 +208,6 @@ internal class ReaderAccountDelegate(
206208
refreshFeeds()
207209
refreshArticleState()
208210
fetchPaginatedArticles(since = since, stream = Stream.Read())
209-
fetchMissingArticles()
210211
}
211212

212213
private fun upsertTaggings(subscription: Subscription) {
@@ -270,17 +271,21 @@ internal class ReaderAccountDelegate(
270271
}
271272

272273
/**
273-
* This is a slightly different algorithm that `refreshTopLevelArticles`.
274+
* This is a slightly different algorithm than [refreshTopLevelArticles].
274275
*
275-
* - Assume the category (folder or feed) exists so it skips refreshing
276-
* the subscription list
277-
* - Refresh all IDs in a given feed and save its content
276+
* - Assume the category (folder or feed) exists so it skips refreshing the subscription list
277+
* - Fetches up to 10k IDs
278+
* - On return, the [fetchMissingArticles] will only fetch articles that are not already
279+
* saved
278280
*/
279281
private suspend fun refreshCategoryArticles(filter: ArticleFilter) {
280282
val stream = filter.toStream(source)
281283

282284
refreshArticleState()
283-
fetchPaginatedArticles(stream = stream)
285+
286+
withResult(googleReader.streamItemsIDs(stream = stream)) { result ->
287+
articleRecords.createStatuses(articleIDs = result.itemRefs.map { it.hexID })
288+
}
284289
}
285290

286291
private suspend fun fetchMissingArticles() {
@@ -317,7 +322,6 @@ internal class ReaderAccountDelegate(
317322
stream = stream,
318323
since = since,
319324
continuation = continuation,
320-
count = MAX_PAGINATED_ITEM_LIMIT,
321325
)
322326

323327
val result = response.body()

capy/src/main/java/com/jocmp/capy/persistence/ArticleRecords.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ internal class ArticleRecords internal constructor(
4646
)
4747
}
4848

49+
/**
50+
* Create placeholder statuses to be updated
51+
* by the [findMissingArticles] query
52+
*/
53+
fun createStatuses(articleIDs: List<String>, updatedAt: ZonedDateTime = nowUTC()) {
54+
database.transactionWithErrorHandling {
55+
articleIDs.forEach { createStatus(articleID = it, updatedAt = updatedAt, read = false) }
56+
}
57+
}
58+
4959
/**
5060
* Upserts a record status. On conflict it overwrites "read" metadata.
5161
*/

capy/src/main/sqldelight/com/jocmp/capy/db/articles.sq

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ findMissingArticles:
154154
SELECT article_id
155155
FROM article_statuses
156156
LEFT OUTER JOIN articles ON article_statuses.article_id = articles.id
157-
WHERE articles.id IS NULL
158-
AND article_statuses.read = 0 OR article_statuses.starred = 1;
157+
WHERE articles.id IS NULL;
159158

160159
create:
161160
INSERT INTO articles(

capy/src/test/java/com/jocmp/capy/accounts/feedbin/FeedbinAccountDelegateTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ class FeedbinAccountDelegateTest {
191191
),
192192
)
193193

194-
val starredEntries = listOf(readEntry, unreadEntry)
194+
val starredEntries = listOf(unreadEntry, readEntry)
195195

196196
coEvery { feedbin.subscriptions() }.returns(Response.success(subscriptions))
197197
coEvery { feedbin.unreadEntries() }.returns(Response.success(listOf(unreadEntry.id)))

capy/src/test/java/com/jocmp/capy/accounts/reader/ReaderAccountDelegateTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ class ReaderAccountDelegateTest {
623623
googleReader.streamItemsIDs(
624624
streamID = stream.id,
625625
since = any(),
626-
count = 100,
626+
count = 10_000,
627627
)
628628
}.returns(Response.success(StreamItemIDsResult(itemRefs = itemRefs, continuation = null)))
629629

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.jocmp.readerclient
2+
3+
object ItemIdentifiers {
4+
fun parseToHexID(numericID: String) = String.format("%016x", numericID.toLong())
5+
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.jocmp.readerclient
22

3+
import com.jocmp.readerclient.ItemIdentifiers.parseToHexID
34
import com.squareup.moshi.JsonClass
45

56
@JsonClass(generateAdapter = true)
67
data class ItemRef(
78
val id: String,
89
) {
9-
val hexID = buildHexID(id)
10+
val hexID = parseToHexID(id)
1011
}
11-
12-
fun buildHexID(id: String) = String.format("%016x", id.toLong())

0 commit comments

Comments
 (0)