Skip to content

Commit

Permalink
Added ability to force add a feed despite network errors
Browse files Browse the repository at this point in the history
  • Loading branch information
spacecowboy committed Sep 24, 2023
1 parent 9c0a130 commit 341310e
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 33 deletions.
23 changes: 20 additions & 3 deletions app/src/main/java/com/nononsenseapps/feeder/FeederApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import com.nononsenseapps.feeder.util.FilePathProvider
import com.nononsenseapps.feeder.util.ToastMaker
import com.nononsenseapps.feeder.util.currentlyUnmetered
import com.nononsenseapps.feeder.util.filePathProvider
import com.nononsenseapps.feeder.util.logDebug
import com.nononsenseapps.jsonfeed.cachingHttpClient
import java.io.File
import java.security.Security
Expand Down Expand Up @@ -104,9 +105,25 @@ class FeederApplication : Application(), DIAware, ImageLoaderFactory {
val filePathProvider = instance<FilePathProvider>()
cachingHttpClient(
cacheDirectory = (filePathProvider.httpCacheDir),
).newBuilder()
.addNetworkInterceptor(UserAgentInterceptor)
.build()
) {
addNetworkInterceptor(UserAgentInterceptor)
if (BuildConfig.DEBUG) {
addInterceptor { chain ->
val request = chain.request()
logDebug(
"FEEDER",
"Request ${request.url} headers [${request.headers}]",
)

chain.proceed(request).also {
logDebug(
"FEEDER",
"Response ${it.request.url} code ${it.networkResponse?.code} cached ${it.cacheResponse != null}",
)
}
}
}
}
}
bind<ImageLoader>() with singleton {
val filePathProvider = instance<FilePathProvider>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ class Repository(override val di: DI) : DIAware {
filter = feedListFilter,
)
}.flatMapLatest {
logDebug("JONAS", "DAMP $it")
feedItemStore.getPagedFeedItemsRaw(
feedId = it.feedId,
tag = it.tag,
Expand Down Expand Up @@ -285,7 +284,6 @@ class Repository(override val di: DI) : DIAware {
filter = feedListFilter,
)
}.flatMapLatest {
logDebug("JONAS", "Fump $it")
feedItemStore.getFeedItemCountRaw(
feedId = it.feedId,
tag = it.tag,
Expand Down
30 changes: 16 additions & 14 deletions app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class FeedParser(override val di: DI) : DIAware {
}
}

internal fun parseRssAtom(
private fun parseRssAtom(
url: URL,
responseBody: ResponseBody,
): Either<FeedParserError, Feed> {
Expand Down Expand Up @@ -344,22 +344,24 @@ class FeedParser(override val di: DI) : DIAware {

class FeedParsingError(val url: URL, e: Throwable) : Exception(e.message, e)

suspend fun OkHttpClient.getResponse(url: URL, forceNetwork: Boolean = false): Response {
suspend fun OkHttpClient.getResponse(
url: URL,
forceNetwork: Boolean = false,
): Response {
val request = Request.Builder()
.url(url)
.cacheControl(
CacheControl.Builder()
.run {
if (forceNetwork) {
.run {
if (forceNetwork) {
cacheControl(
CacheControl.Builder()
// Force cache-revalidation
maxAge(0, TimeUnit.SECONDS)
} else {
// Will accept anything generated in the last X
maxAge(10, TimeUnit.MINUTES)
}
}
.build(),
)
.maxAge(0, TimeUnit.SECONDS)
.build(),
)
} else {
this
}
}
.build()

@Suppress("BlockingMethodInNonBlockingContext")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ object UserAgentInterceptor : Interceptor {
// const val USER_AGENT_STRING = "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.136 Mobile Safari/537.36"
// After email discussion with BleepingComputer.com where Feeder got blocked because they thought it was scraper of some kind
// const val USER_AGENT_STRING = "Mjukisbyxor / ${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})"
const val USER_AGENT_STRING = "SpaceCowboys Android RSS Reader / ${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})"
const val USER_AGENT_STRING =
"SpaceCowboys Android RSS Reader / ${BuildConfig.VERSION_NAME}(${BuildConfig.VERSION_CODE})"
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,16 @@ fun ColumnScope.rightContent(
title = title,
description = error.description,
url = error.url,
)
) {
onClick(
SearchResult(
title = error.url,
url = error.url,
description = "",
feedImage = "",
),
)
}
}
}
for (result in results.item) {
Expand Down Expand Up @@ -489,6 +498,7 @@ fun ErrorResultView(
description: String,
url: String,
modifier: Modifier = Modifier,
onAddAnyway: () -> Unit,
) {
val dimens = LocalDimens.current

Expand Down Expand Up @@ -518,6 +528,9 @@ fun ErrorResultView(
description,
style = MaterialTheme.typography.bodyMedium,
)
OutlinedButton(onClick = onAddAnyway) {
Text(stringResource(id = R.string.add_anyway))
}
}
}
}
Expand Down
29 changes: 18 additions & 11 deletions app/src/main/java/com/nononsenseapps/jsonfeed/JsonFeedParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fun cachingHttpClient(
cacheSize: Long = 10L * 1024L * 1024L,
trustAllCerts: Boolean = true,
connectTimeoutSecs: Long = 30L,
readTimeoutSecs: Long = 30L
readTimeoutSecs: Long = 30L,
block: (OkHttpClient.Builder.() -> Unit)? = null,
): OkHttpClient {
val builder: OkHttpClient.Builder = OkHttpClient.Builder()

Expand All @@ -33,6 +34,10 @@ fun cachingHttpClient(
builder.trustAllCerts()
}

block?.let {
builder.block()
}

return builder.build()
}

Expand All @@ -45,24 +50,24 @@ fun feedAdapter(): JsonAdapter<Feed> =
*/
class JsonFeedParser(
private val httpClient: OkHttpClient,
private val jsonFeedAdapter: JsonAdapter<Feed>
private val jsonFeedAdapter: JsonAdapter<Feed>,
) {

constructor(
cacheDirectory: File? = null,
cacheSize: Long = 10L * 1024L * 1024L,
trustAllCerts: Boolean = true,
connectTimeoutSecs: Long = 5L,
readTimeoutSecs: Long = 5L
readTimeoutSecs: Long = 5L,
) : this(
cachingHttpClient(
cacheDirectory = cacheDirectory,
cacheSize = cacheSize,
trustAllCerts = trustAllCerts,
connectTimeoutSecs = connectTimeoutSecs,
readTimeoutSecs = readTimeoutSecs
readTimeoutSecs = readTimeoutSecs,
),
feedAdapter()
feedAdapter(),
)

/**
Expand All @@ -77,7 +82,7 @@ class JsonFeedParser(
} catch (error: Throwable) {
throw IllegalArgumentException(
"Bad URL. Perhaps it is missing an http:// prefix?",
error
error,
)
}

Expand All @@ -95,11 +100,13 @@ class JsonFeedParser(
contentType.subtype.contains("json") -> {
parseJson(body)
}

else -> {
throw IOException("Incorrect subtype: ${contentType.type}/${contentType.subtype}")
}
}
}

else -> {
throw IOException("Incorrect type: ${contentType?.type}/${contentType?.subtype}")
}
Expand Down Expand Up @@ -133,13 +140,13 @@ data class Feed(
val author: Author? = null,
val expired: Boolean? = null,
val hubs: List<Hub>? = null,
val items: List<Item>?
val items: List<Item>?,
)

data class Author(
val name: String? = null,
val url: String? = null,
val avatar: String? = null
val avatar: String? = null,
)

data class Item(
Expand All @@ -156,18 +163,18 @@ data class Item(
val date_modified: String? = null,
val author: Author? = null,
val tags: List<String>? = null,
val attachments: List<Attachment>? = null
val attachments: List<Attachment>? = null,
)

data class Attachment(
val url: String?,
val mime_type: String? = null,
val title: String? = null,
val size_in_bytes: Long? = null,
val duration_in_seconds: Long? = null
val duration_in_seconds: Long? = null,
)

data class Hub(
val type: String?,
val url: String?
val url: String?,
)
3 changes: 2 additions & 1 deletion app/src/main/res/values-sv/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,5 @@
<string name="failed_to_parse_full_article">Kund inte läsa hela artikeln</string>
<string name="no_url">Ingen URL</string>
<string name="theme_e_ink">Läsplatta</string>
</resources>
<string name="add_anyway">Lägg till ändå</string>
</resources>
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -240,4 +240,5 @@
<string name="unsupported_content_type">Unsupported content type</string>
<string name="failed_to_parse_full_article">Failed to parse full article</string>
<string name="no_url">No URL</string>
<string name="add_anyway">Add anyway</string>
</resources>

0 comments on commit 341310e

Please sign in to comment.