Skip to content

Commit

Permalink
Add user label database tables
Browse files Browse the repository at this point in the history
  • Loading branch information
jocmp committed Jan 18, 2025
1 parent 2aae854 commit bb8ae1b
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.jocmp.capy.db.Database
import com.jocmp.capy.logging.CapyLog
import com.jocmp.capy.persistence.ArticleRecords
import com.jocmp.capy.persistence.FeedRecords
import com.jocmp.capy.persistence.SavedSearchRecords
import com.jocmp.capy.persistence.TaggingRecords
import com.jocmp.feedfinder.withProtocol
import com.jocmp.readerclient.Category
Expand All @@ -26,6 +27,7 @@ import com.jocmp.readerclient.Stream
import com.jocmp.readerclient.Subscription
import com.jocmp.readerclient.SubscriptionEditAction
import com.jocmp.readerclient.SubscriptionQuickAddResult
import com.jocmp.readerclient.Tag
import com.jocmp.readerclient.ext.editSubscription
import com.jocmp.readerclient.ext.streamItemsIDs
import kotlinx.coroutines.coroutineScope
Expand All @@ -45,6 +47,7 @@ internal class ReaderAccountDelegate(
private val articleRecords = ArticleRecords(database)
private val feedRecords = FeedRecords(database)
private val taggingRecords = TaggingRecords(database)
private val savedSearchRecords = SavedSearchRecords(database)

override suspend fun refresh(filter: ArticleFilter, cutoffDate: ZonedDateTime?): Result<Unit> {
return withErrorHandling {
Expand Down Expand Up @@ -186,26 +189,11 @@ internal class ReaderAccountDelegate(
}
}

private suspend fun refreshFeeds() {
withResult(googleReader.subscriptionList()) { result ->
val subscriptions = result.subscriptions

database.transactionWithErrorHandling {
subscriptions.forEach { subscription ->
upsertFeed(subscription)
}

database.feedsQueries.deleteAllExcept(subscriptions.map { it.id })

cleanUpTaggings(result.subscriptions)
}
}
}

private suspend fun refreshTopLevelArticles() {
val since = articleRecords.maxArrivedAt().toEpochSecond()

refreshFeeds()
refreshSavedSearches()
refreshArticleState()
fetchPaginatedArticles(since = since, stream = Stream.Read())
}
Expand All @@ -220,6 +208,22 @@ internal class ReaderAccountDelegate(
}
}

private suspend fun refreshFeeds() {
withResult(googleReader.subscriptionList()) { result ->
val subscriptions = result.subscriptions

database.transactionWithErrorHandling {
subscriptions.forEach { subscription ->
upsertFeed(subscription)
}

database.feedsQueries.deleteAllExcept(subscriptions.map { it.id })

cleanUpTaggings(result.subscriptions)
}
}
}

private fun upsertFeed(subscription: Subscription) {
database.feedsQueries.upsert(
id = subscription.id,
Expand All @@ -243,8 +247,27 @@ internal class ReaderAccountDelegate(
}
}

database.taggingsQueries.deleteOrphanedTags(
excludedIDs = excludedIDs
taggingRecords.deleteOrphaned(excludedIDs = excludedIDs)
}

private suspend fun refreshSavedSearches() {
withResult(googleReader.tagList()) { result ->
database.transactionWithErrorHandling {
val tags = result.tags.filter { it.type == Tag.Type.TAG }

tags.forEach {
upsertSavedSearch(it)
}

savedSearchRecords.deleteOrphaned(excludedIDs = tags.map { it.id })
}
}
}

private fun upsertSavedSearch(tag: Tag) {
savedSearchRecords.upsert(
id = tag.id,
name = tag.name
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.jocmp.capy.accounts.reader

import com.jocmp.readerclient.Tag

val Tag.name: String
get() = id.split("/").lastOrNull().orEmpty()
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.jocmp.capy.persistence

import com.jocmp.capy.db.Database

internal class SavedSearchRecords(private val database: Database) {
internal fun upsert(id: String, name: String) {
savedSearchQueries.upsert(id = id, name = name)
}

internal fun deleteOrphaned(excludedIDs: List<String>) {
savedSearchQueries.deleteOrphaned(excludedIDs = excludedIDs)
}

private val savedSearchQueries
get() = database.saved_searchesQueries
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ internal class TaggingRecords(
database.taggingsQueries.deleteTaggings(taggingIDs)
}

fun deleteOrphaned(excludedIDs: List<String>) {
database.taggingsQueries.deleteOrphanedTags(excludedIDs = excludedIDs)
}

fun findFeedTaggingsToDelete(
feed: Feed,
excludedTaggingNames: List<String> = emptyList()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE saved_searches (
id TEXT NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
query TEXT
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE saved_search_articles (
saved_search_id TEXT NOT NULL REFERENCES saved_searches(id),
article_id TEXT NOT NULL REFERENCES saved_searches(id),
PRIMARY KEY (saved_search_id, article_id)
);
15 changes: 15 additions & 0 deletions capy/src/main/sqldelight/com/jocmp/capy/db/saved_searches.sq
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
upsert:
INSERT OR REPLACE INTO saved_searches(
id,
name
)
VALUES (
:id,
:name
);

deleteOrphaned {
DELETE FROM saved_searches WHERE id NOT IN :excludedIDs;

DELETE FROM saved_search_articles WHERE saved_search_id NOT IN :excludedIDs;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ interface GoogleReader {
@Query("output") output: String = "json"
): Response<SubscriptionListResult>

@GET("reader/api/0/tag/list")
suspend fun tagList(
@Query("output") output: String = "json"
): Response<TagListResult>

@GET("reader/api/0/stream/items/ids")
suspend fun streamItemsIDs(
@Query("s") streamID: String,
Expand Down
17 changes: 17 additions & 0 deletions readerclient/src/main/java/com/jocmp/readerclient/Tag.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.jocmp.readerclient

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class Tag(
val id: String,
val type: Type?,
) {
enum class Type {
@Json(name = "folder")
FOLDER,
@Json(name = "tag")
TAG
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.jocmp.readerclient

import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class TagListResult(
val tags: List<Tag>
)

0 comments on commit bb8ae1b

Please sign in to comment.