Skip to content

Commit

Permalink
Can't add valid feed #123
Browse files Browse the repository at this point in the history
  • Loading branch information
ismartcoding committed Nov 30, 2023
1 parent 18b0d27 commit 681e5e2
Show file tree
Hide file tree
Showing 28 changed files with 1,542 additions and 55 deletions.
18 changes: 8 additions & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -144,21 +144,21 @@ dependencies {
implementation(platform("androidx.compose:compose-bom:2023.10.01"))

// https://github.com/google/accompanist/releases
implementation("androidx.activity:activity-compose:1.8.0")
implementation("androidx.activity:activity-compose:1.8.1")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.foundation:foundation-layout")
implementation("androidx.compose.material3:material3:1.2.0-alpha09")
implementation("androidx.compose.material3:material3:1.2.0-alpha11")
implementation("androidx.compose.material:material-icons-extended")

// implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha12")

// https://developer.android.com/jetpack/androidx/releases/navigation
implementation("androidx.navigation:navigation-compose:2.7.4")
implementation("androidx.navigation:navigation-compose:2.7.5")

releaseImplementation(platform("com.google.firebase:firebase-bom:32.2.3"))
releaseImplementation("com.google.firebase:firebase-crashlytics-ktx:18.4.3")
releaseImplementation("com.google.firebase:firebase-crashlytics-ktx:18.6.0")

implementation("com.apollographql.apollo3:apollo-runtime:$apollo")
implementation("com.apollographql.apollo3:apollo-normalized-cache:$apollo")
Expand All @@ -173,10 +173,10 @@ dependencies {
implementation("com.github.bmoliveira:snake-yaml:v1.18-android")

// CameraX
implementation("androidx.camera:camera-core:1.4.0-alpha01")
implementation("androidx.camera:camera-camera2:1.4.0-alpha01")
implementation("androidx.camera:camera-lifecycle:1.4.0-alpha01")
implementation("androidx.camera:camera-view:1.4.0-alpha01")
implementation("androidx.camera:camera-core:1.4.0-alpha02")
implementation("androidx.camera:camera-camera2:1.4.0-alpha02")
implementation("androidx.camera:camera-lifecycle:1.4.0-alpha02")
implementation("androidx.camera:camera-view:1.4.0-alpha02")

implementation("io.ktor:ktor-server-core:$ktor")
implementation("io.ktor:ktor-server-netty:$ktor")
Expand Down Expand Up @@ -204,8 +204,6 @@ dependencies {
implementation("com.aallam.openai:openai-client:3.2.0")

implementation("com.google.zxing:core:3.5.2")
// Feed
implementation("com.rometools:rome:2.1.0")

implementation("androidx.work:work-runtime-ktx:2.8.1")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.ismartcoding.plain.api

object HttpApiTimeout {
var DEFAULT_SECONDS: Int = 2
var MEDIUM_SECONDS: Int = 5
var BROWSER_SECONDS: Int = 15
var DEFAULT_SECONDS: Int = 3
var MEDIUM_SECONDS: Int = 10
var BROWSER_SECONDS: Int = 20
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import com.ismartcoding.lib.extensions.getFilenameExtension
import com.ismartcoding.lib.extensions.isOk
import com.ismartcoding.lib.helpers.CryptoHelper
import com.ismartcoding.lib.html2md.MDConverter
import com.ismartcoding.lib.rss.DateParser
import com.ismartcoding.lib.rss.model.RssItem
import com.ismartcoding.plain.MainApp
import com.ismartcoding.plain.api.ApiResult
import com.ismartcoding.plain.api.HttpClientManager
import com.ismartcoding.plain.db.DFeedEntry
import com.rometools.rome.feed.synd.SyndEntry
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
Expand All @@ -24,50 +25,39 @@ import net.dankito.readability4j.extended.util.RegExUtilExtended
import net.dankito.readability4j.model.ReadabilityOptions
import net.dankito.readability4j.processor.MetadataParser
import java.io.File
import java.time.format.DateTimeFormatter
import java.util.*

fun SyndEntry.toDFeedEntry(
fun RssItem.toDFeedEntry(
feedId: String,
feedUrl: String,
): DFeedEntry {
val item = DFeedEntry()
item.rawId =
CryptoHelper.sha1(
(feedId + "_" + (link ?: uri ?: title ?: UUID.randomUUID().toString())).toByteArray(),
(feedId + "_" + (link ?: title ?: UUID.randomUUID().toString())).toByteArray(),
)
item.feedId = feedId
if (title != null) {
item.title = HtmlCompat.fromHtml(title, HtmlCompat.FROM_HTML_MODE_LEGACY).toString().replace("\n", " ").trim()
item.title = HtmlCompat.fromHtml(title!!, HtmlCompat.FROM_HTML_MODE_LEGACY).toString().replace("\n", " ").trim()
} else {
item.title = ""
}

val feedBaseUrl = HtmlUtils.getBaseUrl(feedUrl)
item.description = HtmlUtils.improveHtmlContent(contents.getOrNull(0)?.value ?: description?.value ?: "", feedBaseUrl)
item.description = HtmlUtils.improveHtmlContent(content ?: description ?: "", feedBaseUrl)
item.description = MDConverter().convert(item.description)
item.url = link
item.url = link ?: ""

enclosures?.forEach {
if (it.type.contains("image")) {
item.image = it.url
}
}

foreignMarkup?.forEach {
if (it.namespace?.prefix == "media" && it.name == "content") {
it.attributes.forEach { mc ->
if (mc.name == "url") {
item.image = mc.value
}
}
}
}
item.image = image ?: ""

item.author = author.ifEmpty { source?.title ?: "" }
item.author = author?.ifEmpty { sourceName ?: "" } ?: ""

val date = publishedDate ?: updatedDate
if (date != null && date.time < item.publishedAt.toEpochMilliseconds()) {
item.publishedAt = Instant.fromEpochMilliseconds(date.time)
if (pubDate != null) {
val date = DateParser.parseDate(pubDate!!, Locale.US)
if (date != null && date.time < item.publishedAt.toEpochMilliseconds()) {
item.publishedAt = Instant.fromEpochMilliseconds(date.time)
}
}

return item
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package com.ismartcoding.plain.features.feed

import com.ismartcoding.lib.helpers.AssetsHelper
import com.ismartcoding.lib.logcat.LogCat
import com.ismartcoding.lib.opml.OpmlParser
import com.ismartcoding.lib.opml.OpmlWriter
import com.ismartcoding.lib.opml.entity.Body
import com.ismartcoding.lib.opml.entity.Head
import com.ismartcoding.lib.opml.entity.Opml
import com.ismartcoding.lib.opml.entity.Outline
import com.ismartcoding.lib.rss.RssParser
import com.ismartcoding.lib.rss.model.RssChannel
import com.ismartcoding.plain.MainApp
import com.ismartcoding.plain.R
import com.ismartcoding.plain.api.HttpClientManager
import com.ismartcoding.plain.db.AppDatabase
import com.ismartcoding.plain.db.DFeed
import com.ismartcoding.plain.db.FeedDao
import com.ismartcoding.plain.features.locale.LocaleHelper
import com.ismartcoding.plain.workers.FeedFetchWorker
import com.rometools.rome.feed.synd.SyndFeed
import com.rometools.rome.io.SyndFeedInput
import com.rometools.rome.io.XmlReader
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.utils.io.jvm.javaio.*
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.HttpStatusCode
import kotlinx.datetime.Clock
import java.io.Reader
import java.io.Writer
import java.util.*
import java.util.Date

object FeedHelper {
val feedDao: FeedDao by lazy {
Expand Down Expand Up @@ -127,9 +129,13 @@ object FeedHelper {
writer.close()
}

suspend fun fetchAsync(url: String): SyndFeed {
suspend fun fetchAsync(url: String): RssChannel {
val r = HttpClientManager.httpClient().get(url)
val input = r.bodyAsChannel().toInputStream()
return SyndFeedInput().build(XmlReader(input))
if (r.status != HttpStatusCode.OK) {
throw Exception("HTTP ${r.status.value} ${r.status.description}")
}
val xmlString = r.bodyAsText()
val rssParser = RssParser()
return rssParser.parse(xmlString)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ class MainActivity : AppCompatActivity() {
fixSystemBarsAnimation()

instance = WeakReference(this)

// https://stackoverflow.com/questions/51959944/sqliteblobtoobigexception-row-too-big-to-fit-into-cursorwindow-requiredpos-0-t
try {
val field = CursorWindow::class.java.getDeclaredField("sCursorWindowSize")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fun PIconButton(
modifier =
Modifier
.size(8.dp)
.offset(x = (-3).dp, y = 9.dp)
.offset(x = (-1).dp, y = 0.dp)
.clip(CircleShape),
containerColor = badgeColor,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class AddFeedDialog() : BaseBottomSheetDialog<DialogAddFeedBinding>() {
withIO {
FeedHelper.addAsync {
this.url = url
this.name = syndFeed.title
this.name = syndFeed.title ?: ""
}
}
FeedFetchWorker.oneTimeRequest(id)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/ismartcoding/plain/web/SXGraphQL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ class SXGraphQL(val schema: Schema) {
val id =
FeedHelper.addAsync {
this.url = url
this.name = syndFeed.title
this.name = syndFeed.title ?: ""
}
FeedFetchWorker.oneTimeRequest(id)
sendEvent(ActionEvent(ActionSourceType.FEED, ActionType.CREATED, setOf(id)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class FeedFetchWorker(
try {
LogCat.d("Syncing feed: ${feed.id}, ${feed.name}, ${feed.url}")
val syndFeed = FeedHelper.fetchAsync(feed.url)
val list = syndFeed.entries.map { it.toDFeedEntry(feed.id, feed.url) }
val list = syndFeed.items.map { it.toDFeedEntry(feed.id, feed.url) }
val inserted = FeedEntryHelper.feedEntryDao.insertListIfNotExist(list)
if (feed.fetchContent) {
inserted.chunked(4)
Expand Down Expand Up @@ -141,7 +141,7 @@ class FeedFetchWorker(

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
REPEAT_WORK_NAME,
ExistingPeriodicWorkPolicy.REPLACE,
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
request.build(),
)
}
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.1.2")
classpath("com.android.tools.build:gradle:8.1.4")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10")
classpath("com.google.gms:google-services:4.4.0")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.9")
Expand Down
Loading

0 comments on commit 681e5e2

Please sign in to comment.