Skip to content

Commit

Permalink
feat(greader): support google reader api (#536)
Browse files Browse the repository at this point in the history
* feat(greader): support google reader api

* feat(greader): support groups and feeds

* feat(freshrss): support fresh rss api

* feat(freshrss): support fresh rss api

* feat(greader): support mark as read or starred

* feat(greader): support mark as read or starred
  • Loading branch information
Ashinch authored Jan 18, 2024
1 parent 34e6648 commit fa2787b
Show file tree
Hide file tree
Showing 31 changed files with 1,752 additions and 235 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.ash.reader.domain.model.account.security

class FreshRSSSecurityKey private constructor() : SecurityKey() {

var serverUrl: String? = null
var username: String? = null
var password: String? = null

constructor(serverUrl: String?, username: String?, password: String?) : this() {
this.serverUrl = serverUrl
this.username = username
this.password = password
}

constructor(value: String? = DESUtils.empty) : this() {
decode(value, FreshRSSSecurityKey::class.java).let {
serverUrl = it.serverUrl
username = it.username
password = it.password
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ enum class MarkAsReadConditions {
;

fun toDate(): Date? = when (this) {
All -> Date()
All -> null
else -> Calendar.getInstance().apply {
time = Date()
add(Calendar.DAY_OF_MONTH, when (this@MarkAsReadConditions) {
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/me/ash/reader/domain/repository/FeedDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ interface FeedDao {
isNotification: Boolean,
)

@Query(
"""
SELECT * FROM feed
WHERE groupId = :groupId
AND accountId = :accountId
"""
)
suspend fun queryByGroupId(accountId: Int, groupId: String): List<Feed>

@Query(
"""
DELETE FROM feed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import androidx.paging.PagingSource
import androidx.work.CoroutineWorker
import androidx.work.ListenableWorker
import androidx.work.WorkManager
import com.rometools.rome.feed.synd.SyndFeed
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.supervisorScope
import me.ash.reader.domain.model.article.Article
import me.ash.reader.domain.model.account.Account
import me.ash.reader.domain.model.article.ArticleWithFeed
import me.ash.reader.domain.model.feed.Feed
import me.ash.reader.domain.model.feed.FeedWithArticle
Expand Down Expand Up @@ -44,27 +45,45 @@ abstract class AbstractRssRepository(
private val dispatcherDefault: CoroutineDispatcher,
) {

open val subscribe: Boolean = true
open val move: Boolean = true
open val delete: Boolean = true
open val update: Boolean = true
open val addSubscription: Boolean = true
open val moveSubscription: Boolean = true
open val deleteSubscription: Boolean = true
open val updateSubscription: Boolean = true

open suspend fun validCredentials(): Boolean = true
open suspend fun validCredentials(account: Account): Boolean = true

open suspend fun subscribe(feed: Feed, articles: List<Article>) {
open suspend fun clearAuthorization() {}

open suspend fun subscribe(
feedLink: String, searchedFeed: SyndFeed, groupId: String,
isNotification: Boolean, isFullContent: Boolean
) {
val accountId = context.currentAccountId
val feed = Feed(
id = accountId.spacerDollar(UUID.randomUUID().toString()),
name = searchedFeed.title!!,
url = feedLink,
groupId = groupId,
accountId = accountId,
icon = searchedFeed.icon?.link
)
val articles = searchedFeed.entries.map { rssHelper.buildArticleFromSyndEntry(feed, accountId, it) }
feedDao.insert(feed)
articleDao.insertList(articles.map {
it.copy(feedId = feed.id)
})
}

open suspend fun addGroup(name: String): String {
open suspend fun addGroup(
destFeed: Feed?,
newGroupName: String
): String {
context.currentAccountId.let { accountId ->
return accountId.spacerDollar(UUID.randomUUID().toString()).also {
groupDao.insert(
Group(
id = it,
name = name,
name = newGroupName,
accountId = accountId
)
)
Expand Down Expand Up @@ -148,7 +167,10 @@ abstract class AbstractRssRepository(
val articles = rssHelper.queryRssXml(feed, latest?.link)
if (feed.icon == null) {
try {
rssHelper.queryRssIcon(feedDao, feed)
val iconLink = rssHelper.queryRssIconLink(feed.url)
if (iconLink != null) {
rssHelper.saveRssIcon(feedDao, feed, iconLink)
}
} catch (e: Exception) {
Log.i("RLog", "queryRssIcon is failed: ${e.message}")
}
Expand Down Expand Up @@ -272,21 +294,33 @@ abstract class AbstractRssRepository(

suspend fun isFeedExist(url: String): Boolean = feedDao.queryByLink(context.currentAccountId, url).isNotEmpty()

suspend fun updateGroup(group: Group) {
open suspend fun renameGroup(group: Group) {
groupDao.update(group)
}

suspend fun updateFeed(feed: Feed) {
open suspend fun renameFeed(feed: Feed) {
updateFeed(feed)
}

open suspend fun moveFeed(originGroupId: String, feed: Feed) {
updateFeed(feed)
}

open suspend fun changeFeedUrl(feed: Feed) {
updateFeed(feed)
}

internal suspend fun updateFeed(feed: Feed) {
feedDao.update(feed)
}

suspend fun deleteGroup(group: Group) {
open suspend fun deleteGroup(group: Group) {
deleteArticles(group = group)
feedDao.deleteByGroupId(context.currentAccountId, group.id)
groupDao.delete(group)
}

suspend fun deleteFeed(feed: Feed) {
open suspend fun deleteFeed(feed: Feed) {
deleteArticles(feed = feed)
feedDao.delete(feed)
}
Expand Down
48 changes: 41 additions & 7 deletions app/src/main/java/me/ash/reader/domain/service/FeverRssService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.ListenableWorker
import androidx.work.WorkManager
import com.rometools.rome.feed.synd.SyndFeed
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.withContext
import me.ash.reader.R
import me.ash.reader.domain.model.account.Account
import me.ash.reader.domain.model.account.security.FeverSecurityKey
import me.ash.reader.domain.model.article.Article
import me.ash.reader.domain.model.article.ArticleMeta
Expand Down Expand Up @@ -56,10 +58,10 @@ class FeverRssService @Inject constructor(
feedDao, workManager, rssHelper, notificationHelper, ioDispatcher, defaultDispatcher
) {

override val subscribe: Boolean = false
override val move: Boolean = false
override val delete: Boolean = false
override val update: Boolean = false
override val addSubscription: Boolean = false
override val moveSubscription: Boolean = false
override val deleteSubscription: Boolean = false
override val updateSubscription: Boolean = false

private suspend fun getFeverAPI() =
FeverSecurityKey(accountDao.queryById(context.currentAccountId)!!.securityKey).run {
Expand All @@ -72,13 +74,45 @@ class FeverRssService @Inject constructor(
)
}

override suspend fun validCredentials(): Boolean = getFeverAPI().validCredentials() > 0
override suspend fun validCredentials(account: Account): Boolean =
getFeverAPI().validCredentials() > 0

override suspend fun subscribe(feed: Feed, articles: List<Article>) {
override suspend fun clearAuthorization() {
FeverAPI.clearInstance()
}

override suspend fun subscribe(
feedLink: String, searchedFeed: SyndFeed, groupId: String,
isNotification: Boolean, isFullContent: Boolean,
) {
throw Exception("Unsupported")
}

override suspend fun addGroup(destFeed: Feed?, newGroupName: String): String {
throw Exception("Unsupported")
}

override suspend fun renameGroup(group: Group) {
throw Exception("Unsupported")
}

override suspend fun renameFeed(feed: Feed) {
throw Exception("Unsupported")
}

override suspend fun deleteGroup(group: Group) {
throw Exception("Unsupported")
}

override suspend fun deleteFeed(feed: Feed) {
throw Exception("Unsupported")
}

override suspend fun moveFeed(originGroupId: String, feed: Feed) {
throw Exception("Unsupported")
}

override suspend fun addGroup(name: String): String {
override suspend fun changeFeedUrl(feed: Feed) {
throw Exception("Unsupported")
}

Expand Down
Loading

1 comment on commit fa2787b

@ron159
Copy link

@ron159 ron159 commented on fa2787b Jan 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

终于要来了吗,啥时候构建呀😉

Please sign in to comment.